大数据Shuffle原理与实践|青训营笔记
这是我参与「第四届青训营 」笔记创作活动的的第4天
1.shuffle概述
在大数据场景下,数据shuffle表示了不同分区数据交换的过程,不同的shuffle策略性能差异较大。目前在各个引擎中shuffle都是优化的重点,在spark框架中,shuffle是支撑spark进行大规模复杂数据处理的基石。
2.spark 中 shuffle 过程
2.1 发展
- Hash Shuffle:每个partition会映射到一个独立文件
- 优化:每个partiton会映射到一个文件片段
- Sort shuffle:每个task生成一个包含所有partition数据的文件
- shuffle读数据:每个reduce task分别获取所有maptask生成的属于自己的片段。
shuffle 过程的触发流程:collect Action-->SubmitJob-->GetDependencies-->RegisterShuffle
Shuffle Handle的创建:Register Shuffle时做的最重要的事情是根据不同条件创建不同的shuffle Handle
2.2 shuffle Handle与Shuffle Writer的对应关系
- BypassMergeShuffleWriter-->BypassMergeShuffleWriter
- SerializedShuffleWriter-->UnsafeShuffleWriter
- BaseShuffleWriter-->SortShuffleWriter
2.2.1 Write实现-BypassMergeShuffleWriter
- 不需要排序,节省时间
- 写操作的时候会打开大量文件
- 类似于Hash Shuffle
2.2.2 Write实现UnsafeShuffleWriter
- 使用类似内存页存储序列化数据、
- 数据写入后不再反序列化
- 只根据partition排序Long Array
- 数据不移动
2.2.3 Write实现SortShuffleWriter
- 支持combine
- 需要combine时,使用PartitionedAppendOnlyMap,本质是一个HashTable
- 不需要combile是partitionedPairBuffer本质是一个Array
2.2.4 Reader实现-ShuffleBlockFetchIterator
- 区分local和remote节省网络消耗
- 放在OOM
2.2.5 Read 实现- External Shuffle Service
ESS作为一个存在每个节点上的agent为所有shuffle Reader 提供服务,从而优化了Spark作业的资源利用率,MapTask在运行结束后可以正常退出。
2.2.6 写读都会用到的Shuffle优化使用的技术-Zero Copy
DMA:直接存储器存取,是指外部设备不通过CPU而直接与系统内存交换数据的接口技术。
- 可堆外内存,避免JVM堆内存到堆外内存的数据拷贝。
- CompositeByteBuf、Unpooled.wrappedBuffer、ByteBuf.slice,可以合并、包装、切分数组,避免发生内存拷贝
- Netty使用FileRegion实现文件传输,FileRegion底层封装了FileChannel#transferT()方法,可以将文件缓冲区的数据直接传输到目标Channel,避免内核缓冲区和用户态缓冲区之间的数据拷贝。
2.3 常见问题
- 数据存储在本地磁盘,没有备份
- IO并发:大量RPC请求(M*R)
- IO吞吐:随机读,写放大(3X)
- GC频繁:影响NodeManager
2.4 Spark Shuffle优化
- 避免shuffle:使用broadcast替代join
- 使用可以map-side预聚合的算子
- shuffle参数优化:修改默认并发度、忽略空的partition、修改每个task处理的文件、优化SQL、优化reducer处理数据量
2.5 Shuffle倾斜优化
- 倾斜影响:端到端作业运行时间变长、Task OOM作业失败
- 处理办法:提高并行度(优点:足够简单;缺点:只缓解、不根治)、Spark AQE Skew Join
2.5.1 参数调整:
spark.sql.adaptive.shuffle.targetPostShuffleInputSize;Spark.sql.files.maxPartitionBytes
2.6 Push Shuffle
- Avg IO size大小,造成了大量的随机IO,严重影响磁盘的吞吐
- M※R次读请求,造成大量的网络连接,影响稳定性
2.6.1 Magnet实现原理
- spark driver组件,协调整体的shuffle操作
- map任务的shuffle writer过程完成后,增加了一个额外的操作push-merge,将数据复制一份推到远程shuffle服务上
- magnet shuffle service是一个强化版的ESS,将隶属于同一个shuffle partition的block,会在远程传输到magnet后被merge到一个文件中
- reduce任务从magnet shuffle service接收合并好的shuffle数据
- bitmap:存储已merge的mapper id防止重复merge
- poition offset:如果本次block没有正常merge,可以恢复到上一个block的位置
- currentMapID:标注当前正在append的block,保证不同mapper的block能依次append