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

262 阅读8分钟

这是我参与[第四届青训营]笔记创作的第6天。

一、Shuffle概述

1、MapReduce概述

mapReduce分片在重组,MR程序就是封装了JOB对象,一起传递给Yarn。 在开源实现的MapReduce中,存在Map、Shuffle、Reduce三个阶段。

屏幕截图 2022-08-01 211014.jpg

  • Map键值对的集合接口 :读取HDFS文件,每一行变成一<k,v>,每个键值对调用一次map。在单机上进行的针对一小块数据的计算过程。在一个Node节点上把不同颜色散乱在一起圆点根据颜色放在一起map不进行合并car1 car1,到reduce才合并car2hello you hello you变成<0,hello you><1,hello you>

  • Shuffle :在Map基础上进行数据移动,为后续Reduce阶段做准备。不同Node节点上颜色分完组之后,把颜色相同的放在一起。排序,框架做我们不用做分组,我们只map和reduce

  • Reduce :对移动的数据进行处理(求和等),依然是在单机上处理一小份数据。

(1)为什么Shuffle对性能非常重要

  • MxR次网络连接 、大量的数据移动、数据丢失风险、可能存在大量的排序操作、数据压缩、大量的数据序列化、反序列化操作序列化:将结构化对象转换为字节流,以使进行网络传输或写入磁盘进行永久保存。反序列化:从网络或文件中读取的字节流转化为结构化对象。进程间通信是通过远程过程调用RFC实现的。如果自定义的序列化,不需要作为键值对参与排序,那么只需实现Writable接口。需要作为键值对参与排序,则需要Writable Comparable接口,额外实现一个基于键值进行对象比较
  • 在大数据场景下,数据Shuffle表示不同分区数据交换的过程,不同的shuffle策略性能差异较大。目前在各个引擎中Shuffle都是优化的重点,在Spark框架中,Shuffle是支持Spark进行大规模复杂数据处理的基石。MR<Spark演进过程

二、Shuffle算子

Spark中会产生Shuffle的算子大概可以分为四类有的也分为三类

屏幕截图 2022-08-01 213237.jpg

  • repartition:重改分区。
  • ByKey:按Key聚合在一起。
  • Join:把本身没在一起的按某种条件连在一起。
  • Distinct:特殊的BYKey操作。

(1)Shuffle算子应用

Spark源码中RDD的单元测试[spark/RDDSuite.scala at master ·apache/spark ·GitHub]

Spark源码中PairRDDFunctions的单元测试(spark/PairRDDFunctionsSuite.scala at master · apache/spark · GitHub)

val text = sc.textFile("mytextfile.txt")\
val counts = text\
  .flatMap(line => line.split(" "))\
  .map(word => (word,1))\
  .reduceByKey(_+_)\
counts.collect\

(2)Spark中对Shuffle的抽象-宽依赖、窄依赖

屏幕截图 2022-08-01 213949.jpg

  • 算子内部的依赖关系

屏幕截图 2022-08-01 214255.jpg 创建会产生Shuffle的RDD时,RDD会创建Shuffle Dependency来描述Shuffle相关的信息。

(3)Shuffle Dependency 构造

屏幕截图 2022-08-01 214651.jpg 1、Partitioner:两个接口 numberPartitions和getPartition 经典实现HashPartitioner partitioner用来将record映射到具体的partition的方法。

屏幕截图 2022-08-01 215735.jpg 2、Aggregator在map侧合并部分record的函数

接口:

  • CreateCombiner:只有一个Value的时候初始化的方法。
  • mergeValue:合并一个Value到Aggregator。
  • mergeCombiners:合并两个Aggregator。

3、Serializer:对象与二进制数据流相互映射。

三、Shuffle过程

(1)Shuffle实现的发展历程

屏幕截图 2022-08-01 220405.jpg

  • Hash Based Shuffle优化--优点:不需要排序。缺点:打开创建文件过多。解决数据大,占有资源多和打开文件次数多,占有资源多的问题。是C* R文件,其中C是申请CPU的核数。虽然M变成了C但是没有解决问题,所有引入了Sort Based Shuffle
  • Sort based Shuffle--优点:打开的文件少,支持map-side combine、缺点:需要排序。堆内存储,无Java对象内存开销,没有垃圾回收开销。比较key。
  • TungstenSortShuffle--优点:更快的排序效率,更高的内存利用效率。缺点:不支持map-side combine。

(2)Hash Shuffle

1、写数据每个partition会映射到一个独立的文件

屏幕截图 2022-08-01 221256.jpg 2、写数据优化每个partition会映射到一个文件片段

屏幕截图 2022-08-01 221606.jpg

(3)Sort Shuffle

1、写数据 每个Task生成一个包含所有partition数据的文件

屏幕截图 2022-08-01 221746.jpg 2、读数据每个reduce task分别获取所有map task生成的属于自己的片段

屏幕截图 2022-08-01 221910.jpg

(4)Shuffle过程的触发流程

屏幕截图 2022-08-01 222032.jpg

(5)Shuffle Handle的创建

屏幕截图 2022-08-01 222204.jpg

  • Register Shuffle

由action算子触发DAG Scheduler进行Shuffle register.Shuffle Register会根据不同的条件决定注册不同的ShuffleHandle。

(6)shuffle Handle和Shuffle Writer的对应关系

屏幕截图 2022-08-01 222327.jpg

  • BypassMergeSortShuffleWriter相当于Hash based Shuffle。
  • UnsafeShuffleWriter相当于Tungsten-sort based Shuffle。
  • SortShuffleWriter相当于Sort based Shuffle。

(7)Writer实现

1、BYpassMergeShuffleWriter

屏幕截图 2022-08-01 222511.jpg 2、UnsafeShuffleWriter

屏幕截图 2022-08-01 222605.jpg

屏幕截图 2022-08-01 223418.jpg 3、SortShuffleWriter

屏幕截图 2022-08-01 223515.jpg

(8)Reader实现-网络时序图

render实现,本地、外地(不需网络)

屏幕截图 2022-08-01 223739.jpg Spark底层传输netty,申请堆外内存,用0拷贝技术。同时作为网络框架提供网络服务,并接受reduce Task的fetch请求。

首先发起openBlocks请求获得Stream id,然后再处理Stream或者chunk请求。

1、ShuffleBlockFetchlterator

屏幕截图 2022-08-01 224231.jpg fetchRequests随机、fetchlocalBlocks本地 防止OOM:获取字数大小、获取请求大小、地址Block数量、请求Size放下Tomen、控制OOM次数次数越多,限制request请求。

(9)Read实现-External Shuffle Service

屏幕截图 2022-08-01 224830.jpg 可以包装,对外提供一个对象,实现本身需要复制才能是实现的功能。netty包装把两个数组的数藏起来,额外提供一个对象,这个对象看上去像有三个数组。

为了解决Executor为了服务数据的fetch请求导致无法退出问题,我们在每个节点上部署一个External Shuffle Service,这样产生数据的Executor在不需要继续处理任务时,可以随意退出。

(10)Shuffle优化使用的技术

1、Zero Copy 零拷贝:sendfile简化传输,减少上下文切换,减少复制+DMA gather copy

屏幕截图 2022-08-01 225432.jpg 2、Netty zero Copy

  • 可堆外内存,避免JVM堆内存到堆外内存的数据拷贝。
  • CompositeByteBuf、Unpooled.wrappedBuffer、ByteBuf.slice,可以合并、包装、切分数组、避免发生内存拷贝。
  • Netty使用FileRegion实现文件传输,FileRegion底层封装了FileChannel#transferTo()方法,可以将文件缓存区的数据直接传输到目标Channel,避免内核缓冲区之间的数据拷贝。

(11)Shuffle优化

屏幕截图 2022-08-01 230242.jpg 1、使用可以map-side预聚合的算子

屏幕截图 2022-08-01 230404.jpg reduceing<key,value>其中key是偏移量指针,value是集合迭代器。 第一个用户看了第103个电影,评分2.5以键值对 <1,103:2.5>,<>叫范型

2、参数优化

屏幕截图 2022-08-01 230529.jpg 3、倾斜优化 倾斜:假设hello7个而其他只有一个,就会导致一个Task非常大。Task整体运行时间取决于Task最大的。倾斜影响:作业运行时间变长,Task OOM导致作业失败。

屏幕截图 2022-08-02 081712.jpg 常见的优化倾斜处理方法:提高并行度+AQE `

屏幕截图 2022-08-02 081918.jpg Spark AQE Skew Join AQE根据shuffle文件统计数据自动检测倾斜数据,将那些倾斜的分区打散成小的子分区,然后各自进行Join。就像图中把四个虽然拆分成五个但Task变小了,速度变快。

屏幕截图 2022-08-02 082409.jpg

(11)案例-参数优化

屏幕截图 2022-08-02 082536.jpg

(12)参数调整

屏幕截图 2022-08-02 082710.jpg Q:上一部分所讲的shuffle过程存在哪些问题?为了优化该问题很多公司做了思路相近的优化Push Shuffle

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

四、Push Shuffle

为什么需要Push Shuffle?

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

(1)Push Shuffle的实现 业界最火

屏幕截图 2022-08-02 083159.jpg

(2)Magnet 实现原理

主要为边写边push的模式,在原有的Shuffle基础上,尝试push聚合数据,但并不强制完成,读取时优先读取push数据聚合的结果,对于没有Push来得及完成聚合或者聚合失败的情况,则fallback到原模式。

屏幕截图 2022-08-02 083259.jpg

屏幕截图 2022-08-02 083429.jpg Magnet可靠性:

  • 如果Map Task输出的bloke没有成功Push到magnet上,并且反复重试仍然失败,则reduce task直接从ess上拉取原始Block数据。
  • 如果magnet上的block因为重复或者冲突等原因,没有正常完成merge的过程,则reduce task直接拉取未完成merge的block。
  • 如果reduce拉取已经merge好的block失败,则会直接拉取merge前的原始block。
  • 本质上,magnet中维护了两份Shuffle数据的副本。

(3)Cloud Shuffle Service思想字节

屏幕截图 2022-08-02 084536.jpg I/O集合后如果丢失,就得重头开始,所有得备份。

屏幕截图 2022-08-02 084754.jpg 1、Cloud Shuffle Service写入流程红框外是读取流程

屏幕截图 2022-08-02 084859.jpg 2、Cloud Shuffle Service AQE

在聚合文件时主动将文件切分成若干块,当触发AQE时,按照已经切分好的文件块进行拆分。

屏幕截图 2022-08-02 085036.jpg

3、实践案例-CSS优化

屏幕截图 2022-08-02 085237.jpg

五、课后自测

1、自己构造一个会产生shuffle 的spark作业,修改shuffle相关的参数,对比一下不同参数对作业运行的影响。

2、在spark中shuffle实现的发展过程中,每一次变化都优化了之前哪些缺点,又带来了哪些问题?

3、Push Shuffle相对比Fetch Shuffle最大的挑战是什么?

六、电影推荐项目

1、按推荐算法分类:Collaborate协同、Filter过滤

  • 协同过滤算法:userCF两个用户兴趣相近,则A买过啥就给B推荐啥、itemCF根据我曾经买过东西推荐相似的、modelCF
  • 基于内容的推荐算法:用户内容属性和物品内容属性。
  • 社会化过滤算法:基于用户的社会网络关系。

2、按模型划分:

  • 最近邻模型(SVD):基于距离的协同过滤算法。
  • Latnet Factor Model:基于矩阵分解的模型。
  • Graph:图模型,社会网络图模型。

D1D1EDEAC8F0FE301D169203E13D38BF.png 其中汇总就是同现矩阵一起出现,考虑每个数字关联度。 减噪去除已经看过的电影视频等,避免重复推荐。例如用户A看过abc电影,用户B看过bc电影, 用户C看ac电影。减噪后A用户评分没用因为他都看过、B用户没看过a所以推荐C给a电影评分10、C用户没看过b则推荐B给c的评分7给用户C。

C530D0889231AB8C82A73E9474618BFD.png