SparkKafka01

Redis存储Offset(重点)

  1. 获取redis连接
  2. 从redis获取Offset(有或者无)
  3. 更新Offset到redis

在使用Redis连接的时候,注意一点,Connection连接无法被序列化,也就是说在Driver创建的连接,无法发送到Executor内部使用,需要在Executor内部创建单独的连接操作,才可以使用数据的累加或者计算操作,而且Driver负责维护Offset,此连接和Executor内部的连接不冲突,就算在Executor内部关闭连接,也不会影响Driver的连接,因为在Executor内部关闭的连接是Executor的Jedis连接,和Driver无关。(在Driver的代码只会执行一次)

Spark On Yarn

原理:

cluster模式

在这里插入图片描述

  1. 客户端(Spark集群的某台服务器)提交任务到集群(RM)
  2. RM接收任务后,将任务发送到对应的NM
  3. NM接收到任务,首先启动一个APP Master(Driver),再去创建对应的Container
  4. Container内部封装对应的Executor资源,Executor启动后,反向注册到Driver(APP Master)
  5. APP Master接收到Executor反向注册的信息,监控集群内的Task运行 状态
  6. APP Master将监控信息返回给RM,供给客户端显示(log)
  7. 任务运行完成,各个NM会释放对应的资源,注销当前的任务

其实用Spark On Yarn 的模式,说白了就是Yarn的原理,在这里面没有Master节点,也没有Worker节点,有的就是RM,NM,调度操作都是有RM来执行,任务运行都是NM来执行。任务的监控由内部创建的APP Master完成

client模式
在这里插入图片描述

  1. 由客户端(不是集群内的服务器)提交任务到集群(创建APP Master)
  2. RM接收任务,会将任务分配到应用的NM上面
  3. NM会启动对应的Container,内部封装Executor的资源
  4. Executor启动后,反向注册到单独提交任务的那台服务器上的Driver
  5. Driver实时监控当前集群的运行状态(Task运行状态)
  6. 任务执行完成,log任务会在Driver显示,同时RM会收集log到服务器

两者提交方式都可以正常运行任务,但是注意,Cluster模式提交任务后,Driver在内部创建,并且实时监控,也就是说,只要集群正常运行,Driver就正常工作,最后输出结果,但是Client的模式,如果提交任务的这台服务器挂了,那么任务失败

Spark源码分析(了解)

DAG Scheduler:有向无环图,根据宽窄依赖划分Stage,将所有Task提交至Task Scheduler上

  1. 首先DAG触发条件是Action(例如:foreach)点入runjob方法
  2. 进入DAG的runjob方法,内部开始提交当前任务,找到submitJob方法提交
  3. submitJob内部主要是将Job赋值Id,创建阻塞线程,让每个任务 按循序执行
  4. 通过Event事件队列,进行匹配,匹配当前提交任务的事件
  5. 找到当执行方(首先创建ResultStage)
  6. 通过getOrCreateShuffleMapStage,划分所有的shuffle依赖
  7. 倒推完成后,得到finalStage,然后将finalStage传入getMissingParentStages方法进行划分Stage
  8. 内部通过Visit方法,进行递归 调用,循环所有的依赖,如果遇到宽依赖就保存,如果是 窄依赖就push回去继续循环
  9. 当所有Stage划分完成后,将finalStage提交,通过submitStage方法提交
  10. 接下里划分通过 TasksubmitMissingTasks
  11. 内部通过Stage划分Task,Task的数量等于Partition数量,内部会划分两种Task
  12. 划分完成Task提交所有Tasks到TaskSet中
  13. 通过taskScheduler.submitTasks 提交至TaskSchedule上面,进行本地化的划分
  14. 这里调用的是 实现taskScheduler特质的TaskSchedulerImpl
  15. 找到submitTasks的重写方法,在TaskSchedulerImpl实现Task提交
  16. 每个Task在执行之前都会监控通过TaskSetManager
  17. 执行Task是FIFO的调度模式(先进先出)
  18. 开始分配所有Task到每个节点内部,通过resourceOffers方法
  19. 找到taskSet.executorAdded() 划分本地化级别
  20. 本地化级别通过枚举方式实现computeValidLocalityLevels()
  21. 五种本地化级别 PROCESS_LOCAL, NODE_LOCAL, NO_PREF, RACK_LOCAL, ANY 分别是,节点本地化,进程本地化,机架本地化,无本地化,没有
  22. TaskSetManager内部实现本地化级别划分(最优位置)
  23. Task会执行Run方法,然后每个Task会通过执行句柄发送到Executor内部执行
  24. Executor内部会将Task反序列化,根据核数运行Task

Task Scheduler:接收反向注册信息,发送Task(本地级别)

Shuffle(重点)

HashShuffle(了解)

未优化:首先通过ShuffleMapTask写入数据,然后每个ShuffleMapTask创建reduce个数的缓冲区,每个缓冲区都会溢写文件到本地磁盘,生成shuffleBlockFile本地文件,每个缓冲区都会创建一个shuffleBlockFile文件,然后在创建文件后,会创建对应的索引文件,将所有的本地文件元数据信息发送到Driver端,Driver会保存着元数据信息,然后reduce拉取本地文件的时候,会根据driver内的元数据信息拉取数据。

优化后:开启合并小文件机制(consolidation 机制),这样减少小文件输出,复用文件和缓存区,减少资源浪费

spark1.6以前这种shuffle还是不错的,减少磁盘IO,和文件的创建,性能还可以,但是2.0以后,因为底层内存模型发生改变,造成这种shuffle操作,不能完全的合理利用内存,所以被弃用,换成SortShuffle机制

SortShuffle 有两种机制(掌握)

普通机制:内部有两种数据结构,Map和Array,Map会做局部的聚合操作,提前进行分区内的合并,而Array直接写入内存,然后排序到每个缓冲区,当缓冲区满了以后,会溢写到磁盘文件,溢写后的小文件会被合并(这点跟MR比较像),然后合并的时候,都会记录当前的索引信息,当reduce拉取数据的时候,那么会根据索引信息找到位置去拉取merge文件内的数据

触发条件是大于200个Task

ByPass机制:其实前身就是HashShuffle机制,通过溢写文件,然后在去合并当前文件,而hash的是复用之前的本地文件,触发的条件是Task小于200个,溢写后的小文件会被合并(这点跟MR比较像),然后合并的时候,都会记录当前的索引信息,当reduce拉取数据的时候,那么会根据索引信息找到位置去拉取merge文件内的数据

在这里插入图片描述

钨丝Shuffle(TungstenShuffle了解)

其实内部实现的是SortShuffle普通机制,只不过对内存和缓存进行的合理利用,但是很多算子还是不支持钨丝shuffle这种shuffle操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值