深入理解MapReduce

shuffle和排序

MapReduce确保每个reducer的输入都是按键排序的. 系统执行排序, 将map输出作为输入给reducer的过程称为shuffle. 学习shuffle 是如何工作的, 有助于理解工作机制, shuffle属于不断被优化和改进代码的一部分
在这里插入图片描述

map端
  • map函数开始产生输出时, 并不是简单地将它写到磁盘. 这个过程相对比较复杂, 它利用缓冲的方式写到内存并处于效率的考虑进行预排序.

  • 每个map任务都有一个环形内存缓冲区用于存储任务输出. 在默认情况下, 缓冲区的大小为100MB, 这个值可以通过改变mapreduce.task.io.sort.mb 属性来调整. 一旦缓冲内容达到阈值(mapreduce.map.sort.spill.percent, 默认为80%), 一个后台线程便开始把内容溢出到磁盘. 在溢出写到磁盘的过程中, map输出继续写到缓冲区, 但如果在此期间缓冲区被填满, map会被阻塞直到写磁盘过程完成. 溢出写过程按轮询方式将缓冲区中的内容写到mapreduce.cluster.local.dir 属性在作业特定子目录下制定的目录中.

  • 在写磁盘之前, 线程首先根据数据最终要传的reducer把数据划分成相应的分区(partition), 在每个分区中, 后台线程按键进行内存中排序, 如果有一个Combiner函数, 它就在排序后的输出上运行. 运行Combiner函数使得map输出结果更紧凑, 因此减少写到磁盘的数据和传递给reducer的数据.

  • 每次内存缓冲区达到溢出阈值, 就会新建一个溢出文件(spill file), 因此在map在任务写完其最后一个输出记录之后, 会有几个溢出文件, 在任务完成之前, 溢出文件被合并成一个已分区且已排序的输出文件, 配置属性 maoreduce.task.io.sort.factor 控制着一次最多能合并多少流, 默认值是10.

  • 如果至少存在3个溢出文件(通过mapreduce .map. combine.minspills 属性设置)时, 则Combiner就会在输出文件写到磁盘之前再次运行. Combiner可以反复运行, 但并不影响最终结果, 如果只有1个或者2个溢出文件, 那么由于map输出规模减少, 不值得调用Combiner函数, 所以不会为该map输出再次调用Combiner.

reduce端
  • map输出文件位于map任务的tasktracker 的本地磁盘(注意:尽管map输出经常写到map tasktracker 的本地磁盘, 但reduce输出并不这样), 现在, tasktracker需要为分区文件运行reduce任务. 并且, reduce任务需要集群上若干个map任务的map输出作为其特殊的分区文件. 每个map 任务的完成时间可能不同, 因此每个任务完成时, reduce任务就开始赋值其输出. 这就是reduce任务的赋值阶段. reduce任务有少量复制线程, 因此能够并行取得map输出. 默认值是5个线程.

  • 如果map输出相当小, 会被复制到reduce任务JVM 的内存, 否则, map输出被复制到磁盘. 一旦内存缓冲区达到阈值大小或达到map输出阈值, 则合并后溢出写到磁盘中. 如果指定Combiner, 则再合并期运行它以降低写入硬盘的数据量.

  • 随着磁盘上副本增多, 后台线程会将它们合并为更大的, 排序好的文件. 这会为后面的合并节省一些时间. 注意:为了合并, 压缩的map输出都必须在内存中解压缩

  • 复制完所有map输出后, reduce任务进入排序阶段(更恰当的说法是合并阶段, 因为排序是在map端进行的), 这个阶段将合并map输出, 维持其顺序排序. 这是循环进行的. 比如, 如果有50个map输出, 而合并因子是10(10为默认值), 合并将进行5趟, 每趟将10个文件合并成一个文件, 因此最后又5个中间文件.

  • 在最后阶段, 即reduce阶段, 直接把数据输入reduce函数, 从而省略了一次磁盘往返行程, 并没有将这5个文件合并成一个已排序的文件作为最后一趟. 最后的合并可以来自内存和磁盘片段.

  • 在reduce阶段, 对已排序输出中的每个键调用reduce函数. 此阶段的输出直接写到输出文件系统, 一般为HDFS. 如果采用HDFS , 由于节点管理器也运行数据节点, 所以第一个块副本将被写到本地磁盘.


摘自hadoop权威指南

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值