这是我参与【第四节青训营】笔记创作活动的第1天。
大数据Shuffle原理
一、Shuffle概述
MapReduce中,存在Map,Shuffle,Reduce三个阶段。
1.1 Map阶段
是在单机上对一小块数据计算的过程
1.2 Shuffle阶段
在map阶段基础上,进行数据移动,为后续的reduce阶段做准备
1.3Reduce阶段
对移动后的数据进行处理,依然是在单机上处理一小份数据
1.4为什么shuffle对性能非常重要
- M*R次网络连接
- 大量的数据移动 *
- 数据丢失风险
- 可能存在大量的排序操作
- 大量的数据序列化、反序列化操作
- 数据压缩
二、Shuffle算子
2.1 4类算子
repartition
coalesce、repartition
ByKey
groupByKey、reduceByKey、aggregateByKey、combineByKey、sortByKey、sortBy
groupByKey
cogroup、join、leftOuterJoin、intersection、subtract、subtractByKey
join
cogroup,join,leftOuterJoin,intersection
Distinct
distinct
2.2 宽依赖、窄依赖
窄依赖
父RDD的每个分片被多个子RDD的一个分片所依赖
宽依赖
父RDD中的每个分片可能被子RDD中的多个分片所依赖
2.3 Shuffle Dependency构造
创建shuffle的RDD时,会创建Shuffle Dependence来描述Shuffle相关的信息
三、Shuffle过程
3.1 Hash Shuffle-写过程
每个partition会映射到一个独立文件
- 优点:不需要排序
- 缺点:打开,创建的文件过多
写数据优化
每个partition会映射到一个文件片段
3.2 Sort shuffle:写数据
每个task生成一个包含所有partition数据文件
- 优点:打开的文件少、支持map-side combine
- 缺点:需要排序
TungstenSortShuffle
- 优点:更快的排序效率,更高的内存利用效率
- 缺点:不支持map-side combine
3.3 Shuffle 读数据
每个reduce task分别获取所有map tasK生产的属于自己的片段
3.4 Shuffle 过程的触发流程
Collect Action=>SubmitJob=>GetDependencies=>RegisterShuffle
3.5 Shuffle Handle的创建
Register Shuffle时做的最重要的事情是根据不同的条件创建不同的shuffle Handle
- SerializedShuffleHandle:支持mapside combine或partitions小于spark.shuffle.sort.bypassMergeThreshold,支持mapside combine、serializer、relocation或partitions
- SerializedShuffleHandle:SerializedShuffleHandle:支持mapside combine或partitions小于spark.shuffle.sort.bypassMergeThreshold,不支持mapside combine、serializer、relocation及partitions
- BypassMergeSortShuffleHandle:不支持mapside combine且partitions小于spark.shuffle.sort.bypassMergeThreshold,不支持mapside combine、serializer、relocation及partitions
- 三种不同的ShuffleHandle对用三种不同的ShuffleWriter实现
BypassMergerSortShuffleHandle --> BypassMergeSortShuffleWrite
SerializedShuffleHandle --> UnsafeShuffleWriter
BaseShuffleHandle --> SortShuffleWriter
3.6 Writer实现
- BypassMergeShuffleWriter
优点:不需要排序
缺点:写操作时会打开大量文件 - unsafeShuffleWriter
优点:数据写入后不再反序列化 - SortShuffleWriter
支持combine 需要combine时,使用PartitionedAppendOnlyMap,本质是个HashTable 不需要combine时PartitionedPairBuffer本质是个array
3.7 Reader实现-网络时序图
基于netty的网络通信框架
位置信息记录在MapOutputTracker中
会发送两个类型的请求: openBlock请求 chunk请求或Stream请求
- Reader实现-shuffleBlockFetchInetrator
区分Local和remote
- Read实现-External Shuffle Service
ESS作为一个存在每个节点上的agent为所有Shuffle Reader提供,从而优化了Spark作业的资源利用率,MapTask在运行结束后正常退出
3.9 Shuffle优化使用技术-Zero Copy
DMA: 直接存储器存取,是指外部设备不通过CPU而之间与系统内存交换数据的接口技术
3.10 Shuffle优化使用的技术:Netty
3.11 Shuffle优化
避免shuffle
使用broadcast替代join
3.12 Shuffle参数优化
spark.default.parallelism && spark.sql.shuffle.partitions ...
3.13 Shuffle倾斜优化
什么叫Shuffle倾斜?
一个map task需要处理很多数据,而其他的map task数据少
倾斜影响
作业时间变长
Task OOM导致作业失败
常见的倾斜处理方法
提高并行度 (参数调整调吞吐量)
优点:足够简单
缺点:只缓解、不根治
Spark AQE Skew Join
AQE根据shuffle文件统计数据自动检测倾斜数据,将那些倾斜的分区打散成效的子分区,然后各自进行join。