Map-reduce 二次排序

Map-Reduce的流程切面:

  1. Split
  2. Mapper
  3. Partition
  4. Combiner
  5. Group
  6. Reducer

这里要解释下 Partition 和 Group (它们都是Shuffle的重要步骤)的区别.

他们的作用都是为了Reducer分配记录去处理.但区别是Partition是把记录分给不同的Reducer去处理(每一个partition就对应了输出的一个part). 而Group是指同一个Reducer处理过程中会有批次又叫迭代的概念, Group就是把一个Group的记录放到同一批次里去处理. 默认的分配函数是hash函数.

Reducer的同一个迭代会保留内部变量, 比如可以很方便来找最大值.

Mapper的结果会自动根据Key来排序.


因为Mapper会对key进行排序, 我们可以利用这一点把要排序的列作为key传入系统, 利用Mapper的排序, 达成我们的排序, 但是这时Reducer只能有一个. 否则两个reducer的结果可能交错,  比如第一个Reducer排序了13579, 第二个Reducer排序了2468, 那就还需要一次复杂的合并.

怎么避免?

奥妙就是充分利用上述的Partition, 把12345 交给Reducer A, 6789交给Reducer B, 这样出来的两个结果Part, 直接合并就行了.这需要重载Partition函数.


标题中的二次排序, 又是另一种情况: 要对两列进行排序, 比如一列是年份y, 一列是当年每天的最高温度m, 现在要对这两列排序, 优先排序y, y相同则再排序m. 怎么做到, 其实很容易想到的是把y和m拼起来, 合并为一个列ym, 重载Comparator函数,重载Partition函数. 确保不会因为多个Reducers, 打乱输出顺序. 比如一年的数据对应一个Reducer.

再比如要从每一年找出温度最高的一天, 这就进一步要用到Group了, 把同一年的数据Group在同一次Reducer的迭代里, 想象一下伪代码:

if(newValue > CurrentBiggestValue)
{
    CurrentBiggestValue = newValue ;
}

因为同一次迭代, 有一个公用的CurrentBiggestValue ,方便找出最大值.






posted @ 2018-03-01 16:51  爱知菜  阅读(17)  评论(0编辑  收藏  举报