本地化级别:
1. 进程本地化
2. 节点本地化
3. 机架本地化
4. Any(都没有)
Spark在Driver上,对Application的每个stage的task,进行分配之前,都会计算出每个task要计算的是哪个分片数据,RDD的某个partition;Spark的task分配算法优先希望每个task正好分配到它要计算数据所在的节点,这样的话,就不用在网络间传输数据,
但是,通常来说,有时候,事与愿违,可能task没有机会分配到它的数据所在的节点,可能那个节点的计算资源和计算能力都满了,所以,这种时候,通常俩说,Spark会等待一段时间,默认情况下是3s(不是绝对的,还有很多情况,对不同本地化级别都会去等待),到最后,实在等待不了了,就会选择一个比较差的本地化级别,比如说,将task分配到靠它要计算的数据所在的节点,比较近的一个节点,然后计算
但是对于第二种情况,通常来说,肯定要发生数据传输,task会通过器所在节点的BlockManager来获取数据,BlockManager发现自己本地没有数据,会通过一个getRemote()方法,通过TransferService(网络传输组件)从数据所在接地那的BlockManager中,获取数据,通过网络传输回task所在节点。
对于我们来说,当然不希望类似第二种情况,最好的,当然是task和数据在一个节点上,直接从本地executor的BlockManager中获取数据,纯内存,或者带一点磁盘I/O;
我们什么时候要调节这个参数
要观察日志,spark作业的运行日志,在本地看到比较全的日志
日志里面会显示,starting task。。。这里会显示是什么级别
观察大部分task的数据本地化级别
如果大多都是PROCESS_LOCAL,那就不用调节了
如果是发现,好多的级别都是NODE_LOCAL、ANY,那么最好就去调节一下数据的等待时长、
调节完,应该是要反复调节,每次调节完以后,再来运行,观察日志
看看大部分的task的本地化级别有没有提升,看看,整个spark作业的运行时间有没有缩短
不要本地化级别倒是提升了,但是因为大量的等待时长,spark作业运行时间反而增加了,那就不要调节了
怎么调节
spark.locality.wait 默认是3s
set("spark.locality.wait","10")