这是我参与「第四届青训营 」笔记创作活动的的第6天,学习了【大数据 Shuffle 原理与实践】的内容,重点是shuffle算子、shuffle过程及优化,并且还了解到了零拷贝技术的原理及应用。
MapReduce
graph LR
A[Map:单机小数据聚类] --> B[Shuffle:数据移动,大数据聚类] --> C[Reduce:每个单机进行计算]
shuffle 算子
算子分类
- repartition:重新改变分区,数据分成一小块叫
- Bykey:聚合到一起
- join:把不在一起的数据按照某条件放在一起
- distinct
算子内部依赖
Partitioner构造
经典实现HashPartitioner
Aggregator构造
Map时就做Sum,最终发送本地处理好的结果,不全发给Reduce
shuffle过程
hash shuffle:写
partition映射到一个文件片段
sort shuffle:写
每个task成成一个包含所有partition数据的文件
读数据
shuffle handle 对应不同的 shuffle writer
partition多了需要unsafeshufflewriter
unsafeshufflewriter实现
堆外内存管理:用Long Array管理,只排序Long Array,数据不移动
reader实现
远程数据openBlocks,客户端接收的文件chunk请求存内存,stream请求存文件
shuffle writer最终的数据格式都一样data file + index file,因此只有一种reader
防止OOM
- 限制数据大小
- 请求数量
- 每个地址上获取block数量
External shuffle Service
解耦存储和计算,map写完即可退出,由service来接管
zero-copy
DMA:直接对存储器存取,不过DMA
定义:I/O优化,少在内存层面拷贝数据,用DMA来传输
典型场景:网络发送文件数据流
no zero-copy: 4次数据拷贝
sendfile: 3次数据拷贝
sendfile + DMA: 将data地址直接送给DMA,2次数据拷贝
实现
- mmap+write
mmap 直接把内核缓冲区的数据映射到用户空间,减少拷贝
mmap()
write()
- sendfile
netty zero copy
netty用FileRegion实现文件传输,避免内核缓冲区和用户态缓冲区之间的数据拷贝
shuffle 优化
broadcast替代join
RDD小 join RDD 大,用broadcast
mapside预聚合
预处理,不是直接把全部数据发给reduce
shuffle倾斜处理
- 提高并行度
缓解但不根治 - skew join
根据文件统计信息,差分大分区
push shuffle
解决问题:大量随机读
css
IO聚合:mapper同一partition数据远程写道同一个文件 备份:双磁盘副本