这是我参与「第四届青训营 」笔记创作活动的第6天
大数据Shuffle原理与实践
一、Shuffle概述
1.1 MapReduce概述
在开源实现的MapReduce中,存在Map,Shuffle,Reduce三个阶段
1.2 Shuffle阶段
reduce阶段,堆移动后的数据进行处理,依然是在单机上处理一小份数据。
1.3 Reduce阶段
reduce阶段,对移动后的数据进行处理,依然是在单机上处理一小份数据。
1.4 为什么shuffle对性能非常重要
- M * R次网络连接
- 大量的数据移动
- 数据丢失风险
- 可能存在大量的排序操作
- 大量的数据序列化、反序列化操作
- 数据压缩
总结
在大数据场景下,数据shuffle表示了不同分区数据交换的过程,不同的shuffle策略性能差异较大
目前在各个引擎中Shuufle都是优化的重点,在spark框架中,shuffle是支撑spark进行大规模复杂数据处理的基石。
二、Shuffle算子
2.1 Shuffle算子分类
Shuffle算子应用
- Spark源码中RDD的单元测试
- Spark源码中PairRDDFunctions的单元测试
2.2 Spark中对Shuffle的抽象 宽依赖、窄依赖
算子内部的依赖关系
三、Shuffle过程
3.1 Shuffle实现的发展历程
3.2 Hash Shuffle -写数据
每个partition会映射到一个独立的文件
Hash Shuffle -写数据优化
每个partition会映射到一个文件片段
Short Shuffle: 写数据 每个task生成一个包含所有partition数据的文件
3.3 Shuffle -读数据
每个reduce task分别获取所有map task生成的属于自己的片段
3.4 Shuffle过程的触发流程
Collect Action -> SubmitJob -> GetDependecies -> RegisterShuffle
3.5 Shuffle Handle 的创建
Register Shuffle时做的最重要的事情时根据不同条件创建不同的Shuffle Handle
3.6 Shuffle Handle 与 Shuffle Writer的对应关系
3.7 Writer实现
BypassMergeShuffleWriter
- 不需要排序,节省时间
- 写操作的时候会打开大量文件
- 类似于Hash Shuffle
UnsafeShuffleWriter
- 使用类似于内存页储存序列化数据
- 数据写入后不再反序列化
- 只根据partition排序Long Array
- 数据不移动
ShortShuffleWriter
- 支持combine
- 需要combine时,使用PartitionedAppendOnlyMap,本质是一个HashTable
- 不需要combine时PartitionedPariBuffer本质时一个array
3.8 Reader实现
网络时序图
- 使用基于netty的网络通信框架
- 位置信息记录在MapOutputTracker中
- 主要会发送两种类型的请求 OpenBlocks请求 Chunk请求或Stream请求
ShuffleBlockFetchIterator
- 区分local和remote节省网络消耗
- 防止OOM
External Shuffle Service ESS作为一个存在于每个节点上的agent为所有Shuffle Reader提供服务,从而优化了Spark作业的资源利用率,MapTask在运行结束后可以正常退出
3.9 Shuffle优化使用的技术
Zero Copy
DMA(Direct Memory Access):直接存储器存取,是指外部设备不通过CPU而直接与系统内存交换数据的接口技术
Netty Zero Copy
- 可堆外内存,避免JVM堆内存到堆外内存的数据拷贝
- CompositeByteBuf、Unpooled.wrappedBuffer、ByteBuf.slice,可以合并、包装、切分数组、避免发生内存拷贝
- Netty使用FileRegion实现文件传输,FileRegion底层封装了FileChannedl#TransferTo()方法,可以将文件缓冲区的数据直接传输到目标Channel,避免内核缓冲区和用户态缓冲区之间的数据拷贝。
3.10 常见问题
- 数据存储在本地磁盘无备份
- IO并发:大量RPC请求
- IO吞吐:随机读,写放大
- GC频繁,影响NodeManager
3.11 Shuffle优化
使用broadcast替代join
使用可以map-side预聚合的算子
3.12 Shuffle参数优化
3.13 Shuffle倾斜优化
倾斜影响
- 作业运行时间长
- Task OOM导致作业失败