调试带有大型 JSON 数据处理的 Spark 驱动程序内存不足 (OOM) 问题

主要观点:作为数据工程师遇到 Apache Spark 内存管理和内部处理的复杂挑战,一个 25GB 的数据集导致驱动程序内存溢出错误,文章讨论 Spark 内部处理复杂性和内存管理以构建弹性数据复制解决方案,深入探讨了 OOM 问题的原因(如生成的计划字符串过大、数据集内部表示等),提出了修复方法(关闭解释计划或优化实现,仅使用 DataFrame 操作计算净变化),并给出了 OOM 的快速经验法则(区分驱动程序和执行器的风险因素)。

关键信息:

  • 场景:读取 25GB 的 DynamoDB 导出 JSON 数据,使用 Spark 进行处理,执行简单的isEmpty()操作时出现 OOM 错误。
  • 原因:Spark 为日志、UI 等目的生成计划字符串表示,由于数据集内部表示和 Spark 遍历生成计划,导致计划字符串过大,消耗大量内存。
  • 修复方法:关闭解释计划(目前 Spark 无此功能)或优化实现,仅使用 DataFrame 操作计算净变化,本地测试显示内存消耗显著降低。
  • OOM 经验法则:区分驱动程序和执行器的内存风险因素,如驱动程序的collect等操作和执行器的shuffle等操作。

重要细节:

  • 集群配置:9 台机器的 Glue Spark 集群,每台机器 32vCPU 和 128GB 内存。
  • 代码细节:展示了导致 OOM 的代码片段,包括从读取数据到计算净变化的过程,以及优化后的仅使用 DataFrame 操作的代码。
  • 堆栈跟踪:详细的 OOM 堆栈跟踪,显示 Spark 在执行过程中调用explainString方法生成计划字符串。
  • 内存相关属性:Spark 中控制计划生成的maxToStringFieldsmaxPlanStringLength属性,仅影响格式化或截断输出,不控制遍历本身。
阅读 7
0 条评论