Spark之shuffle

shuffle:groupByKey、reduceByKey、countByKey、部分join
遇到宽依赖就会产生shuffle,切分出新的stage。
数据倾斜:相同key的数据会分发到同一个task中执行。
调优:代码、资源、skew、shuffle

shuffle的类型

hash:HashShuffleManager ( < spark1.2)
sort:SortShuffleManager ( > spark1.2)
tungsten-sort:SortShuffleManager ( > spark1.5)

HashShuffleManager

每一个map task要为每个reduce task创建“东西”(内存(bucket)、file)。
产生的问题:
1)产生过多的file:M * R
spark job的maptask和reducetask个数都是比较大的,所以中间产生的磁盘文件数量是非常惊人的。
2)耗费过多的内存空间
每个maptask需要开启R个bucket。
由于内存可以复用,同时存在的bucket数量:R * core
bucket大小:spark.shuffle.file.buffer,默认32K
在这里插入图片描述
HashShuffleManager优化
map端输出文件合并:一个core上连续执行的shufflemaptask可以共用一个输出文件。
产生的file数量:R * core
只需要配置:spark.shuffle.consolidateFiles (1.2才有)

SortShuffleManager

SortShuffleManager的运行机制主要分成两种,一种是普通运行机制,另一种是bypass运行机制。当shuffle map task的数量小于等于spark.shuffle.sort.bypassMergeThreshold参数的值时(默认为200),就会启用bypass机制。
普通运行机制
在该模式下,Shuffle Write 阶段会将数据写入一个内存的数据结构中,此时根据不同的算子会有不同的数据结构。比如是 reduceByKey 这种聚合类的 shuffle 算子,会选用 Map 数据结构,一遍用 Map 进行聚合,一遍写入内存;如果是 join 相关的普通 shuffle 算子的话,会用 Array 数据结构,直接写入内存。当内存达到临界阈值之后,会将内存中的数据进行排序,然后分批次写入内存缓冲流 (默认每批次有 1W 条数据),当缓冲流溢满之后一次性写入磁盘。
此时也会生成大批量的文件,最后会将之前所有的临时磁盘文件进行合并,这就是 merge 过程 (就是将所有的临时磁盘文件中的数据读取出来,然后依次写入最终的文件中)。每个 task 最终会生成一份磁盘文件和一份索引文件,索引文件中标识了下游每个 task 数据在文件中的 start offset 和 end offset。
在这里插入图片描述
bypass 机制
触发该机制的条件:

  • shuffle reduce 端的 task 数量小于 spark.shuffle.sort.bypassMergeThreshold 参数值(200);
  • 不是聚合类的shuffle算子(比如reduceByKey);

该机制下,当前 stage 的每个 task 会将数据的 key 进行 hash,然后将相同 hash 的 key 所对应的数据写入到同一个内存缓冲区,缓冲写满后会溢写到磁盘文件(这里和 HashShuffleManager一致),然后会进入 merge 阶段,将所有的磁盘文件合并成一个磁盘文件,并创建一个索引文件。
在这里插入图片描述

相比较于普通机制,这里有两个地方不同:

  • 将数据写入内存时候,普通模式是将数据写入 Map 或者 Array 这样的内存数据结构中,这里是根据 key 的 Hash 值写入内存;
  • 该模式下在写入磁盘之前不会排序。

参考:https://www.aboutyun.com/thread-27330-1-1.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值