Spark技术内幕:SortBasedShuffle实现解析

Spark技术内幕:SortBasedShuffle实现解析

来源:IT165收集  发布日期:2015-01-05 23:36:12

在Spark 1.2.0中,Spark Core的一个重要的升级就是将默认的Hash Based Shuffle换成了Sort Based Shuffle,即spark.shuffle.manager 从hash换成了sort,对应的实现类分别是org.apache.spark.shuffle.hash.HashShuffleManager和org.apache.spark.shuffle.sort.SortShuffleManager。

这个方式的选择是在org.apache.spark.SparkEnv完成的:

1. // Let the user specify short names forshuffle managers
2. val shortShuffleMgrNames = Map(
3.   "hash" ->"org.apache.spark.shuffle.hash.HashShuffleManager",
4.   "sort" ->"org.apache.spark.shuffle.sort.SortShuffleManager")
5. val shuffleMgrName =conf.get("spark.shuffle.manager", "sort") //获得Shuffle Manager的type,sort为默认
6. val shuffleMgrClass =shortShuffleMgrNames.getOrElse(shuffleMgrName.toLowerCase, shuffleMgrName)
7. val shuffleManager =instantiateClass[ShuffleManager](shuffleMgrClass)

那么Sort BasedShuffle“取代”Hash BasedShuffle作为默认选项的原因是什么?

正如前面提到的,Hashbased shuffle的每个mapper都需要为每个reducer写一个文件,供reducer读取,即需要产生M*R个数量的文件,如果mapper和reducer的数量比较大,产生的文件数会非常多。Hash based shuffle设计的目标之一就是避免不需要的排序(Hadoop Map Reduce被人诟病的地方,很多不需要sort的地方的sort导致了不必要的开销)。但是它在处理超大规模数据集的时候,产生了大量的DiskIO和内存的消耗,这无疑很影响性能。Hash based shuffle也在不断的优化中,正如前面讲到的Spark 0.8.1引入的file consolidation在一定程度上解决了这个问题。为了更好的解决这个问题,Spark 1.1 引入了Sort based shuffle。首先,每个Shuffle Map Task不会为每个Reducer生成一个单独的文件;相反,它会将所有的结果写到一个文件里,同时会生成一个index文件,Reducer可以通过这个index文件取得它需要处理的数据。避免产生大量的文件的直接收益就是节省了内存的使用和顺序Disk IO带来的低延时。节省内存的使用可以减少GC的风险和频率。而减少文件的数量可以避免同时写多个文件对系统带来的压力。

并且从作者ReynoldXin的几乎所有的测试来看,Sortbased shuffle在速度和内存使用方面优于Hashbased shuffle:“sort-basedshuffle has lower memory usage and seems to outperformhash-based in almost allof our testing.”

性能数据:from:https://issues.apache.org/jira/browse/SPARK-3280


Shuffle Map Task会按照key相对应的partition ID进行sort,其中属于同一个partition的key不会sort。因为对于不需要sort的操作来说,这个sort是负收益的;要炸ky"http://www.it165.net/qq/" target="_blank" class="keylink">qq1wNaux7BTcGFya7jVv6rKvMq508NIYXNoIGJhc2VktcRzaHVmZmxltviyu8rHc29ydCBiYXNlZL7NysfOqsHLsdzD4khhZG9vcCBNYXAgUmVkdWNlttTT2sv509C8xsvjtry74XNvcnS1xNDUxNzL8LrEoaO21NPaxMfQqdDo0qpzb3J0tcTUy8vjo6yxyMjnc29ydEJ5S2V5o6zV4rj2c29ydNTaU3BhcmsgMS4yLjDA77u5ysfTyXJlZHVjZXLN6rPJtcShozwvcD48cD7I57n71eK49rn9s8zE2rTmsru5u9PDwcujrMTHw7TV4tCp0tG+rXNvcnS1xMTayN274bG7c3BpbGy1vc3isr+05rSioaPIu7rz1Nq94cr4tcTKsbryvavV4tCpsrvNrLXEzsS8/r340NBtZXJnZSBzb3J0oaM8L3A+PHA+zqrBy7Hj09rPwtPOtcRUYXNrZmV0Y2i1vcbk0OjSqrXEcGFydGl0aW9uo6zV4sDvu+HJ+rPJ0ru49mluZGV4zsS8/qOsyKW8x8K8srvNrLXEcGFydGl0aW9utcTOu9bD0MXPoqGjtbHIu8HLb3JnLmFwYWNoZS5zcGFyay5zdG9yYWdlLkJsb2NrTWFuYWdlctDo0qrSstPQz+zTprXEyrXP1tLUyrXP1tXi1tbQwrXE0bDWt7e9yr2hozwvcD48cD48aW1nIHNyYz0="http://www.it165.net/uploadfile/files/2015/0105/20150105220629433.png" alt="" />

核心实现的逻辑都在类org.apache.spark.shuffle.sort.SortShuffleWriter。下面简要分析一下它的实现:

1) 对于每个partition,创建一个scala.Array存储它所包含的key,value对。每个待处理的key,value对都会插入相应的scala.Array。

2) 如果scala.Array的大小超过阈值,那么需穴ky"http://www.it165.net/qq/" target="_blank" class="keylink">qq9q9XiuPZpbiBtZW1vcnm1xMr9vt1zcGlsbLW9zeKyv7TmtKKho9XiuPbOxLz+tcS/qsq8sr+31rvhvMfCvNXiuPZwYXJ0aXRpb261xElEo6zV4rj2zsS8/rGjtObBy7bgydm49nBhaXK1yNDFz6KhozwvcD48cD4zo6kgICAgICAgICAg1+6689Do0qq9q8v509BzcGlsbLW9zeKyv7TmtKK1xM7EvP69+NDQbWVyZ2Vzb3J0oaPNrMqxtPK/qrXEzsS8/rK7xNy5/bbgo6y5/bbgtcS7sLvhz/u6xLTzwb+1xMTatOajrNT2vNNPT0278tXfR0O1xLfnz9Wju9KysrvE3Ln9ydmjrLn9ydm1xLuwvs274dOwz+zQ1MTco6zU9rTzvMbL47XE0dPKsaGj0ruw47XEu7DNxrz2w7+0zs2syrG08r+qMTAgqEMgMTAwuPbOxLz+oaM8L3A+PHA+NKOpICAgICAgICAgINTayfqzydfuuvO1xMr9vt3OxLz+yrGjrNDo0qrNrMqxyfqzyWluZGV4y/fS/c7EvP6ho9X9yOfHsMPmzOG1vbXEo6zV4rj2y/fS/c7EvP69q7zHwryyu82scGFydGl0aW9utcRyYW5nZaGjPC9wPjxwPrWxyLvBy6OsxOO/ycTcu7nT0Lj20snOyqOsvs3Kx0hhc2ggQmFzZWQgU2h1ZmZsZcu1sNfBy77Nyse4+b7da2V50OjSqtC0yOu1xG9yZy5hcGFjaGUuc3BhcmsuSGFzaFBhcnRpdGlvbmVyo6zOqsO/uPZSZWR1Y2Vy0LTI67WltsC1xFBhcnRpdGlvbqGj1ruyu7n9ttTT2s2s0ru49kNvcmXG9LavtcRTaHVmZmxlIE1hcCBUYXNro6zI57n70aHU8XNwYXJrLnNodWZmbGUuY29uc29saWRhdGVGaWxlc7XEu7CjrLXatv649lNodWZmbGUgTWFwIFRhc2u74bDRveG5+2FwcGVuZLW9yc/Su7j2zsS8/tbQyKWho8THw7Rzb3J0tcTC37ytysfN6sirv8nS1NX7us+1vUhhc2ggQmFzZWQgU2h1ZmZsZdbQyKWjrM6qyrLDtNPW0qrW2NDCyrXP1tK71tZTaHVmZmxlIFdyaXRlcsTYo7/O0sjPzqrT0NLUz8K8uLXjo7o8L3A+PHVsIHR5cGU9"disc"> Shuffle机制是所有类似计算模块的核心机制之一,要进行大的优化的风险非常高;比如一个看似简单的consolidation机制,在0.8.1就引入了,但是到1.2.0还是没有作为默认选项。 Hash Based Shuffle如果修改为Sort的逻辑,所谓的改进可能会影响原来已经稳定的Spark应用。比如一个应用在使用Hash Based Shuffle性能是完全符合预期的,那么迁移到Spark 1.2.0后,只需要将配置文件修改以下就可以完成这个无缝的迁移。 作为一个通用的计算平台,你的测试的case永远cover不了所有的场景。那么,还是留给用户去选择吧。 Sort的机制还处理不断完善的阶段。比如很有的优化或者功能的改进会不断的完善。因此,期待Sort在以后的版本中更加完善吧。
如果您喜欢 本文,那么请动一下手指支持以下博客之星的评比吧。非常感谢您的投票。每天可以一票哦。
点我投票

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值