Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 重写数据帧变量时引发内存泄漏_Python_Apache Spark_Memory Leaks_Pyspark_Apache Spark Sql - Fatal编程技术网

Python 重写数据帧变量时引发内存泄漏

Python 重写数据帧变量时引发内存泄漏,python,apache-spark,memory-leaks,pyspark,apache-spark-sql,Python,Apache Spark,Memory Leaks,Pyspark,Apache Spark Sql,我在spark驱动程序中遇到了内存泄漏,我似乎不知道为什么。我猜这与试图覆盖DataFrame变量有关,但我找不到任何文档或其他类似问题 这是在Spark 2.1.0(PySpark)上实现的 从pyspark.sql导入SparkSession 从pyspark.sql导入SQLContext 从pyspark.sql.types导入* 火花=火花会话\ 建筑商先生\ .appName(“火花泄漏”)\ .getOrCreate() sc=spark.sparkContext sqlConte

我在spark驱动程序中遇到了内存泄漏,我似乎不知道为什么。我猜这与试图覆盖
DataFrame
变量有关,但我找不到任何文档或其他类似问题

这是在Spark 2.1.0(PySpark)上实现的

从pyspark.sql导入SparkSession
从pyspark.sql导入SQLContext
从pyspark.sql.types导入*
火花=火花会话\
建筑商先生\
.appName(“火花泄漏”)\
.getOrCreate()
sc=spark.sparkContext
sqlContext=sqlContext.getOrCreate(sc)
项目=5000000
数据=[str(x)表示范围内的x(1,项)]
df=sqlContext.createDataFrame(数据,StringType())
打印(df.count())
对于范围内的x(0,项):
sub_df=sqlContext.createDataFrame([str(x)],StringType()
df=df.减法(sub_df)
打印(df.count())
这将继续运行,直到驱动程序内存耗尽然后死亡

java.net.SocketException:连接重置
位于java.net.SocketInputStream.read(SocketInputStream.java:210)
位于java.net.SocketInputStream.read(SocketInputStream.java:141)
位于java.net.SocketInputStream.read(SocketInputStream.java:224)
位于org.apache.spark.api.python.pythonacumeratorv2.merge(PythonRDD.scala:917)
位于org.apache.spark.scheduler.DAGScheduler$$anonfun$updateacumerators$1.apply(DAGScheduler.scala:1089)
位于org.apache.spark.scheduler.DAGScheduler$$anonfun$updateacumerators$1.apply(DAGScheduler.scala:1081)
位于scala.collection.mutable.resizeblearray$class.foreach(resizeblearray.scala:59)
位于scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:48)
位于org.apache.spark.scheduler.DAGScheduler.updateacumerators(DAGScheduler.scala:1081)
位于org.apache.spark.scheduler.DAGScheduler.handleTaskCompletion(DAGScheduler.scala:1184)
位于org.apache.spark.scheduler.DAGSchedulerEventProcessLoop.doOnReceive(DAGScheduler.scala:1717)
位于org.apache.spark.scheduler.DAGSchedulerEventProcessLoop.onReceive(DAGScheduler.scala:1675)
位于org.apache.spark.scheduler.DAGSchedulerEventProcessLoop.onReceive(DAGScheduler.scala:1664)
位于org.apache.spark.util.EventLoop$$anon$1.run(EventLoop.scala:48)
17/05/25 16:55:40错误:无法更新任务13的累加器
java.net.SocketException:管道断开(写入失败)
位于java.net.SocketOutputStream.socketWrite0(本机方法)
位于java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111)
位于java.net.SocketOutputStream.write(SocketOutputStream.java:155)
位于java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
位于java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
位于java.io.DataOutputStream.flush(DataOutputStream.java:123)
位于org.apache.spark.api.python.pythonacumeratorv2.merge(PythonRDD.scala:915)
位于org.apache.spark.scheduler.DAGScheduler$$anonfun$updateacumerators$1.apply(DAGScheduler.scala:1089)
位于org.apache.spark.scheduler.DAGScheduler$$anonfun$updateacumerators$1.apply(DAGScheduler.scala:1081)
位于scala.collection.mutable.resizeblearray$class.foreach(resizeblearray.scala:59)
位于scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:48)
位于org.apache.spark.scheduler.DAGScheduler.updateacumerators(DAGScheduler.scala:1081)
位于org.apache.spark.scheduler.DAGScheduler.handleTaskCompletion(DAGScheduler.scala:1184)
位于org.apache.spark.scheduler.DAGSchedulerEventProcessLoop.doOnReceive(DAGScheduler.scala:1717)
位于org.apache.spark.scheduler.DAGSchedulerEventProcessLoop.onReceive(DAGScheduler.scala:1675)
位于org.apache.spark.scheduler.DAGSchedulerEventProcessLoop.onReceive(DAGScheduler.scala:1664)
位于org.apache.spark.util.EventLoop$$anon$1.run(EventLoop.scala:48)
...
如果有什么区别的话,我认为内存应该收缩,因为项目正在从
数据帧中删除,但事实并非如此

我不明白spark是如何将
DataFrames
分配给Python变量之类的吗


我还尝试将
df.subtract
分配给一个新的临时变量,然后取消持久化
df
,然后将临时变量分配给
df
,取消持久化临时变量,但这也有同样的问题。

这里的基本问题似乎是理解
数据帧的确切含义(这也适用于Spark
RDD
)。本地
DataFrame
对象有效地描述了在给定对象上执行某些操作时要执行的计算

因此,它是一个递归结构,它捕获了它的所有依赖项。在每次迭代中有效地执行计划。虽然Spark提供了一些工具,如检查点
,可以用来解决这个问题并切断沿袭,但问题中的代码一开始就没有多大意义

Spark中可用的分布式数据结构是为高延迟、IO密集型作业而设计的。将单个对象并行化,在数百万个分布式对象上执行数百万个Spark作业无法很好地工作

此外,Spark并不是为高效的单项目操作而设计的。每个
减法
都是O(N),形成一个完整的过程O(N2),在任何大型数据集上实际上都是无用的

虽然很琐碎,但正确的方法是这样的:

items = 5000000

df1 = spark.range(items).selectExpr("cast(id as string)")
df2 = spark.range(items).selectExpr("cast(id as string)")
df1.subtract(df2)