这是我参与「第四届青训营 」笔记创作活动的第15天
一.Shuffle概述
1.MapReduce概述
在Map、Shuffle、Reduce三个阶段
2.Map阶段
在单机上进行的针对一小块数据的计算过程
3.Shuffle
在map阶段的基础上,进行数据移动
4.Reduce
对移动后的数据进行处理,依然是在单机上处理一小份数据
5.Shuffle重要性
- M*R网络连接
- 大量的数据移动
- 数据丢失风险
- 可能存在大量的排序操作
- 大量的数据序列化、反序列化操作
- 数据压缩
二.Shuffle算子
1.Shuffle算子分类
- Repartition(改变数据分区)
- ByKey(给数据一个key,把hey相同的组合在一起)
- join把数据放在一起
- Distinct
2.Spark中对shuffle的抽象
- 窄依赖:父RDD的每个分片至多被子RDD中的一个分片所依赖
- 宽依赖:父RDD中的分片可能被子RDD中的多个分片所依赖
3.Shuffle Dependency构造-Partitioner
- 两个接口:numberPartitions、getPartition
- 经典实现:HashPartitioner
4.Shuffle Dependency构造-Aggregator
- createCombiner:只有一个value的时候初始化的方法
- mergeValue:合并一个value到Aggregator中
- mergeCombiners:合并两个Aggregator
三.Shuffle过程
1.Hash Shuffle:
生成的和打开的文件太多,资源消耗多 优化:每个partition会映射一个文件片段
2.Sort shuffle(写数据)
每个task生成一个包含所有partition数据的文件
3.Shuffle(读数据)
每个reduce task分别获取所有map task生成的属于自己的片段
4.Shuffle过程的触发流程
Collect Action->SubmitJob->GetDependencies->RegisterShuffle
5.Shuffle Handle的创建
Register Shuffle时做的最重要的事情是根据不同条件创建不同的shuffle Handle
6.Shuffle Handle与Shuffle Writer的对应关系
7.Write实现-BypassMergeShuffleWriter
- 不需要排序,节省时间
- 写操作的时候会打开大量文件
- 类似于Hash Shuffle
8.Write实现-UnsafeShuffleWriter
- 使用类似内存页存储序列化数据
- 数据写入后不再反序列化
9.Writer实现-UnsafeShuffleWriter
- 只根据partition排序Long Array
- 数据不移动
10.Writer实现-SortShuffleWriter
- 支持combine
- 需要combine时,使用PartitionedAppendOnlyMap,本质是个HashTable
- 不需要combine时PartitionedPairBuffer本质是个array
11.Reader实现-网络时序图
- 使用基于netty的网络通信架构
- 位置信息记录在MapOutputTracker中
- 主要会发送两种类型的请求:OpenBlocks、Chunk、Stream
12.Reader实现-ShuffleBlockFetchLterator
- 区分local和remote节省网络消耗
- 防止OOM
13.Read实现-External Shuffle Service
ESS作为一个存在于每个节点上的agent为所有shuffle Reader提供服务,从而优化了Spark作业的资源利用率,MapTask在运行结束后可以正常退出
14.Zero Copy
- 不使用zero copy
- 使用sendfile
- 使用sendfile+DMA gather copy
15.Netty Zero Copy
- 可堆外内存,避免JVM堆外内存的数据拷贝
- CompositeByteBuf、Unpooled.wrappedBuffer、ByteBuf.slice,可以合并、包装、切分数组,避免发送内存拷贝
- Netty使用FileRegion实现文件传输,FileRegion底层封装了FileChannel#transferTo()方法,可以将文件缓冲区的数据直接传输到目标Channel,避免内核缓冲区和用户态缓冲区之间的数据拷贝
16.Shuffle优化
- 避免shuffle
- 使用broadcast替代join
- 使用可以map-side预聚合的算子
17.shuffle倾斜优化
影响:
- 作业运行时间变长
- Task OOM导致作业失败
处理方法:
- 提高并行度(简单,但不根治)
18.Spark AQE Skew Join
AQE根据shuffle文件统计数据自动检测倾斜数据,将那些倾斜的分区打散成小的子分区,然后各自进行join。