Pyspark简单的重新分区和toPandas()无法完成600,000多行

时间:2016-10-01 20:15:49

标签: apache-spark memory pyspark distributed-computing bigdata

我有JSON数据,我正在读取包含多个字段的数据框,根据两列重新分区,然后转换为Pandas。

这项工作在仅有600,000行数据的EMR上失败,但有一些模糊的错误。我还增加了火花驱动器的内存设置,但仍然没有看到任何分辨率。

这是我的pyspark代码:

enhDataDf = (
    sqlContext
    .read.json(sys.argv[1])
    )

enhDataDf = (
    enhDataDf
    .repartition('column1', 'column2')
    .toPandas()
    )
enhDataDf = sqlContext.createDataFrame(enhDataDf)
enhDataDf = (
    enhDataDf
    .toJSON()
    .saveAsTextFile(sys.argv[2])
    )

我的火花设置如下:

conf = SparkConf().setAppName('myapp1')
conf.set('spark.yarn.executor.memoryOverhead', 8192)
conf.set('spark.executor.memory', 8192)
conf.set('spark.driver.memory', 8192)
sc = SparkContext(conf=conf)

我得到的错误是:

16/10/01 19:57:56 ERROR executor.CoarseGrainedExecutorBackend: Driver 172.31.58.76:37973 disassociated! Shutting down.
16/10/01 19:57:11 ERROR executor.CoarseGrainedExecutorBackend: Driver 172.31.58.76:42167 disassociated! Shutting down.
16/10/01 19:57:56 ERROR executor.CoarseGrainedExecutorBackend: Driver 172.31.58.76:37973 disassociated! Shutting down.
log4j:ERROR Could not read configuration file from URL [file:/etc/spark/conf/log4j.properties].
log4j:ERROR Ignoring configuration file [file:/etc/spark/conf/log4j.properties].
16/10/01 19:57:11 ERROR ApplicationMaster: RECEIVED SIGNAL 15: SIGTERM
16/10/01 19:57:11 ERROR ApplicationMaster: User application exited with status 143
log4j:ERROR Could not read configuration file from URL [file:/etc/spark/conf/log4j.properties].
log4j:ERROR Ignoring configuration file [file:/etc/spark/conf/log4j.properties].
16/10/01 19:57:56 ERROR ApplicationMaster: RECEIVED SIGNAL 15: SIGTERM
16/10/01 19:57:56 ERROR ApplicationMaster: User application exited with status 143
16/10/01 19:57:11 ERROR executor.CoarseGrainedExecutorBackend: Driver 172.31.58.76:42167 disassociated! Shutting down.
16/10/01 19:57:56 ERROR executor.CoarseGrainedExecutorBackend: Driver 172.31.58.76:37973 disassociated! Shutting down.

代码在最多约600,000条JSON线上工作正常 - 即使有大量可用内存。然后,它一直在失败。

有关正在发生的事情以及如何调试/解决此问题的任何想法?

2 个答案:

答案 0 :(得分:4)

我认为问题来自您的代码的以下部分:

enhDataDf = (
    enhDataDf
    .repartition('column1', 'column2')
    .toPandas()
)

.toPandas()收集数据,因此当记录数量增加时,将导致驱动程序失败。

根据您的评论,这是您使用的确切管道。这意味着整个阶段不仅过时而且不正确。收集数据并进一步并行化时,可以保证由

创建分区
.repartition('column1', 'column2')
重新创建Spark DataFrame

时,将保留

sqlContext.createDataFrame(enhDataDf)

如果您想按列编写数据,可以直接执行:

(sqlContext
    .read.json(sys.argv[1])
    .repartition('column1', 'column2')
    .write
    .json(sys.argv[2]))

跳过中间toPandas并转换为RDD。

发表评论:

如果toPandas有用,那么它将始终成为管道中的限制因素,唯一直接的解决方案是扩展驱动程序节点。根据您在收集的数据上应用的确切算法,您可以考虑其他选项:

  • 重新实现你在Spark上使用的算法,它已经没有了。
  • 考虑具有更好的SciPy堆栈互操作性的替代框架(如Dask)。

答案 1 :(得分:1)

这让我想起了我的Spark – Container exited with a non-zero exit code 143,我正在 cluster 模式下运行PySpark作业,这表明你的应用程序存在内存问题。

首先尝试确定哪些机器出现故障,驱动程序或执行程序,从而能够更好地针对您的行动 - 从我读到的,它应该是执行者。

我可以看到你已经设置好memoryOverhead配置了。现在让我们关注memory配置:

  

...使用Spark(PySPark)运行Python,因此我的所有代码都在堆中运行。出于这个原因,我必须分配“不多”的内存(因为这将削减我可以从总内存中使用的内存;即,如果我允许使用的总内存是20G而我请求12G,那么8G将留给我的Python应用程序使用。

所以尝试减少该属性,是的,减少它!

下一个目标: #cores

减少它,例如,如果你使用8,那么在执行器和/或驱动程序中使用4:

spark.executor.cores                        4
spark.driver.cores                          4