这是我参与「第四届青训营」笔记创作活动的的第6天
map阶段
在单机上进行的针对一小块数据的计算过程(把不同颜色拆开分类)
shuffle阶段
在map阶段的基础上进行数据移动,为后续的reduce阶段做准备
reduce阶段
对移动后的数据进行处理,依然是在单机上处理一小部分数据
shuffle对性能的重要性
M * R次网络连接与数据移动,会有数据丢失风险,可能存在大量排序操作,大量的数据序列化与反序列化操作,数据压缩
在大数据场景下,数据shuffle表示不同分区数据交换的过程,不同的shuffle策略性能差异大。 目前各个引擎中shuffle都是优化重点。shuffle是支撑spark进行大规模复杂数据处理的基石。
shuffle 算子
shuffle算子分类
- repartition重分区:coalesce/repatition
- bykey:有groupByKey / reduceByKey/ aggregateByKey/ sortByKey
- join:有cogroup/ join/ leftOuterJoin等
- distinct
Shuffle Dependency
-
创建会产生shuffle的RDD时,RDD会创建Shuffle Dependency来描述Shuffle相关的信息
-
Partitioner
用来将record映射到具体的partition的方法 两个接口:numberPartitions、getPartition
- Aggregator
在map侧合并部分record的函数
接口有: createCombiner:只有一个value的时候初始化的方法 mergeValue:合并一个value到Aggregator中 mergeCombiners:合并两个Aggregator
shuffle过程
Hash Shuffle:写数据
每个partition会映射到一个独立的文件
- 优点:不需要排序;缺点:打开,创建的文件过多
Sort Shuffle:写数据
每个task生成一个包含所有partition数据的文件
- 优点:打开的文件少、支持map-side combine;缺点:需要排序
shuffle过程的触发流程
Collect Action -> Submit Job -> GetDependcies -> Register Shuffle
shuffle Handle与Shuffle Writer的对应关系
shuffle优化
- 避免shuffle ——使用broadcast替代join
- 使用可以map-side预聚合的算子
- 参数优化
- spark.default.parallelism && spark.sql.shuffle.partitions
- spark.hadoopRDD.ignoreEmptySplits
- spark.hadoop.mapreduce.input.fileinputformat.split.minsize
- spark.sql.file.maxPartitionBytes
- spark.sql.adaptive.enabled && spark.sql.adaptive.shuffle.targetPostShuffleInputSize
- spark.reducer.maxSizeInFlight
- spark.reducer.maxReqsInFlight
- spark.reducer.maxBlocksInFlightPerAddress
- 倾斜优化
- 倾斜的影响:作业运行时间变长;Task OOM导致作业失败
- 解决办法:提高并行度。足够简单但只起到缓解作用。
案例优化
- 整体数据量 200+TB,文件84万+
- 主要工作:groupby,两个sum
- 优化操作:增大Map Task的数据处理量,由于该算子有Map-Side Aggregation,减少了整体的shuffle数据量;参数调整,增大了Chunk Size,减小shuffle过程中的IOPS,避免了长时间的Blocked Time
push shuffle
为解决shuffle过程的问题
- Avg IO size太小,造成大量的随机IO,严重影响磁盘的吞吐
- M * R次的读请求造成大量的网络连接,影响稳定性
- 数据储存在本地磁盘,没有备份
- GC 频繁,影响 NodeManager
push shuffle的实现
- Facebook:cosco
- LinkedIn:magnet
- Uber:Zeus
- Alibaba: RSS
- Tencent: FireStorm
- Bytedance:Cloud Shuffle Service
- Spark3.2: push based shuffle
Magnet主要流程
- 主要为边写边push的模式,在原有的shuffle基础上尝试push聚合数据,但并不强制完成,读取时优先读取push聚合的结果,对于没有来得及完成聚合或者聚合失败的情况,则fallback到原模式
- Spark driver组件协调整体的shuffle操作
- map任务的shuffle writer完成后,增加一个额外的操作push-merge,将数据复制一份到远程shuffle服务上
- magnet shuffle service是强化版ESS。将属于同一个shuffle partition的block,会在远程传输到magnet后,被merge到一个文件中
- reduce任务从magnet shuffle service接收合并好的shuffle数据
Cloud Shuffle Service
架构:
-
Zookeeper WorkerList [服务发现]
-
CSS Worker [Partitions / Disk | Hdfs]
-
Spark Driver [集成启动 CSS Master]
-
CSS Master [Shuffle 规划 / 统计]
-
CSS ShuffleClient [Write / Read]
-
Spark Executor [Mapper + Reducer]