执行许多数据框连接时出现PySpark OutOfMemoryErrors

时间:2018-07-12 16:55:42

标签: python apache-spark pyspark

关于此问题的帖子很多,但没有一个回答我的问题。

在尝试将许多不同的数据帧连接在一起时,我在PySpark中遇到了OutOfMemoryError

我的本​​地计算机具有16GB的内存,并且我已经将Spark配置设置如下:

class SparkRawConsumer:

    def __init__(self, filename, reference_date, FILM_DATA):
        self.sparkContext = SparkContext(master='local[*]', appName='my_app')
        SparkContext.setSystemProperty('spark.executor.memory', '3g')
        SparkContext.setSystemProperty('spark.driver.memory', '15g')

很明显,有很多关于Spark中OOM错误的SO帖子,但是基本上大多数文章都说是为了增加您的内存属性。

我基本上是从50-60个较小的数据帧执行联接的,这些数据帧有两列uiddata_in_the_form_of_lists(通常是Python字符串列表)。我要加入的主数据框大约有10列,但还包含一个uid列(我要加入的列)。

我仅尝试合并1,500行数据。但是,当所有这些数据都可以放入内存时,我会经常遇到OutOfMemory错误。我通过在存储中查看SparkUI来确认这一点:

Spark UI screenshot

在代码中,我的联接如下所示:

# lots of computations to read in my dataframe and produce metric1, metric2, metric3, .... metric 50
metrics_df = metrics_df.join(
                self.sqlContext.createDataFrame(metric1, schema=["uid", "metric1"]), on="uid")

metrics_df.count()
metrics_df.repartition("gid_value")
metrics_df = metrics_df.join(
                self.sqlContext.createDataFrame(metric2, schema=["uid", "metric2"]),
                on="gid_value")

metrics_df.repartition("gid_value")
metrics_df = metrics_df.join(
                self.sqlContext.createDataFrame(metric3, schema=["uid", "metric3"]),
                on="uid")

metrics_df.count()
metrics_df.repartition("gid_value")

metric1metric2metric3都是RDD的情况下,我在连接之前将其转换为数据帧(请记住,实际上我有50个较小的metric df加入)。

我打电话给metric.count()来强制评估,因为这似乎有助于防止内存错误(否则,在尝试最终收集时,我会得到更多的驱动程序错误)。

错误是不确定的。我看不到它们始终出现在我的联接中的任何特定位置,有时似乎是在我的最后一个metrics_df.collect()通话中,有时是在较小的联接中。

我真的怀疑任务序列化/反序列化存在一些问题。例如,当我查看事件时间表的一个典型阶段时,我发现其中的大部分是由任务反序列化处理的:

Spark UI screenshot serialization

我还注意到垃圾收集时间很多:

Spark UI screenshot garbage collection

垃圾回收是否是导致内存错误的问题?还是任务序列化?

编辑以回答评论问题

我一直在作为较大的PyCharm项目的一部分来运行Spark作业(因此,为什么Spark上下文围绕一个类包装)。我使用以下火花提交重构了代码以将其作为脚本运行:

spark-submit spark_consumer.py \
  --driver-memory=10G \
  --executor-memory=5G \
  --conf spark.executor.extraJavaOptions='-XX:+UseParallelGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps'

1 个答案:

答案 0 :(得分:1)

我遇到了类似的问题,并且可以解决以下问题:
Spark提交:

spark-submit --driver-memory 3g\
            --executor-memory 14g\
            *.py

代码:

sc = SparkContext().getOrCreate()
相关问题