Spark参数调优之locality wait

背景

工作中使用Spark Streaming处理实时数据流,发现所处理的数据量与所消耗的时间很不对等,如下图:

Stage耗时

区区几KB的数据,简单的mapToPair操作,竟然耗时4~5秒,很不合理。

于是,点击进去看Stage详情:

Task耗时

可见所有Task的耗时都是毫秒级的,怎么整个Stage就需要4秒呢?

通过查看EventTimeline,发现竟然有3秒的空窗期,这3秒内,没有任何Task再执行,而正是这3秒导致整个Stage的耗时增加。

EventTimeline 3秒空窗期

解决方法

启动Spark任务时,设置参数spark.locality.wait=0s即可。

什么是 locality wait ?

为什么会等待3秒呢?

原来这是Spark的一个任务管理策略。Spark把Stage拆解成N个Task,那么这N个Task要交给哪些节点去处理,就有说法了。

考虑到不同节点之间数据转移、复制的带宽成本会比较高,所以应尽量避免数据在不同节点之间流转。那对应的策略就是:数据在哪个节点上,就把Task分配到对应的节点上,这样就避免了不必要的网络传输。

那么,这就引出另外一个问题,数据所在的节点比较忙,压力比较大,没有资源来执行你分配的任务怎么办?

Spark的策略是:等你一会儿。

这就是spark.locality.wait参数的含义了。这个参数默认值是3秒,那么就会等待数据节点3秒钟。在3秒内数据节点有资源并且成功创建了任务,那么就省去了网络传输;如果3秒内没有创建成功,那么就把任务分派给其他有资源的节点去完成了。

如何调优?

等待3秒,这是Spark的默认策略。实际应用中,我们应该根据具体的数据情况来适当调整这个参数。

以本文背景为例,每次处理就区区几KB的数据,就算走网络和很快就完成了,肯定是远小于3秒,那么这种情况就可以调到0秒,也就是不要管带宽压力,直接给按资源情况分配任务。

而如果这个数据很大,网络传输的话耗时远超3秒,这是可以适当调大spark.locality.wait,已避免网络传输。

按照官方的建议,如果Jobs处理时间很短(小于2秒),就把这个值调小,甚至是0;如果Jobs处理时间很长,也不在乎多等几秒,那么就适当调大。

参考引用

https://support.datastax.com/hc/en-us/articles/208237373-FAQ-When-is-it-a-good-idea-to-set-Spark-locality-wait-to-zero-

你可能感兴趣的:(Spark参数调优之locality wait)