Spark实战(2)_Spark内核架构剖析

Standalone模式

Spark实战(2)_Spark内核架构剖析_第1张图片
Spark内核架构剖析_Standalone模式
  1. 提交Spark应用的机器,Application(自己的Spark程序),spark-submit(shell)提交Application。
  2. Driver(启动一个进程),spark-submit使用Standalone模式提交Application的时候,其实会通过反射的方式,(在本机/客户端)创建和构造一个DriverActor进程出来。
  3. Driver执行我们的Application应用程序,也就是我们编写的代码。
  4. 我们编写的spark应用的第一行,先构造SparkConf,再构造SparkContext。
  5. SparkContext(对象),在初始化的时候,做的最重要的两件事情,就是构造出来DAGScheduler和TaskScheduler。
  6. TaskScheduler(有自己的后台进程),实际上负责,通过它对应的一个后台进程,去连接Master,向Master注册Application。
  7. Master,接收到Application注册的请求之后,会去连接Worker,会使用自己的资源调度算法,在spark集群的多个Worker上,为这个Application启动多个Executor。
  8. Master通知Worker启动Executor。
  9. Worker会为Applicator启动Executor。
  10. Ececutor(进程),启动之后,会自己反向注册到这个Application对应的这个SparkContext里面的的TaskScheduler上去,这时TaskScheduler就知道自己服务于当前这个Application应用的Executor有哪些了。
  11. 所有Eecutor都反向注册到Driver上之后,Driver结束SparkContext初始化,会继续执行我们自己编写的代码。
  12. 每执行到一个action,就会创建一个job。
  13. job,会提交给DAGScheduler。
  14. DAGScheduler,会将job划分为多个stage,然后每个stage创建一个TaskSet。
  15. stage,stage划分算法
  16. 每个TaskSet会提交给TaskScheduler。
  17. TaskScheduler,会把TaskSet里每一个task提交到executor上执行。所以,之前哪些executor是注册到这个TaskScheduler上面来,那么TaskScheduler在接收到TaskSet的时候,就会把Task提交到哪些executor上面去。(task分配算法
  18. Executor(进程),有一个线程池,每接收到一个task,都会用TaskRunner来封装task,然后从线程池里取出一个线程,执行这个task。
  19. TaskRunner,将我们编写的代码,也就是要执行的算子以及函数,拷贝,反序列化,然后执行task。
  20. Task,有两种,ShuffleMapTask和ResultTask,只有最后一个stage是ResultTask,之前的stage都是ShuffleMapTask。
  21. 所以,最后整个spark应用程序的执行,就是stage分批次作为taskset提交到executor执行,每个task针对RDD的一个partition,执行我们定义的算子和函数,这些task在执行完对初始的RDD的算子和函数之后,会产生一个新的RDD,这批task如果在一个stage里面,他会继续执行我们对第二个RDD定义的算子和函数,然后以此类推,这个stage执行完以后会执行下一个stage,到job,直到所有操作执行完为止。

宽依赖与窄依赖

窄依赖

以wordcount为例,lines RDD,通过val words = lines.flatMap(line => line.split(" ")),得到words RDD,这个过程中lines RDD中的每个partition一一对应到words RDD的每个partition。

第一批task,肯定是,先执行针对hdfs的数据,进行读取,读取到lines RDD中,然后同一批task继续工作,对lines RDD进行操作,执行flatMap算子。

words RDD,通过val pairs = words.map(word => (word, 1)),得到pairs RDD,两个RDD的每个partition也是一一对应的关系。

还是那批task,flatMap算子执行完以后,继续针对words RDD执行map算子。

以上一一对应的关系,就是窄依赖,英文名Narrow Dependency,一个RDD,对它的父RDD,只有简单的一对一的依赖关系,也就是说,RDD的每个partition,仅仅依赖于父RDD中的一个partition,父RDD和子RDD的partition之间的对应关系,是一对一的。

宽依赖

pairs RDD,通过val wordCounts = pairs.reduceByKey(_ + _),得到wordCounts RDD。

map算子执行完以后,上一个stage就结束了,会切分出一个新的stage,新的一批task会提交到executor执行,针对pairs RDD,执行reduceByKey算子。

宽依赖,英文全名Shuffle Dependency,本质就是Shuffle,也就是说,每一个父RDD的partition中的数据,都可能会传输一部分,到下一个RDD的每个partition中,此时就会出现,父RDD和子RDD的partition之间,具有交互错综复杂的关系,那么,这种情况,就叫做两个RDD之间是宽依赖,同时,他们之间发生的操作,是shuffle。

Yarn-Cluster提交模式

  1. spark-submit提交(yarn-cluster),客户端与ResourceManager(RM)通信,发送请求到RM,请求启动ApplicationMaster(AM)。
  2. RM分配container,在某个NodeManager(NM)(随机分配)上启动AM。
  3. NM,在AM启动(相当于是Driver)以后,反过来与RM通信,AM找RM,请求container,启动executor。
  4. RM会向AM分配一批contoiner,用于启动executor。
  5. AM(Driver)又会去找其他的NM,AM连接其他NM,来启动executor,这里的NM相当于是Worker。
  6. NM(Worker)上的executor启动后,向AM反向注册。

这里,RM相当于Standalone模式里的Master,AM相当于Driver,NM相当于Worker。

Spark实战(2)_Spark内核架构剖析_第2张图片
Spark内核架构剖析_基于Yarn的两种提交模式

Yarn-Client提交模式

  1. spark-submit提交(yarn-client),发送请求给RM,请求启动AM。但是还是会在本地启动Driver进程。
  2. RM,分配一个container,在某个NM上启动AM,但是这里的AM,其实只是一个ExecutorLauncher。
  3. AM/ExecutorLanucher向RM申请container,启动executor。
  4. RM分配一批container,然后AM连接其他NM,用container的资源,启动executor。
  5. NM上启动executor后,反向注册到本地的Driver上。

两种模式的区别,yarn-cluster的Driver相当于就是在NM上的某一个AM,yarn-client的Driver在本地启动Driver进程,在NM上启动的AM,只是一个ExecutorLanucher,ExecutorLanucher只会向RM申请container资源,然后用申请的container资源连接其他的NM,去启动executor。executor启动之后,会反向注册到我们提交应用的本地客户端的Driver进程上,然后通过本地客户端的Driver进程去做其他事情(大量Task的调度,发送到NM上的executor中去执行)。

yarn-client用于测试,因为Driver运行在本地客户端,负责调度Application,会与yarn集群产生超大量的网络通信,从而导致网卡流量激增,可能会被公司的SA(运维)警告。好处在于,直接执行时,本地可以看到所有的log,方便调试。
yarn-cluster,用于生产环境,因为Driver运行在NM,没有网卡流量激增的问题,缺点在于调试不方便,本地用spark-submit提交后,看不到log,只能用yarn application -logs application_id这种命令来查看,很麻烦。

基于yarn的提交模式的spark-env.sh的配置补充

# 加HADOOP_HOME
export JAVA_HOME=
export SCALA_HOME=
export SPARK_MASTER_IP=
export SPARK_WORKER_MEMORY=
export HADOOP_HOME=
export HADOOP_CONF_DIR=

本文首发于steem,感谢阅读,转载请注明。

https://steemit.com/@padluo


微信公众号「padluo」,分享数据科学家的自我修养,既然遇见,不如一起成长。

Spark实战(2)_Spark内核架构剖析_第3张图片
数据分析

读者交流电报群

https://t.me/sspadluo


知识星球交流群

Spark实战(2)_Spark内核架构剖析_第4张图片
知识星球读者交流群

你可能感兴趣的:(Spark实战(2)_Spark内核架构剖析)