spark-shuffle总结及调优

spark1.2  默认使用的是 HashShuffle 

写入磁盘流程:

    将每个task 处理的数据,按照 key 的 hash 进行分类,从而相同的 key 写入到同一个磁盘文件里面,而每个磁盘文件都只属于下游 stage 的一个 task,将数据写入到磁盘前,会先将数据写入到内存缓冲中,当内存缓冲填满后,溢写到磁盘文件中

    不排序,当前 stage 的每个 maptask,会为下个 stage每个 reducetask生成一个文件;

        文件数量计算公式:maptask_num * reducetask_num 

        比如当时 stage 有50个 task,下个 stage 有100个 task,那么每个 task 会创建100个文件,总共需要创建50*100

    缺点:大量随机 io,大量内存占用

下图为优化后的 hashShuffle ,开启了 File consolidation 机制

    针对第一版 shuffle 进行改进,引入 File Consolidation 机制

        文件数量计算公式:core_num * reducetask_num

        举例来说:stage 有50个 task,当前有10个core,下个 stage 有100个 task,那么每个 core会创建100个文件,总共需要创建10*100

        其它等式

            executor_core_num = shuffleFilegroup_num 

            shuffleFilegroup 产生的文件数量 = 下游 stage 的 task 数量

        开启 consolidate机制:设置 spark.shuffle.consolidateFiles = true; 开启后, shufflewrite 阶段,task 就不会再为下游 stage 的每个 task 都创建一个磁盘文件,会有shuffleFilegroup 概念,每个 shuffleFilgroup 会对应一批磁盘文件,文件数量=下游 stage 的 task 数量。一个 executor有几个 core,就会有几个 shuffleFilegroup 数量,第一批 task 并行,创建相应的文件,第二批直接利用第一批已经创建的文件


spark1.2后使用的量 sortshuffle

    sortshufflemanager 运行机制有两个:普通运行机制,另外一个是 bypass 运行机制

    普通运行机制:

    

    

文件数量: 当前 stage maptask 数量,比如当前stage的task数量为50,那么会产生50个文件

流程:

    数据先写入一个内存结构(根据不同的算子,选择不同的数据结构;如果是 bykey类,写入Map;如果是 join 类,写入 Array),接着每写入一条数据,判断是否达到溢写到磁盘的阀值(10000),如果达到阀值溢写到磁盘,然后清空内存;

    在写入磁盘前,在内存中进行排序,写入磁盘使用的是 java 的BufferedOutputStream 实现,BufferedOutputStream 是 java 的缓冲输出流,首先将内存缓存在内存里,当内存满溢后,再写入到磁盘中,减少了 io,提升性能;

    一个 task 将所有数据写入到内存结构时,会发生多次磁盘溢写,产生多个临时文件,最后将之前的文件合并,写入到最终文件里,称为merge;

    由于一个 task 只能产生一个文件,那么意味着下游task 所需文件都在这个文件里面,因此还写了一份索引文件,记录了下游各 task的数据在文件中的start offset, end offset

    

bypass 机制

当shuffle read task 数量小于等于 spark.shuffle.sort.bypassMergeThreshold参数时(默认值200)就会启用bypass 机制

前段处理与 hashshuffle 一致,当前task 为下游每个 task 创建一个文件,按照 key 的 hash值,写入到对应的文件里面;只是最后有个 merge过程,合并成一个文件,并添加索引文件

与普通机制不同点:

        1 写磁盘文件不同

        2 bypass 机制不排序


shuffle 调优

1 spark.shuffle.file.buffer

    默认:32k

    作用:用于设置 shuffle wite task 的 bufferedOutputStream 的 buffer 缓冲大小;数据写入到磁盘前,先写入到 buffer 缓冲中,待缓冲用完后,再写入到磁盘

    建议:如果资源充足,增加这个参数大小,从而减小 shuffle write 过程溢写磁盘文件的次数,一般提升1%~5%

2 spark.reducer.maxSizeInFlight

    默认:48m

    作用:用于设置 shuffle read task 的buffer 缓冲大小,决定了每次能拉多少数据

    建议:如果内存资源充足,调大这个参数,减少拉取数据次数,也就可以减少网络传输次数,一般提升1%~5%

3 spark.shuffle.io.maxRetries 

    默认:3

    作用:shuffle read task从 shuffle write task 节点拉取数据,如果遇到网络原因拉取失败,最大重试次数,如果重试超过最大次数,还没有成功,那么任务失败

    建议:对于那些包含了特征耗时的 shffle 操作,增加重试次数,防止由于 full GC,或者网络不稳定原因导致任务失败

4 spark.shuffle.io.retryWait

    默认:5s

    作用:每次重试拉取时间间隔

    建议:建议增大,以增加 shuffle 的稳定

5 spark.shuffle.memoryFraction

    默认:0.2

    作用:Executor 内存中,分配级 shuffle read task 进行聚合操作的内存比例

    建议:如果内存充足且很少使用持久化操作,建议调高这个比例,给 shuffle read 的聚合操作更多的内存,以避免由于内存不足导致聚合操作频繁读写磁盘;合理设置,可提高性能 10%

6 spark.shuffle.manager

    默认:sort

    作用:用于设置 shuffle类型 sort,hash

    建议:SortShuffleManager 为默认值;如果业务不需要排序,那么可以把 bypass 默认值调大,或者使用优化后的 hashshufle

7 spark.shuffle.sort.bypassMergeThreshold 

    默认:200

    作用:触发 bypass 机制的阀值,如果 shuffle read task 的数量小于这个阀值,则 shuffle write 过程不会进行排序操作,而是直接按照未经优化的 HashShuffleManager 的方式去写数据,但是最后会将每个 task 产生的临时磁盘文件都合并成一个文件,并创建单独的索引文件

    建议:如果不需要排序操作,就把这个值调大,大于 shuffle read task 数量,那么就会启动 bypass 机制

8 spark.shuffle.consolidateFiles

    默认:false

    作用:如果使用 HashShuffleManager,该参数有效,如果设置为 true,那么就会启动 consolidate机制,会大副合并 shuffle write 输出的文件

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值