Spark | 数据本地性

Spark在Driver上会对Application的每一个Stage的Task进行分配前,都会计算出每个Task要计算的是哪个分片数据,RDD的某个partition;Spark的Task分配算法会让每个Task正好分配到它要计算的数据所在的节点,这样不用在网络间传输数据,因此在DAG划分Stage分配Task任务时候就确定好了数据本地性。

 但通常来说,很有可能因为节点A的计算资源和计算能力都满了导致Task没有机会分配到它的数据所在的节点A,Spark会在等待一段时间后会选择一个比较差的本地化级别,比如将这个Task分配到靠它要计算的数据所在节点,比较近的一个节点,然后进行计算。

面对这种情况一般会发生数据传输,Task会通过其所在节点的BlockManager来获取数据,BlockManager发现自己本地没有数据,会通过一个getRemote()方法,通过TransferService(网络数据传输组件)从数据所在节点的BlockManager中,获取数据,通过网络传输回Task所在节点。

Task任务读取数据本地性共分为五个级别:

PROCESS_LOCAL:要处理的数据就在同一个本地进程中,即数据和Task在同一个Executor JVM中,即RDD的数据在之前已经被缓存过了,因为BlockManager是以Executor为单位的,所以只要Task所需要的Block在其Executor的BlockManager上已经被缓存。这种实最优的,因为数据不需要在网络中传输。

NODE_LOCAL:数据在同一台节点上,但是并不不在同一个JVM中,比如数据在同一台节点上的另外一个Executor上,速度要比PROCESS_LOCAL略慢。还有一种情况是读取HDFS的块就在当前节点上,数据本地性也是NODE_LOCAL。

NO_PREF:数据从哪里访问都一样,表示数据本地性无意义,看起来很奇怪,其实指的是从MySQL、MongoDB之类的数据源读取数据。

RACK_LOCAL:数据在同一机架上的其它节点,需要经过网络传输,速度要比NODE_LOCAL慢。

ANY:数据在其它更远的网络上,甚至都不在同一个机架上,比RACK_LOCAL更慢,一般情况下不会出现这种级别。

 

发布了44 篇原创文章 · 获赞 11 · 访问量 5448

猜你喜欢

转载自blog.csdn.net/Sampson_Hugo/article/details/103388484