这是我参与「第四届青训营 」笔记创作活动的的第6天。
本节课程主要分为 4 个方面:
1.Shuffle概述
2.Shuffle算子
3.Shuffle过程
4.Push Shuffle
一.Shuffle概述
1.1.MapReduce概述
开源实现的MapReduce中,存在Map、Shuffle、Reduce三个阶段。
1.1.1.Map阶段
Map阶段,是在单机上进行的针对一小块数据的计算过程。
1.1.2.Shuffle阶段
Shuffle阶段,在map阶段的基础上,进行数据移动,为后续的reduce阶段做准备。
1.1.3.Reduce阶段
reduce阶段,对移动后的数据进行处理,仍然是在单机上处理一小份数据。
1.4.为什么shuffle对性能非常重要
1).M*R网络连接
2).大量的数据移动
3).数据丢失风险
4).可能存在大量的排序操作
5).大量的数据序列化、反序列化操作
6).数据压缩
二.Shuffle算子
2.1.Shuffle算子分类
■ repartition
✓ coalesce、repartition
■ ByKey
✓ groupByKey、reduceByKey、aggregateByKey、combineByKey、sortByKeysortBy
■ Join ✓ cogroup、join
2.1.1.Shuffle算子应用
val text = sc.textFile("mytextfile.txt")
val counts = text
.flatMap(line => line.split(" "))
.map(word => (word,1))
.reduceByKey(_+_)
counts.collect
2.2.Spark中对shuffle的抽象
1).窄依赖:父RDD的每个分片至多被子RDD中的一个分片所依赖。
2).宽依赖:父RDD的分片可能被子RDD中的多个分片所依赖。
2.2.1.算子内部的依赖关系
ShuffleDependency
✓ CoGroupedRDD
✓ ShuffledRDD
2.2.2.Shuffle Dependency
创建会产生shuffle的RDD时,RDD会创建Shuffle Dependency来描述Shuffle相关的信息
构造函数:
◌ A single key-value pair RDD, i.e.RDD[Product2[K, V]];
◌ Partitioner(available aspartitionerproperty);
◌ Serializer;
◌ Optional key ordering(of Scala’sscala.math.Orderingtype);
◌ OptionalAggregator;
◌ mapSideCombineflag which is disabled(i.e.false)by default。
2.2.3.Shuffle Dependency构造-Partitioner
✔ 用来将record映射到具体的partition的方法。
接口:◎ numberPartitions
◎ getPartition
2.2.4.Shuffle Dependency构造-Aggregator
✔ 在map侧合并部分record的函数。
接口:◎ createCombiner:只有一个value的时候初始化的方法
◎ mergeValue:合并一个value到Aggregator中
◎ mergeCombiners:合并两个Aggregator
三.Shuffle过程
3.1.Hash Shuffle
写数据:每个partition会映射到一个独立的文件。
写数据优化:每个partition会映射到一个文件片段。
优点:不需要排序
缺点:打开,创建的文件过多
3.2.Sort Shuffle
写数据:每个task生成一个包含所有partition数据的文件。
读数据:每个reduce task分别获取所有map task生成的属于自己的片段。
优点:打开的文件少、支持map-side combine
缺点:需要排序
TungstenSortShuffle:
优点:更快的排序效率,更高的内存利用效率
缺点:不支持map-side combine
3.5.Shuffle Handle的创建
Register Shuffle:
由action算子触发DAG Scheduler进行shuffle register。
Shuffle Register会根据不同的条件决定注册不同的ShuffleHandle。
3.6.Shuffle Handle 与 Shuffle Write的对应关系
3.7.Writer实现-BypassMergeShuffleWrite
◆ 不需要排序,节省时间
◆ 写操作的时候会打开大量文件
◆ 类似于Hash Shuffle
3.7.1.Writer实现-UnsafeShuffleWrite
◆ 使用类似内存页储存序列化数据
◆ 数据写入后不再反序列化
◆ 只partition排序Long Array
◆ 数据不移动
3.7.2.Writer实现-SortShuffleWrite
◆ 支持combine
◆ 需要combine时,使用PartitionedAppendOnlyMap,本质是上HashTable
◆ 不需要combine时PartitionedPairBuffer本质是上array
3.8.Reader实现-网络时序图
3.8.1.Reader实现-ShuffleBlockFetchIterator
○ 区分local和remote节省网络消耗
○ 防止OOM:
● maxBytesInFlight
● maxReqsInFlight
maxBlocksInFlightPerAddress
● maxReqSizeShuffleToMem
● maxAttemptsOnNettyOOM
3.8.2.Reader实现-External Shuffle Service
3.9.Shuffle优化使用的技术:Netty Zero Copy
1).可堆外内存,避免JVM堆内存到堆外内存的数据拷贝。
2).CompositeByteBuf、Unpooled.wrappedBuffer、ByteBuf.slice,可以合并、包装、切分数组,避免发生内存拷贝。
3).Netty使用FileRegion实现文件传输,FileRegion底层分装FileChannel#transferTo()方法,可以将文件缓冲区的数据直接传输到目标Channel,避免内核缓冲去和用户态缓冲区之间的数据拷贝。
3.10.常见问题
◎ 数据存储在本地磁盘,没有备份
◎ IO 并发:大量 RPC 请求(M*R)
◎ IO 吞吐:随机读、写放大(3X)
◎ GC 频繁,影响 NodeManager
3.11.Shuffle优化
1).避免shuffle
使用broadcast替代join
2).使用可以map-side预聚合的算子
3.12.Shuffle参数优化
○ 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
3.13.Shuffle倾斜优化
□ 倾斜影响
● 作业运行时间变长
● Task OOM导致作业失败
□ 常见的倾斜处理方法
● 增大并发度
优点:足够简单
缺点:只缓解、不根治
● AQE
四.Push Shuffle
4.1.为什么需要Push Shuffle
1).Avg IO size太小,造成了大量的随机IO,严重影响磁盘的吞吐。
2).M * R次读请求,造成大量的网络连接,影响稳定性。
4.3.Magnet实现原理
4.4.Magnet可靠性
✔ 如果Map task输出的Block没有成功Push到magnet上,并且反复重试仍然失败,则reduce task直接从ESS上拉取原始block数据。
✔ 如果magnet上的block因为重复或者冲突等原因,没有正常完成marge的过程,则reduce task直接拉取未完成merge的block。
✔ 如果reduce拉取已经merge好的block失败,则会直接拉取merge前的原始block。
✔ 本质上,magnet中维护了两份shuffle数据的副本。
4.6.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]
4.6.1.Cloud Shuffle Service流程
4.6.3.Cloud Shuffle Service AQE