spark原理学习总结

来源:互联网 发布:红帽群排名优化软件 编辑:程序博客网 时间:2024/06/07 10:04

Spark运行基本流程


Spark运行基本流程参见下面示意图 
1.构建Spark Application的运行环境(启动SparkContext),SparkContext向资源管理器(可以是Standalone、Mesos或YARN)注册并申请运行Executor资源; 
2.资源管理器分配Executor资源并启动StandaloneExecutorBackend,Executor运行情况将随着心跳发送到资源管理器上; 
3.SparkContext构建成DAG图,将DAG图分解成Stage,并把Taskset发送给Task Scheduler。Executor向SparkContext申请Task,Task Scheduler将Task发放给Executor运行同时SparkContext将应用程序代码发放给Executor。 
4.Task在Executor上运行,运行完毕释放所有资源。 
这里写图片描述

Spark运行架构特点:

  • 每个Application获取专属的executor进程,该进程在Application期间一直驻留,并以多线程方式运行tasks。这种Application隔离机制有其优势的,无论是从调度角度看(每个Driver调度它自己的任务),还是从运行角度看(来自不同Application的Task运行在不同的JVM中)。当然,这也意味着Spark Application不能跨应用程序共享数据,除非将数据写入到外部存储系统。
  • Spark与资源管理器无关,只要能够获取executor进程,并能保持相互通信就可以了。
  • 提交SparkContext的Client应该靠近Worker节点(运行Executor的节点),最好是在同一个Rack里,因为Spark Application运行过程中SparkContext和Executor之间有大量的信息交换;如果想在远程集群中运行,最好使用RPC将SparkContext提交给集群,不要远离Worker运行SparkContext。
  • Task采用了数据本地性和推测执行的优化机制。
sparkApplication 提交给spark,启动SparkContext,资源管理器根据spark-submit中提供的参数,申请相应的资源,在work节点上开辟Exeutor进程。个节点上申请后的exeutor进程向SparkContext注册,说我现在准备好了,可以分配Task给我运行。于是驱动程序Driver       的 SparkContext 构建DAG有向五环图的  ,把job拆分为多个阶段state,每个state有多个Task,多个Task为一个taskset。于是把taskset分配给来Exeutor来运行。
Exeutor中根据spark-submit中提供的参数,分配了相应的内存和cpu core 数,Exeutor中用于运行task,1个CPU core 在同一个时间了只能运行一个线程,一个线程用于运行一个task,也就是一个cpu core 运行一个task。 同一阶段state里的task运行的逻辑是一样的,只是处理的数据不同。也是是task用于处理partition里数据,一个task处理一个分区partition的数据。
spark的job的阶段state是根据sparkApplication 中的shuffle算子来决定。shuffle算子之前是一个阶段,shuffle算子之后是一个阶段。
shuffle操作发生在两个state阶段之间。一个阶段state中的task是可以并行操作的,而shuffle过程中是不能发生并行操作的。
shuffle操作简单的说是把不同节点中具有相同key的数据拉取到同一个节点来。
进行shuffle操作的时候,先要把数据写入磁盘,序列化,通过网络传输,相同key的数据写到同一个节点来。其中涉及到磁盘io,网络传输,序列化等操作,所以shuffle是一个很耗性能操作,所以尽量使用shuffle操作。

一个阶段state的中task运行完得到的结果写入到磁盘文件中,启动下一个阶段state的task,读取上一个阶段state中的处理的数据结果作为这次阶段中的输入源。如此循环,直到最后执行完成。


spark streaming 中  一个 batch interval  间隔  处理一批数据,batch interval 里有多个Rdd, 其中一个rdd中有多个partition,其中每个partition中有多条数据,一个partition 由一个task 来处理里,一个task是一个线程,一个线程占用一个cpu core.
SparkStreamingContext 是驱动程序,通过submit 向资源管理器 (如yarn 资源管理器) 申请Exeutor和内存资源。
其中Exeutor中占有一定数量的CPU core 和内存资源。其中内存资源,默认情况下 20%用于task代码的运行,20%用途shuffle操作的,其余60%是用于rdd 数据持久化。

性能调优方面: 运行task的比较慢的时候,内存不足,频繁导致gc操作,这时候可以适当的增加其内存,减少持久化的内存或者shuffle的内存  。


SparkStreamingContext 是驱动程序 把 程序 拆分为多个阶段state,一个阶段state有一个或者多个rdd,一个阶段state里有多个task来运行处理rdd。阶段的划分是根据shuffle操作来决定,shuffle操作之前为一个阶段state,shuffle操作及其之后为另外一个阶段state。

spark RDD 特征介绍

rdd 在java中可以理解为一个特殊的对象,在对象中包含了我们从HDFS上拉去到的记录数据data,同时包含了一些处理记录数据data的方法,这些方法即为为rdd提供的算子(map,groupbykey,reducebykey等)。其中rdd中由多个partition组成,一个spark job有多个阶段,一个阶段state有多个rdd,一个rdd有多个partition,partition 分布在 spark集群的多个节点work上,work里分配了对于的资源exeutor(cpu core + 内存),同时spark Diver程序会分配处理这些partition的部分逻辑代码块执行,这些逻辑代码块即为task,也就是可以把task起看做一个线程,task来处理这些partition,一个task一次处理一个partition中的数据,一个partition中可以有多条数据,或者没有数据。exeutor中可以有多个task并行运行,同时间并行运行task数由executor中的分配的cpu core 数来决定。

rdd具有弹性分布式,rdd的partition中的数据可以根据存储级别,持久化到内存还是磁盘中。rdd自身也有权衡机制来决定存储数据内存还是磁盘,这种特性是rdd的弹性分布式的特征。
rdd中具有容错性,在rdd运行过程中,某个分区partition的数据有可能丢失的情况,这种情况下,rdd具有容错机制,需要重新从源端读取数据,经过一系列的rdd转换到目前的阶段的rdd中partition的数据。这是rdd的容错机制。
spark在性能调优中,可以对多次使用的rdd进行持久化,使用cache 或者persist操作来持久化rdd,这用可以在第二次使用同样的rdd的时候再次重源端读取数据。减少了不必要的操作,提高了性能。
在持久化cache,persist的数据,也有可能出现丢失的情况,这个时候可以使用checkpoint操作,对cache的数据做一个备份。checkpoint的数据可以指定一个HDFS地址,当
cache中的数据出现丢失情况下,可以从到该HDFS目录下找到数据,而不用再次重源端经过一系列的rdd操作获取数据。

窄依赖 和宽依赖
窄依赖: 窄依赖是上一个rdd中partition中的数据到下一个rdd中partition 是一对一的,也就是上一个rdd中partition的数据只转换到下一个rdd中的一个partition中。算子转换 例如  map  filter

宽依赖  : 宽依赖是指上一个rdd中partition中的数据被转换分散到下一个rdd的不同分区partition中。

yarn-client 与yarn-cluster的区别
主要区别:spark application的驱动程序Diver运行在不同地方。
yarn-client 的驱动程序Driver 运行在提交代码的本地机器上运行,驱动程序driver进程启动,会向Resource  Manager进行注册申请资源,Resource  Manager会向集群中node manager 的 work节点申请container 在container中有executor资源,申请到的executor会向本地的driver反向注册,告知driver要那些executor资源可以用,之后driver会监控这些executor资源,同时driver会通过DAGsheduler把spark application 拆分为一个有向五环图的任务,把job拆分为多个阶段state ,每一个阶段有为一个taskset  ,taskset 中有多个task ,taskset提交给driver中的TaskScheduler,由TaskScheduler负责把taskset 提交到 executor中,在executor中会把task包装为TaskRuner ,交给executor运行。driver会监控各个work上的executor的运行状态,运行完一批taskset ,driver接着会分配下一批takset给executor运行。当最后job的所有taskset运行完之后,executor会取消在driver中的注册,释放executor资源。
优点:yarn-client模式会在本地产生log,可以在本地中查看log,在本地测试的时候可以采用此种模式。
缺点:yarn-client模式driver在本地运行过程中,会与yarn集群中的节点不断的进行通信,而client端与集群可能不再一个集群网络中,这样会产生本机client的网络流量剧增。

yarn-cluster: 
yarn-cluster模式的driver程序提交到yarn 的cluster中某一个节点work上运行,然后向Resource  Manager申请资源,Resource  Manager会向集群中其他work节点申请container,在container中有executor资源。运行机制与yarn-client差不多,
重要区别是
yarn-cluster的驱动程序driver运行在yarn集群的每一个节点上,而yarn-client的驱动程序driver则运行在本地local机器上。

http://blog.csdn.net/yirenboy/article/details/47441465

数据倾斜发生时的现象

  • 绝大多数task执行得都非常快,但个别task执行极慢。比如,总共有1000个task,997个task都在1分钟之内执行完了,但是剩余两三个task却要一两个小时。这种情况很常见。

  • 原本能够正常执行的Spark作业,某天突然报出OOM(内存溢出)异常,观察异常栈,是我们写的业务代码造成的。这种情况比较少见。

数据倾斜的原理,
处理的数据中,其中某一个或者几个key的数据量特别大,其他的key的数据量比较小。在进行shuffle操作的时候,几个key数据量特别的拉取到某一个节点,这也有可能导致内存溢出情况。

数据倾斜的解决方案

解决方案一:使用Hive ETL预处理数据

解决方案二:过滤少数导致倾斜的key

解决方案三:提高shuffle操作的并行度

解决方案四:两阶段聚合(局部聚合+全局聚合)

解决方案五:将reduce join转为map join

解决方案六:采样倾斜key并分拆join操作

解决方案七:使用随机前缀和扩容RDD进行join

解决方案八:多种方案组合使用


SparkContext监控各个Exeutor的运行状态,当各个Exeutor执行完成之后,SparkContext则注销关闭。



参考链接:https://tech.meituan.com/spark-tuning-basic.html
参考链接:http://blog.csdn.net/yirenboy/article/details/47441465














yarn-client