Spark Shuffle两种Manager

前言

reduceByKey会将上一个RDD中的每一个key对应的所有value聚合成一个value,然后生成一个新的RDD,元素类型是<key,value>对的形式,这样每一个key对应一个聚合起来的value。聚合之前,每一个key对应的value不一定都是在一个partition中,也不太可能在同一个节点上,因为RDD是分布式的弹性的数据集,RDD的partition极有可能分布在各个节点上。在1.6版本中有两种管理机制:hashShuffleManager、sortShuffleManager。在2.3版本中砍掉了hashShuffleManager,只留下了sortShuffleManager。

hashShuffleManager

1.普通机制

在这里插入图片描述
上图中1个cpu core,2个task,必定串行运行。一个Task的数据写往内存Buffer缓冲区,每个Buffer的大小是32k,有几个reduceTask就写往几个buffer。每个buffer对应一个磁盘小文件。然后reduce端就从各个节点拉取属于自己的磁盘小文件。小文件个数=map个数*reduce个数

缺陷

产生的磁盘小文件过多,会导致:
1.shuffle write过程会产生很多写磁盘小文件的对象
2.shuffle read过程会产生很多读取磁盘小文件的对象
3.在JVM堆内存中对象过多就会造成频繁GC,如果GC都解决不了运行所需内存问题,就会OOM
4.数据传输过程中会有频繁的网络通信,频繁的网络通信出现通信故障的可能性大大增加,一旦网络通信出现了故障会导致shuffle file cannot find 由于这个错误导致的task失败,TaskScheduler不负责重试,由DAGScheduler负责重试Stage。

2.合并机制-优化

task共用一个buffer缓冲区,小文件个数=core个数*reduce个数
在这里插入图片描述

sortShuffleManager

能够替代hashShuffleManager,主要就是为了解决磁盘I/O问题。

1.普通机制

在这里插入图片描述

小文件个数:2map (2包含索引文件和磁盘文件)
1.map task 的计算结果会写入到一个内存数据结构里面,内存数据结构默认是5M
2.在shuffle的时候会有一个定时器,不定期的去估算这个内存结构的大小,当内存结构中的数据超过5M时,比如现在内存结构中的数据为5.01M,那么他会申请5.01
2-5=5.02M内存给内存数据结构。
3.如果申请成功不会进行溢写(继续写往内存),如果申请不成功,这时候会发生溢写磁盘。
4.在溢写之前内存结构中的数据会根据分区号进行排序(0、1、2)
5.然后开始溢写磁盘,写磁盘是以batch的形式去写,一个batch是1万条数据,
6.map task执行完成后,会将这些磁盘小文件合并成一个大的磁盘文件(0号在一块,1号在一块…),同时生成一个索引文件。
7.reduce task去map端拉取数据的时候,首先解析索引文件,根据索引文件再去拉取对应的数据。

2.byPass机制

在这里插入图片描述
相比于普通模式,丢弃了排序。诸如:repartition之类的算子涉及到了重新分区,所有排序在此处就毫无意义了。

总结:

① bypass运行机制的触发条件如下:
shuffle reduce task的数量小于spark.shuffle.sort.bypassMergeThreshold的参数值。这个值默认是200。
产生的磁盘小文件为:2*M(map task的个数)
②map端不能有预聚合

发布了197 篇原创文章 · 获赞 245 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_36299025/article/details/97611285
今日推荐