Spark 本地化计算参数调整分析

Spark在Driver上,对Application的每一个stage的task,进行分配之前,都会计算出每个task要计算的是哪个分片数据,RDD的某个partition;Spark的task分配算法,优先,会希望每个task正好分配到它要计算的数据所在的节点,这样的话,就不用在网络间传输数据;

     但是呢,通常来说,有时,事与愿违,可能task没有机会分配到它的数据所在的节点,为什么呢,可能那个节点的计算资源和计算能力都满了;所以呢,这种时候,通常来说,Spark会等待一段时间,默认情况下是3s钟(不是绝对的,还有很多种情况,对不同的本地化级别,都会去等待),到最后,实在是等待不了了,就会选择一个比较差的本地化级别,比如说,将task分配到靠它要计算的数据所在节点,比较近的一个节点,然后进行计算。

    但是对于第二种情况,通常来说,肯定是要发生数据传输,task会通过其所在节点的BlockManager来获取数据,BlockManager发现自己本地没有数据,会通过一个getRemote()方法,通过TransferService(网络数据传输组件)从数据所在节点的BlockManager中,获取数据,通过网络传输回task所在节点。
 

在Spark中数据的本地化分为5种

本地化级别

1、PROCESS_LOCAL : 进程本地化,指task计算的数据在本进程(Executor)中

2、NODE_LOCAL:节点本地化,指task计算的数据在本节点(node)的磁盘上,当task在本进程中一直没有执行(如果Driver分发task 3s后没有执行,且重复5次后),此时Driver就把这个没有执行的task发送到本节点的其他executor中执行

3、NO_PREF:没有本地化这一说,无需本地化,如计算所需的数据在关系型数据中(MySQL或Oracle),node1节点中的MySQL,可以被node2或node3节点连接使用。

4、RACK_LOCAL:task计算的数据是在本机架的其他节点上

5、ANY:随机,任何地方都可以

优先级依次是1到5,逐渐降低
 

参数调整

通过 SparkConf 进行调整:

new SparkConf() 
.set(“spark.locality.wait”, “10”)

默认值: spark.locality.wait,默认为3s

PROCESS_LOCAL : spark.locality.wait.process   默认为3s

NODE_LOCAL:spark.locality.wait.node

RACK_LOCAL: spark.locality.wait.rack

观察大部分task的数据本地化级别 
如果大多都是PROCESS_LOCAL,那就不用调节了

如果是发现,好多的级别都是NODE_LOCAL、ANY,那么最好就去调节一下数据本地化的等待时长。

调节完,应该是要反复调节,每次调节完以后,再来运行,观察日志 
看看大部分的task的本地化级别有没有提升;看看,整个spark作业的运行时间有没有缩短。
实践出真理!!!

图例:

获取本地化级别时间 对应代码:
private def getLocalityWait(level: TaskLocality.TaskLocality): Long = {

  // 默认等待时间,取自参数spark.locality.wait,默认为3s
  val defaultWait = conf.get(config.LOCALITY_WAIT)

  // 根据不同的TaskLocality,取不同的参数,设置TaskLocality等待时间
  // PROCESS_LOCAL取参数spark.locality.wait.process
  // NODE_LOCAL取参数spark.locality.wait.node
  // RACK_LOCAL取参数spark.locality.wait.rack

  val localityWaitKey = level match {
    case TaskLocality.PROCESS_LOCAL => "spark.locality.wait.process"
    case TaskLocality.NODE_LOCAL => "spark.locality.wait.node"
    case TaskLocality.RACK_LOCAL => "spark.locality.wait.rack"
    case _ => null
  }

  if (localityWaitKey != null) {
    conf.getTimeAsMs(localityWaitKey, defaultWait.toString)
  } else {
    0L
  }
}

参考链接:

https://blog.csdn.net/JasonZhangOO/article/details/79350149

https://blog.csdn.net/lxhandlbb/article/details/52987909

猜你喜欢

转载自blog.csdn.net/zhanglong_4444/article/details/85332124
今日推荐