关于Spark中的常见问题及解决方法(2) ——Stragglers/任务执行缓慢

 

 

 

前言

在优化应用程序时,这类问题非常常见,大多数时候可能是由于Tasks在集群上不均匀分,数据倾斜,或者某台计算节点的性能比其的差(例如,硬件上的性能劣势)。

主要症状

  • 某一个task卡主导致后续的stage无法启动
  • Spark UI在观察到对于同一个数据集的作业,某些tasks总是执行缓慢。
  • 增加更多的executor并不能解决问题,某些task依旧比其他的消耗更多的时间。
  • 在SparkUI中可以观察到某些task比其他的读写更多的数据。

可能的原因

执行缓慢的任务通常被称为"stragglers(落后者)"。造成这种情况的原因有很多,但大多数情况下,这个问题的根源是被处理数据被不均匀地划分到DataFrame或RDD分区内。 当发生这种情况时,一些Executor可能需要处理比其Executor更多的工作。 一个特别常见的情况是使用group-by-key操作,其中一个键比其他键含有更多的数据。 在这种情况下,当我们查看Spark UI时,会发现某些节点的shuffle数据比其他节点大得多。

可能的解决方法

  • 尝试增加分区数,减少每个分区包含的数据。
  • 尝试通过另一种列组合重新分区。 例如,当您通过倾斜列 或 可能包含许多值为null的列进行分区时,straggler就会出现。 在后一种情况下,首先过滤掉空值可能是有意义的。
  • 如果可以,尝试增加每个executor所分配的内存
  • 监视有问题的executor,可能是因为群集中的某一个不健康的executor或节点- 例如,磁盘以满。
  • 查看是否是 Join或者Aggregation问题
  • 检查UDF在业务逻辑中是否滥用现象。 如果可能,尝试将它们转换为DataFrame代码,即尽量使用built-in的函数。
  • 确保使用的UDF或UDAF在足够小的数据批量上运行。 通常,聚合根据主键将大量数据拉入内存,从而导致某个executor不能不处理更多的数据。
  • 当您使用数据集时,可能会出现另一类常见问题。 由于Dataset执行大量对象实例化来将记录转换为UDF的Java对象,因此它们可能导致大量垃圾回收。 如果你在使用Dataset,请查看Spark UI中的垃圾收集指标,看看它们是否与缓慢的任务一致。

总结

Stragglers可能是最难调试的问题之一,因为有很多可能的原因。 但是,大多数情况下,可能是因为某种数据产生倾斜。 因此在发生这种问题时,请务必第一时间通过Spark UI检查task之间是否存在数据不平衡的现象。

参考资料

[BOOK] Spark - The Definitive Guide

posted @ 2019-03-27 10:21  LestatZ  阅读(1092)  评论(0编辑  收藏  举报