首先,读者需要知道Spark的task是干什么的?
详见笔者之前的文章《Spark性能调优之调节task并行度》
介绍task 摘要如下:
我们写的spark作业称为application;
一个application有多个job(一个action比如:collect操作触发一个job);
每个job在发生shuffle(比如:reduceByKey)时,就会被拆成一个stage;
每个stage被拆为多个task,task被分配到executor上执行,一个task会有一个线程去执行,
一个task处理一小片数据。
为什么又有 “数据本地化等待时长 ” - - spark.locality.wait 这个参数呢?
Spark在driver 上,对application的每个stage的task分配之前,会先计算出每个task要计算的是哪个分片数据(RDD 上的某个Partition);Spark分配task的算法,优先希望每个task恰好分配到它所要计算的数据的节点上,这样,就避免了网络间数据传输。
但事实上,有时候,task并没有分配到它所要计算的数据的节点上,原因呢?
有可能是那个节点的计算资源和计算能力满了,task处理数据是需要计算资源的。所以,通常来说,Spark会等待一段时间,看能否将task分配到它要处理数据所在节点上,这个等待时长默认是3秒(3s不是绝对的,针对不同的本地化级别可以设置不同等待时长)。如果超过等待时长,无法继续等待,就会选择一个性能比较差的本地化级别,比如说:将task分配到距离它所要处理数据节点比较近的一个节点上,然后传输数据进行计算。
对于我们来说,最好是,task正好分配到它要处理数据所在节点上,这样直接从本地executor