这是我参与「第四届青训营 」笔记创作活动的的第7天
-
Shuffle概述
-
Map阶段:是在单机上进行的针对一小块数据的计算过程
-
Shuffle阶段:在Map阶段的基础上,进行数据移动,为后续的reduce阶段做准备
-
Reduce阶段:对移动后的数据进行处理,依然是在单机上处理一小份数据
-
为什么shuffle对性能非常重要
-
M*R次网络连接
-
大量的数据移动
-
数据丢失风险
-
可能存在大量的排序操作
-
大量的数据序列化,反序列化操作
-
数据压缩
-
在大数据场景下,数据shuffle标识了不同分区数据交换的过程,不同的shuffle策略性能差异较大。目前在各个引擎中shuffle都是优化的重点,在spark框架中,shuffle是支撑spark进行大规模复杂数据处理的基石。
-
-
shuffle算子
-
分类
spark中会产生shuffle的算子大概可以分为4类
repartition bykey join distinct coalesce groupByKey cogroup distinct repartition reduceByKey join aggregateByKey leftOuterJoin combineByKey intersection sortByKey subtract sortBy sutractByKey -
Spark中对shuffle的抽象--宽依赖、窄依赖
- 窄依赖:父RDD的每个分片至多被RDD中的一个分片所依赖
- 宽依赖:父RDD中的分片可能被子RDD中的多个分片所依赖
-
算子内部的依赖关系
- CoGroupedRDD
- Cogroup
- fullOuterJoin、rightOuterJoin、leftOuterJoin
- join
- ShuffledRDD
- combineByKeyWithClassTag
- combineByKey
- reduceByKey
- Coalesce
- sortByKey
- sortBy
- combineByKeyWithClassTag
- Cogroup
- CoGroupedRDD
-
-
Shuffle过程
-
Hash Shuffle-写数据:每个partition会映射到一个独立的文件
写数据优化:每个partition会映射到一个文件片段
Sort shuffle-写数据:每个task生成一个包含所有partition数据的文件
Shuffle-读数据:每个reduce task分别获取所有map task生成的属于自己的片段
-
Writer实现
- BypassMergeShuffleWriter
- 不需要排序,节省时间
- 写操作的时候会打开文件
- 类似于Hash Shuffle
- UnsafeShuffleWriter
- 使用类似内存页储存序列化数据
- 数据写入后不再反序列化
- 只根据partition排序Long Array
- 数据不移动
- SortShuffleWriter
- 支持combine
- 需要combine时,使用PartitionedAppendOnlyMap,本质是个HashTable
- 不需要combine时PartitionedPairBuffer本质是个array
- BypassMergeShuffleWriter
-
Reader实现
- ShuffleBlockFetchlterator
- 区分local和remote节省网络消耗
- 防止OOM
- External Shuffle Service
- ESS作为一个存在于每个节点上的agent为所有Shuffle Reader提供服务,从而优化了Spark作业的资源利用率,MapTask在运行结束后可以正常退出
- ShuffleBlockFetchlterator
-
-
Push Shuffle
- Magent实现原理
- Spark driver组件,协调整体的shuffle操作
- map任务的shuffle writeri过程完成后,增加了一个额外的操作push-merge,将数据复制一份推到远程shuffle服务上
- magnet shuffle service,是一个强化版的ESS。将隶属于同一个shuffle partition的block,会在远程传输到magnet后被merge到一个文件中
- reduce任务从magnet shuffle service接收合并好的shuffle数据
- bitmap:存储已merge的mapper id,防止重复merge position offset:如果本次blocki没有正常merge,可以恢复到上一个block的位置 current Mapld:标识当前正在append的block,保证不同mapper的block能依次append
- Magent可靠性
- 如果Map task输出的Block没有成功Push到nagnet上,并且反复重试仍然失败,则reduce task直接从ESS上拉取原始block数据
- 如果magnet上的block因为重复或者冲突等原因,没有正常完成merge的过程,则reduce task直接拉取未完成mergel的block
- 如果reduce:拉取已经merge好的block失败,则会直接拉取merge前的原始block
- 本质上,magnet中维护了两份shuffle数据的副本
- Magent实现原理