Spark的Shuffle过程解释

初始RDD分区个数由Split个数决定(老师说若读取HDFS初始也参考spark.default.parallelism参数指定分区数,如果使用SparkSQL读取Hive或者MySQL数据,初始按照split个数,不参考该参数),假定为N。执行过程中假如没有执行重分区则分区个数还是N,如果执行到Shuffle,Shuffle分为Map端和Reduce端,Map端的任务个数还是N,Reduce端(下个Stage)默认取spark.default.parallelism的值作为分区数,如果该值未配置,则和上一个Shuffle最末端(Map端)的任务个数一致。Shuffle的Map端结束会将数据溢写到磁盘(猜测非HDFS,先内存)并把该位置告知Driver(MapOutputTrackerWorker对象将mapStatus发给Driver的MapOutputTrackerMaster对象),下个Stage阶段Reduce端Task的MapOutputTrackerWorker向Driver的MapoutputTrackerMaster获取数据位置,然后有BlockTransferService去指定的Executor拉取数据放入20%的Executor内存中,默认启动5个子线程,每次拉取不超过48MB。任务在执行时从指定位置拉取数据(例如知道HDFS具体的Block了吧?)。

Shuffle的Map端写入:假设reduce分区个数为M,将写入M个文件,未经优化的HashShuffleManager每个Map任务都写入M个文件,将产生大量的小文件,优化后的每个CPU核心写入M个文件,下次再有Task写入直接复用原来的文件。现在优化和未优化的HashShuffleManager已经淘汰了。现在使用SortShuffleManager,包括两种运行机制,第一是普通运行机制,内存中数据达到阈值后,取10000条进行排序然后通过Java的BufferedOutputStream(自动内存缓存,优化IO性能)写入到单独的文件,写入完成之后所有的文件合并成一个大文件和一个索引文件(对应Partition的索引?),这里不针对Reduce端任务数分文件了。在Map端还会针对reduceByKey、join算子进行Map端的处理;第二种是Bypass方式,当Map端的任务数量小于spark.shuffle.sort.bypassMergeThreshold参数值时启用,写入时也会根据Hash产生M个文件,写入方式先写入缓存,然后溢写到磁盘文件,这个过程和未经优化的HashShuffleManager基本一模一样,不同之处是最后会合并成一个文件和索引文件。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值