Spark数据本地化
背景:
数据本地化对于Spark Job性能有着巨大的影响,如果数据以及要计算它的代码是一起的,那么性能当然会非常高。但是如果数据与计算它的代码是分开的,那么其中之一必须到另外一方机器上,通常来说,移动代码到其它节点,会比移动数据到代码所在的节点上,速度要快的多。
因为代码较小,Spark也正是基于这个数据本地化的原则来构建Task调度算法的。
数据本地化:数据离计算它的代码有多近,基于数据距离代码的距离,有几种数据本地化级别:
1.PROCESS_LOCAL:进程本地化,性能最佳。数据和计算它的代码在同一个JVM进程中。
2.NODE_LOCAL:节点本地化。数据和计算它的代码在一个节点上,但是不在一个进程中,比如在不同的executor进程中,或者是数据在HDFS文件的block中。
3.NO_PREF:从任何地方访问数据速度都是一样,不关心数据的位置。
4.RACK_LOCAL:数据和计算它的代码在一个机架上。
5.ANY:数据可能在任意地方,比如其他网络环境内,或者其他机架上,性能最差。
调节参数:
Spark.locality.wait:默认是3S。
扩展参数(默认值为Spark.locality.wait):
spark.locality.wait.process
spark.locality.wait.node
spark.locality.wait.rack
调节一般默认3S,重试5次的分配,如果超时失败,则下降一个本地级别重新分配,如果发生数据传输,Task先从BlockManager获取数据,若本地没有数据,则通过getRemote方法从数据所在节点BlockManager获取数据并返回Task所在节点。
1.如果Task和数据在同一个JVM中,那么这个时候性能是最好的。
2.但是如果这个executor已经分配了许多Task任务,没有剩余资源可以启动Task任务。那么这时,Task的任务调度算法会选择等待,具体等待需要多长时间需要我们开发人员进行调优。
3.如果等待一会后,该executor里有空余的资源,可以使用,那么我们就会在里面启动Task任务,这样是不是达到了调优的目的。
4.如果等待一会后,依旧没有空余资源释放,那么这时就会下降一个级别。比如,这个服务器上另外一个executor里资源是空闲的,那么就会在另外的executor里启动Task任务,这时就需要跨进程复制数据。