大数据shuffle原理与实践(3) | 青训营笔记

167 阅读3分钟

这是我参与「第四届青训营 」笔记创作活动的第8天

6.3 Shuffle过程

Shuffle实现的发展历程

Spark 0.8及以前Hash Based Shuffle

Spark 0.8.1为Hash Based Shuffle引入File Consolidation机制

Spark 0.9引入ExternalAppendOnlyMap

Spark 1.1引入Sort Based Shuffle,但默认仍为Hash Based Shuffle

Spark 1.2默认的Shuffle方式改为Sort Based Shuffle

Spark 1.4引入Tungsten-Sort Based Shufle

Spark 1.6 Tungsten-Sort Based Shuffle并入Sort Based Shufle

Spark 2.0 Hash Based Shuffle退出历史舞台

1.Hash Shuffle-写数据

每个partition会映射到一个独立的文件

image.png

Hash Shuffle-写数据优化

每个partition会映射到一个文件片段

image.png

2.Sort shuffle:写数据

每个task生成一个包含所有partition数据的文件

image.png

3.shuffle-读数据

每个reduce task分别获取所有map task生成的属于自己的片段

image.png

4.shuffle过程的触发过程

image.png

image.png

5.shuffle handle的创建

Register shuffle时做的最重要的事情是根据不同的条件创建不同的shuffle handle

image.png

6.shuffle handle 和shuffle writer的对应关系

image.png

7.writer 实现-BypassMergeShuffleWriter

image.png

1)不需要排序,节省时间

2)写操作的时候会打开大量文件

3)类似于hash shuffle

writer 实现-UnsafeShuffleWriter

image.png

1)使用类似内存页储存序列化数据

2)数据写入后不再反序列化

image.png

1)只根据partition排序Long Array

2)数据不移动

writer 实现-SortShuffleWriter

image.png

支持combine

需要combine时,使用PartitionedAppendOnlyMap, 本质是个HashTable

不需要combine时PartitionedPairBuffer本质是个array

8.Reader 实现-网络时序图

使用基于netty的网络通信框架

位置信息记录在MapOutputTracker中

主要会发送两种类型的请求:OpenBlocks请求、Chunk请求或Stream请求

image.png

Reader 实现-ShuffleBlockFetchlterator

image.png

区分local和remote节省网络消耗

防止OOM:maxBytesInFlight

maxReqsInFlight

maxBlocksInFlightPerAddress

maxReqSizeShuffle ToMem

maxAttemptsOnNettyOOM

Reader 实现-External Sheffle Service

ESS作为一个存在于每个节点 上的agent为所有Shuffle Reader提供服务,从而优化了Spark作业的资源利用率,MapTask在运行结束后可以正常退出

image.png

9.shuffle优化使用的技术-Zero Copy

不使用zero copy

image.png

使用sendfile

image.png

使用sendfile+DMA gather copy

image.png

shuffle优化使用的技术- Netty Zero Copy

可堆外内存,避免JVM堆内存到堆外内存的数据拷贝。

CompositeByteBuf、 Unpooled.wrappedBuffer. ByteBuf.slice,可以合并、包装、切分数组,避免发生内存拷贝

Netty使用FileRegion 实现文件传输,FileRegion 底层封装了FileChannel#transferTo0) 方法,可以将文件缓冲区的数据直接传输到目标Channel, 避免内核缓冲区和用户态缓冲区之间的数据拷贝

10.常见问题

数据存储在本地磁盘,没有备份

I0并发:大量RPC请求(M*R)

I0吞吐:随机读、写放大(3X)

GC频繁,影响NodeManager

11.shuffle 优化

避免shuffle

使用broadcast替代join

image.png

使用可以map-side预聚合的算子

image.png

image.png

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.targetPostShufflelnputSize

spark.reducer.maxSizelnFlight

spark.reducer.maxReqsInFlight

spark.reducer.maxBlocksInFlightPerAddress

13.shuffle倾斜优化

什么叫shuffle倾斜

倾斜影响:作业运行时间变长、Task OOM导致作业失败

image.png

常见的倾斜处理办法

提高并行度:优点:足够简单,缺点:只缓解,不根治

image.png

Spark AQE Skew Join

AQE根据shuffle文件统计数据动检测倾斜数据,将那些倾斜的分区打散成小的子分区,然后各自进行join.

image.png

14.案例-参数优化

ad_show

number of files read: 840,042

number of total tasks: 5,553

size of files read: 203.3 TiB

number of output rows: 128,676,054,598

image.png

15.参数调整

spark. sql. adaptive. shuffle.targetPostShuffleInputSize:64M->512 M

spark. sql.files. maxPartitionBytes: 1G ->40G

image.png