大数据Shuffle原理与实践||青训营

126 阅读5分钟

大数据Shuffle原理与实践||青训营

今天是我参加青训营的第五天。

一、Shuffle概述

1.1MapReduce概述

2004年谷歌发布《Mapreduce:Simplified DATa PRocessingonlarge clusters》论文

在开源实现的MapReduce中,存在Map、Shuffle、Reduce三个阶段。

1.2Map阶段

map阶段,是在单机上进行的针对一小块数据的计算过程

1.2shuffle阶段

shuffle阶段,在map阶段的基础上,进行数据移动,将相同的放在一起,为后续的reduce阶段做准备,

image.png

1.3Reduce阶段

reduce阶段,对移动后的数据进行处理,依然是在单机上处理一小份数据

1.4为什么shuffle对性能非常重要

image.png

1.M*R次网络连接
2.大量的数据移动
3.数据丢失风险
4.可能存在大量的排序操作
5.大量的数据序列化、反序列化操作
6.数据压缩

01总结

image.png 在大数据场景下,数据shuffle表示不同分区数据交换的过程,不同的shuffle策略性能差异较大 目前在各个引擎中shuffle都是优化的重点,在spark框架中shuffle是支撑spark进行大规模复杂数据处理的基石。

2.Shuffle算子

2.1shuffle算子分类

image.png

repartition  BYkey            join                    distinct
一般改变分区  聚合同类型数据  本身没有相关的数据放在一起  特殊的bykey操作

2.2Sparl中对shuffle的抽象-宽依赖、窄依赖

image.png

窄依赖:父RDD的每个分片至多被子RDD的一个分片所依赖
宽依赖:父RDD中的分片可能被子RDD中的多个分片所依赖

2.2算子内部的依赖关系

shuffleDependency
    CoGroupedRdd
        Cogroup
            fullOuterjoin、rightOuterJoin、leftOUterjoin
            join
 ShuffedRDD
     combineBykeywithclass Tag
         combinebykey
         reduceBykey
     Coalesce
     SortBykey
         sortby

2.2.1 Shuffle Dependency构造

image.png 第二个负责给定一个key产生一个key的分区 第三个负责把一个对象映射成二进制流或相反 第四个负责排序的flag

2.2.1SHuffle dependency构造-partitioner

image.png 两个接口 numberPartitions getPartitioner 经典实现 HashPartitioner

2.2.1SHuffle dependency构造-Aggregator

createCombiner:只有一个value的时候初始化的方法
mergevalue:合并一个value到Aggregator中
mergeCombiners:合并两个Aggregator,把两个加起来输入真正的merge

3.Shuffle实现的发展历程

image.png

3.1Hash Shuffle-写数据

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

image.png

3.1Hash Shuffle-写数据优化

每个partition会映射到一个文件片段,这样的话还是会m改成c文件还是不会下降多少,而且文件的打开数还没有减少多少=。 image.png

3.2Sort shuffle:写数据

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

image.png

3.3Shuffle-读数据

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

image.png

3.4Shuffle过程的触发流程

image.png image.png 在第六行这个collect是一个action 在前五行只是一个计算对象,只有后面才会触发过程

3.5shuffle handle的创建

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

image.png

3.6Shuffle handle 与shuffle writer的对应关系

image.png

3.7Writer实现-BypassMergeShuffleWriter

image.png

不需要排序,节省时间
写操作的时候会打开大量文件
类似于Hash Shuffle
节省CPU,虽然不一样的地方,多了一个操作,最终还是会整合到一起

3.7Writer实现-UnsafeShuffleWriter

image.png

没有java内存的开销也没有垃圾回收的开销
使用类似内存存储存序列化数据
数据写入不再反序列化

3.7Writer实现-UnsafeShuffleWriter

image.png

只根据partition排序long Array
数据不移动  
long array不能超过24的次方

3.7Writer实现-SortShuffleWriter

image.png

支持combine
需要combine时,使用PartiotionedAppendOnlyMap,本质三个HashTable
不需要combine时PartitionePairBuffer本质是个array

3.8Reader实现-网络时序图

image.png

使用基于netty的网络通信框架
位置信息记录在MapOutputTracker中
主要会发送两张类型的请求
    OPenBlocks请求
    chunk请求或Stream请求
 
 对于没有聚合操作只会生成一个简单的迭代器。

3.7Reader实现-ShuffleBlockFetchIterator

image.png

3.8Read实现-External shuffle Service

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

image.png 3.9Shuffle优化使用的技术-Zero Copy

image.png

image.png

3.10常见问题


数据存储在本地磁盘,没有备份
IO并发:大量RPC请求(M*R)
IO吞吐:随机读,写放大(3x)
GC频繁,影响NodeManager

3.11Shuffle优化

避免shuffle 使用broadcast替代join 使用可以map-side预聚合的算子,可以减少数据量

image.png

3.12Shuffle参数优化

image.png

第一个是默认的并发度 可以帮我们优化shuffle的表现,过高随机读,过低一个task处理的数据量过大,作业速度慢
第二第三类似,减少不必要的Rdd
第二如果文件是空的可以减少速度
第三我们在读取数据时可以做一些合并
第四是也是读数据task处理的数据量生成一个合适的大小

3.13Shuffle 倾斜优化

什么叫shuffle倾斜
倾斜影响
    作业运行时间变长
    task OOM导致作业失败

3.13常见的倾斜处理办法

image.png

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

3.13Spark AQE Skew join

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

3.14案例-参数优化

image.png

3.15参数调整

image.png 减少了随机读的问题,减少了shuffle读取磁盘的数据,导致CPU浪费 四、Push Shuffle

4.1为什么需要Push Shuffle?

image.png

Avg iosize太小,造成了大量的随机IO,严重影响磁盘的吞吐
M*R次读请求,造成大量的网络连接,影响稳定性

4.2Push shuffle的实现

image.png

4.3Magnet实现原理

image.png

image.png

4.4Magnet可靠性

image.png

4.5Cloud Shuffle Service 思想

image.png

io聚合,如果文件丢失的代价是特别大的
写入速度:用极小的失败概率换取极大的速度是非常值得的

4.6Cloud Shuffle Service 架构

image.png

4.6.1Cloud shuffle Service 写入流程

image.png

4.6.2Clound shuffle service读取流程

image.png

4.6.3 2Clound shuffle service AQE

image.png

一个Partition会最终对应到多个Epoch file,每个Epoch目前设置512MB,一个大的文件划分为小文件,不需要大的文件读取很多遍