Spark内存泄漏SOP

1 驱动日志——问题原因

如任务因为超过最大试错次数spark.task.maxFailures导致失败等。

理解:通常可作为问题诊断的出发点。

此案例的原因为执行器失联。

2 执行日志——具体原因

表象:OOM

原因:通常为内存不足导致的节点失效。

3 GC活动——内存诊断

表象:GC时间过长,并且经常负载超限

尝试方案:按照Spark GC调优文档,通常可以使用以下参数解决:

1
spark.executor.extraJavaOptions: -XX:+UseG1GC

效果:阶段性GC速率提升、GC频率降低、负载超限异常消失,但是Full GC还是很慢,并且还有OOM

4 集群健康度——寻找线索

如使用Ganglia分布式监控系统。

Cluster memory screenshot from Ganglia

表象:内存逐步累积

可能原因:
1 状态作业没有及时清理状态

2 内存泄漏

5 检查流式监控指标——分析原因

截屏2022-01-11 下午3.33.44

通过观察stateOperators.numRowsTotal,得到总体行数量随时间保持稳定。排除OOM导致。

以下针对内存泄漏诊断原因。

6 启用堆快照

启用堆快照:

1
spark.executor.extraJavaOptions: -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/dbfs/heapDumps

7 周期性导出堆快照

为了比对平常和异常是堆快照差异,每12小时导出一次对快照。

导出命令:

1
jmap -dump:format=b,file=pbs_worker.hprof <pid>

8 分析堆快照

通常可以使用分析工具YourKit或Eclipse MAT。

对于过大的快照可以使用以下方式:

使用MAT中的ParseHeapDump.sh脚本创建索引并输出报告,并且可以直接在MAT中打开索引。

Tool for analyzing large Java heap dumps

9 查找泄漏点

Screenshot from YourKit

观察类和包视图,发现泄漏点在AWS-SDK中。查阅资料后确定未正常关闭连接导致。

Possible Memory Leak - Connection Reaper

10 结语

  • 基于日志和经验收集线索,分析线索并定位问题
  • 内存泄漏多发于连接未正常关闭、对象引用未正常回收

参考资料