今天有朋友问之前NodeManager被Shuffle拉挂的问题,借此机会将之前分析的另一文档整理一下分享出来。
现象描述及分析
9月27日10时左右,编号为2611节点执行应用时发生先前描述的NM OOM问题。其中触发该问题的应用的部分信息如下所示:
- 应用Stage信息如下所示:
由该图可知,Stage3包含10万+Map任务,Stage4有3000个Reduce任务。
Stage3 中每个Map任务会将处理的数理 Hash成3000份并存入一个文件当中。
-
Stage3阶段, 编号2611节点中分配的Executor信息:
应用其申请100个Executor, 其中4个Executor落在编号为2611节点(为单节点Executor最多的情况),2611中4个Executor共执行3512个Map Task. 即理论上会有3512个shuffle临时文件落在该节点。因为Reduce任务数为3000,所示每个临时文件中包含3000个reduce task的数据(备注:任务数据本无倾斜,调度原因导致倾斜)。
3000个reduce任务会到编号为2611中的3512个文件中取回属于自己的数据,所以共需要打开30003512次文件(FileInputStream数目),然而:
由FailedStages信息可知已执行的Task数约为2200(之后出现错误退出)
则在编号2166节点打开文件次数大约为 3512 * 2200 = 7726400次(考虑索引文件时,该值2,2611节点约创建1500万FileInputStream).
而通过分析OOM时Dump文件,结果显示Finallizer堆集数量为430万+, 因此理论上Shuffle Service有致使Finallizer堆集至430万+的可能.
应用重试结果
NM挂掉之后, 任务抛出下述异常:
FetchFailed(BlockManagerId(69, ****2611.****.com, 7337)
重新提交后,应用正常执行完成,分析Executor列表,最多两个Executor分配至同一个Node。
问题?
由Shuffle Service原理可知,同一个NM上的所有Executor共用同一个服务, 因此在某个NM上运行的Executor过多时,其对外提供Shuffle服务的负担会变重…特别是同一个应用的多个Executor调度到同个NM时,问题会更加严重, 因为这些Executor的shuffle数据将同一时间被reduce拉取(不同应用会有错峰的可能)。
因此,RM如何为Spark APP分配container会影响Shuffle Server的负载强度,即OOM发生的风险。
==Yarn 调度时是否可以增加如下机制:==
- ==对同一APP的Container进行调度时,打散到多个NM, 类似于Spark Streaming中Receiver的调度,尽量避免隶属同一APP的Container在同一个NM上堆积==
此举可减轻Shuffle Server负担,可在一定程度上避免OOM发生,再结合之前“Shuffle Service 导致NM OOM问题分析”解决方案,可更好的解决NM 挂掉问题
另外:
同一应用中任务在同一时间会必然竞争相同的资源,若隶属同一个应用的Container过多的落在同一NM上时,在逻辑资源隔离的背景下,理论上会降低任务执行效率。
若将其打散,则应用在某Node上的Container会与其它应用重合,则存在相同资源错峰使用的可能,在一定程度上还会比相同应用Container堆叠时作业执行效率高。
附 网络信息
//由上述Stage信息图可知Stage4 shuffle任务 从09:39开始提交执行,其网络使用情况如下所示:
9:52左右NM日志中开始出现异常信息… 10:05左右NM挂掉…
由该信息可知,shuffle时fetch请求量较非shuffle阶段高很多…
(totsck: socket总数量, tcpsck用于TCP的socket数量)
09:36:01 AM totsck tcpsck udpsck rawsck ip-frag tcp-tw
09:37:01 AM 682 341 10 0 0 5081
09:38:01 AM 711 345 10 0 0 8289
09:39:01 AM 690 353 10 0 0 10512
09:40:01 AM 880 512 10 0 0 8532
09:41:01 AM 1013 660 10 0 0 5957
09:42:01 AM 1879 1589 10 0 0 3357
09:43:01 AM 2717 2434 10 0 0 1251
09:44:01 AM 3445 3150 10 0 0 629
09:45:01 AM 4061 3784 10 0 0 291
09:46:01 AM 4727 4451 10 0 0 81
09:47:01 AM 5639 5362 10 0 0 62
09:48:01 AM 6463 6187 10 0 0 72
09:49:01 AM 7447 7160 10 0 0 94
09:50:01 AM 8453 8176 10 0 0 56
09:51:01 AM 9638 9364 10 0 0 108
09:52:01 AM 10740 10466 10 0 0 56
09:53:01 AM 11808 11533 10 0 0 323
09:54:01 AM 12634 12357 10 0 0 207
09:54:01 AM totsck tcpsck udpsck rawsck ip-frag tcp-tw
09:55:01 AM 13742 13468 10 0 0 71
09:56:01 AM 14859 14584 10 0 0 35
09:57:01 AM 16005 15725 10 0 0 53
09:58:01 AM 17124 16834 10 0 0 71
09:59:01 AM 18213 17925 10 0 0 53
10:00:01 AM 19134 18804 10 0 0 40
10:01:01 AM 19792 19464 10 0 0 38
10:02:01 AM 20394 20102 10 0 0 48
10:03:01 AM 21017 20690 10 0 0 53
10:04:02 AM 21077 20789 10 0 0 26
10:05:01 AM 21897 21584 10 0 0 42
10:06:01 AM 710 393 9 0 0 144
10:07:01 AM 726 404 9 0 0 49
注: 官方Spark 2 版本做了众多与Shuffle Service相关工作(SPARK-21475,20994,20426等),可以拉取相关patch解决该问题。
另外 Yarn社区也有提出System Container的概念,旨在将Shuffle Service等AuxiliaryServices独立于NodeManger之外,可以做为终极解决方案的参考,地址见:https://issues.apache.org/jira/browse/YARN-1593。