Spark Shuffle内幕解密

来源:互联网 发布:ff14龙女捏脸数据分享 编辑:程序博客网 时间:2024/05/21 11:33

一:什么是Shuffle?
Shuffle中文翻译“洗牌”,需要Shuffle的关键性原因是某种具有共同特征的数据需要最终汇聚到一个计算节点上进行计算。shuffle会将中间结果存储在本地,然后下个stage需要数据再去向这个节点要数据(此时如果是不同节点会涉及到网络传输)。

二:Shuffle可能面临的问题?运行Task的时候才会产生Shuffle(Shuffle已经融化在Spark的算子中了)。
1.数据量非常大;(几千台机器进行shuffle,网络传输比较大)

2.数据如何分类,即如何Partition:hash,sort,钨丝计算(tungsten);

3.负载均衡(数据倾斜);(不同方式进行shuffle)

4.网络传输效率,需要在压缩和解压缩(CPU)之间做出权衡,序列化和反序列化也是要考虑的问题;

说明:具体的Task进行计算的时候尽一切最大可能使得数据具备Process Locality的特性;退而求次是增加数据分片,减少每个Task处理的数据量。

三:Hash Shuffle
1.Key不能使Array;
2.Hash Shuffle不需要排序,此时从理论上讲就节省了Hadoop MapReduce中进行Shuffle需要排序时候的时间浪费,因为实际生产环境有大量的不需要排序Shuffle的类型;
3.每个ShuffleMapTask会根据key的哈希值计算出当前key需要写入的Partition,然后把决定后的结果写入到单独的文件,此时会导致每个Task产生R(指下一个Stage的并行度(reduce的个数))个文件,如果当前的Stage中有M个ShuffleMapTask,则会产生M*R个文件

上个Stage的信息会注册给driver,下个Stage会从driver中(通过网络)读取数据,但是注意:shuffle操作绝大多数情况下都要通过网络,如果mapper和reducer在同一台机器上,此时只需要读取本地磁盘即可。

除了最后一个Stage外的Stage,Task的类型是ShuffleMapTask
Task在执行过程中,假设下一个Stage有三个并行,如果有两个shufflemaptask,就会产生六个文件,但是数量越大,就越大
读数据需要文件句柄读数据
这里写图片描述

**思考:不需要排序的Hash Shuffle是否一定比需要排序的Sorted Shuffle速度更快?
答:不一定,如果数据规模比较小的情况下,Hash Shuffle会比Sorted Shuffle速度快(快很多)!但是如果数据量大,此时Sorted Shuffle一般都会比Hash Shuffle快(很多)!**

注意:Shuffle操作绝大多数情况下都要通过网络,如果Mapper和Reducer在同一台机器上,此时只需要读取本地磁盘即可。

Hash Shuffle的俩大死穴:第一:Shuffle前会产生海量的小文件于磁盘之上,此时会产生大量耗时低效的IO操作;第二:内存不共用!!!由于内存中需要保存海量的文件操作句柄和临时缓存信息,如果数据处理规模比较庞大的话,内存不可承受,出现OOM等问题!!

三:Sorted Shuffle:

为了改善上述的问题(同时打开过多文件导致Write Handler内存使用过大以及产生过度文件导致大量的随机读写带来的效率极为地下的磁盘IO操作),Spark后来推出了Consolidate机制,来把小文件合并。此时Shuffle时文件产生的数量为Cores*R,对于ShuffleMapTask数量明显多于同时可用并行的Cores的数量的情况下,Shuffle产生的文件会大幅度减少,会极大降低OOM的可能;

为此Spark推出了Shuffle Pluggable开放框架,方便系统升级的时候定制Shuffle功能模块,也方便第三方系统改造人员根据实际的业务尝尽来开发具体最佳的Shuffle模块;核心接口ShuffleManager。具体默认实现由HashShuffleManager,SortShuffleManager等;Spark 1.6.0中具体的配置如下:

val shortShuffleMgrNames = Map( “hash”-> “org.apache.spark.shuffle.hash.HashShuffleManager”, “sort”-> “org.apache.spark.shuffle.sort.SortShuffleManager”, “tungsten-sort”-> “org.apache.spark.shuffle.sort.SortShuffleManager”)

默认是sort

首先shuffle map不会,所有结果写到一个文件中,还有索引,避免产生大量文件,磁盘文件变小,索引,节省内存,减少gc分享频率,减少同时写多个文件给系统带来的压力,归并排序