这是我参与「第四届青训营」笔记创作活动的第7天。
shuffle概述
Map reduce 概述
Map reduce中存在map,shuffle,reduce三个阶段
Map: 单机上对小块数据的计算。
Shuffle: 在map后,对各分区的数据进行移动,为后续reduce做准备。
Reduce: 对移动后的数据处理,依旧是单机。
数据shuffle表示了不同分区数据交换的过程,不同的shuffle策略性能差异较大。目前在各个引擎中shuffle都是优化的重点,在spark框架中,shuffle是支撑spark进行大规模复杂数据处理的基石。以下是shuffle的一些·特点。
- M*R次网络连接
- 大量的数据移动
- 数据丢失风险
- 可能存在大量的排序操作
- 大量的数据序列化、反序列化操作
- 数据压缩
shuffle 算子
常见的触发shuffle的算子
- repartition - coalesce、repartition
- ByKey - groupByKey、reduceByKey、aggregateByKey…
- Join - cogroup、join…
- distinct
宽依赖和窄依赖
窄依赖: 父RDD的每个分片至多被子RDD中的一个分片所依赖
宽依赖: 父RDD中的分片可能被子RDD中的多个分片所依赖
Shuffle Dependency
创建会产生shuffle的RDD时,RDD会创建Shuffle Dependency来描述Shuffle相关的信息
构造函数
Partitioner: 用来将record映射到具体的partition的方法
接口:numberPartitions;getPartition
Aggregator: 在map侧合并部分record的函数
接口:
- createCombiner:只有一个value的时候初始化的方法
- mergeValue:合并一个value到Aggregator中
- mergeCombiners:合并两个Aggregator
shuffle 过程
spark中的shuffle变迁过程
HashShuffle
优点:不需要排序
缺点:打开,创建的文件过多
SortShuffle
优点:打开的文件少、支持map-side combine
缺点:需要排序
TungstenSortShuffle
优点:更快的排序效率,更高的内存利用效率
缺点:不支持map-side combine
Register Shuffle
由action算子触发DAG Scheduler进行shuffle register。Shuffle Register会根据不同的条件决定注册不同的ShuffleHandle
三种ShuffleHandle对应了三种不同的ShuffleWriter的实现
BypassMergeSortShuffleWriter:HashShuffle
UnsafeShuffleWriter:TunstonShuffle
SortSHuffleWriter:SortShuffle
ShuffleReader网络请求流程
使用netty作为网络框架提供网络服务,并接受reducetask的fetch请求。首先发起openBlocks请求获得streamId,然后再处理stream或者chunk请求
Push shuffle
shuffle过程存在以下问题
- 数据存储在本地磁盘,没有备份
- IO 并发:大量 RPC 请求(M*R)
- IO 吞吐:随机读、写放大(3X)
- GC 频繁,影响 NodeManager
Magnet主要流程
边写边push的模式,在原有的shuffle基础上尝试push聚合数据,但并不强制完成,读取时优先读取push聚合的结果,对于没有来得及完成聚合或者聚合失败的情况,则fallback到原模式。
Cloud Shuffle Service架构
总结
具有某种共同特征的一类数据需要最终汇聚到一个计算节点上进行计算。这种数据打乱然后汇聚到不同节点的过程就是Shuffle。本节课对spark中的shuffle算子进行了介绍,深入了解了shuffle运行的底层原理。