首页 > 解决方案 > 使用 pyspark 时,有人知道如何解决“java.lang.OutOfMemoryError:GC 开销限制超出”错误吗?

问题描述

我编写了一个 spark 应用程序,它从一个 hive 表(100M 行,~ 3GB)中查询所有数据,通过将其转换为 pandas 数据帧将所有数据收集回驱动程序,遍历每条记录并执行计算并保存结果在一个新的领域。针对数据的子集运行可以正常完成,但针对总体执行此操作会导致“java.lang.OutOfMemoryError:超出 GC 开销限制”错误。驱动程序有足够的内存来处理这些数据以及有限的副本数。驱动程序有大约 125GB 的可用内存,我将工作中的驱动程序内存设置为 32GB。有人可以帮忙吗?


if __name__ == "__main__":
    spark = SparkSession.builder.appName('some_app').getOrCreate()

    sdf = spark.sql("SELECT * from some_database.some_table") # input
    df = sdf.toPandas() # input converted
    results = pd.DataFrame() # output

    for i in df.some_field.unique():
        df2 = "apply some logic"
        results = results.append(df2) # store processed data in results

    sdf2 = spark.createDataFrame(results)
    sdf2.registerTempTable("sdf2")
    spark.sql("DROP TABLE IF EXISTS some_database.my_results")
    spark.sql("CREATE TABLE IF NOT EXISTS some_database.my_results STORED AS PARQUET as select * from sdf2")

标签: apache-sparkpyspark

解决方案


正如错误所说,此操作消耗太多内存,因为正在向驱动程序读取 3GB 数据。实际内存占用量将远远超过 3GB,我假设为 5-10X。这不是一个合适的设计,因为它仅取决于驱动程序的处理能力。

您应该基于 Hive 表“some_database.some_table”创建数据框,而无需转换为 pandas。


推荐阅读