大数据技术 - MapReduce的Combiner介绍

本章来简单介绍下 Hadoop MapReduce 中的 Combiner。Combiner 是为了聚合数据而出现的,那为何要聚合数据呢?由于咱们知道 Shuffle 过程是消耗网络IO 和 磁盘IO 比较大的操做,若是咱们能减小 Shuffle 过程的数据量,那就能够提高整个 MR 做业的性能。我在《大数据技术 - MapReduce的Shuffle及调优》 一文中写到 Shuffle 中会有两次调用 Combiner 的过程,有兴趣的朋友能够再翻回去看看。接下来咱们仍是以 WordCount 为例,简单介绍下 Combiner 的做用以及什么时候能够设置 Combiner。网络

Combiner 的做用

假设有 2 个输入文件,每一个文件只有一行数据,所以 map 阶段启动的 map 任务数为 2,reduce 任务的数量使用默认值 1 便可。文件内容以下:app

#第一个文件内容
hello hello

#第二个文件的内容
world world

本例子仍然使用《大数据技术 - 通俗理解MapReduce之WordCount》中的代码。该 MR 做业数据传输过程以下:函数

由上图能够发现,每一个 map 任务的输出都有重复的 key。假设每一个任务输出记录是几百万甚至几千万,重复的 key 会更多。这时若是咱们要减小 Shuffle 过程传输的数据量,咱们要怎么办呢?因为咱们这个做业是个计数的任务,所以容易想到的方法是在 map 端输出的时候对相同的 key 先作一遍计数,这样作一来能够减小数据量,二来不影响 reduce 端的统计结果。在 Hadoop 中若是要实现上述过程须要在 job 中指定 Combiner,代码以下:oop

job.setMapperClass(WordCountMapper.class); //设置 map 任务的类
job.setCombinerClass(WordCountReducer.class); // 设置 Combiner
job.setReducerClass(WordCountReducer.class); // 设置 reduce 任务的类

咱们能够看到设置 Combiner 的 class 与 Reducer 相同,所以咱们说 Combiner 不会改变 reduce 的输出结果。引入 Combiner 后,咱们的 MR 做业数据传输过程以下:性能

设置 Combiner 后,Shuffle 过程传输的数据量明显减小。这里就是咱们在写 Shuffle 那篇文章中所说的,map 任务输出到本地磁盘时会先判断有没有设置 Combiner ,若是有会调用 Combiner 作聚合以减小写入磁盘的数据量,从而减小网络 IO。Shuffle 还有一个过程会调用 Combiner 但在上图没有体现。那就是在 reduce 复制阶段须要溢写文件的时候,由于 reduce 接收来自不一样的 map 输出的数据,这时候会出现 key 相同的记录,对相同 key 进行聚合一样能够减小输出到磁盘的数据量,同时也能够减小 reduce 函数对内存的占用。学习

为何要用 Combiner

读到这里咱们已经清楚了 Combiner 的做用。可能有些读者会说,我在 map 函数中把相同的 key 聚合起来不同能达到 map 输出的聚合效果吗, 一样也能减小 Shuffle 过程的网络 IO。但这种作法并不可取,缘由有三:大数据

  • 这种作法 map 函数和 reduce 函数业务逻辑出现重合
  • 若是 reduce 函数要作一些其余的处理逻辑,好比对输入的 key 小写转大,那么 map 函数中也要进行一样的处理
  • 通过上面的介绍咱们知道调用 Combiner 不止在 map 输出时会发生,reduce 复制阶段时也会发生,若是将聚合操做写在 map 函数里,reduce 复制阶段将没法聚合

可是引入 Combiner 就不会出现上述问题,这里咱们总结一下为何要引入 Combiner优化

  • 减小本地磁盘 IO
  • 减小 reduce 端复制数据的网络 IO
  • 将上述优化与业务逻辑剥离,使得做业调优与业务逻辑之间的耦合度下降

所以,我的认为 Combiner 的设计是比较优秀的。咱们学习新东西的时候就是须要不断的思考为何要这样设计,这样设计的优缺点以及不这样设计的优缺点,这样咱们成长的会快。spa

何时用 Combiner

到目前为止咱们已经知道 Combiner 的优点很是明显,可是不是全部的做业均可以设置 Combiner 呢?答案是否认的。对于咱们的 WordCount 这个例子来讲,由于是求和操做,所以在任何阶段进行求和不会影响最终的结果。可是有些做业是不行的,好比求平均值。若是在 map 输出时或者 reduce 复制阶段对一部分 key 先求了平均值,那是没法保证最终 reduce 函数输出的平均值是正确的。所以对于求最值、求和之类的统计咱们能够设置 Combiner。设计

除了直接用 Reducer 设置 Combiner 外,咱们也能够自定义 Combiner ,跟写 Reducer 同样,须要继承 Reducer<K1, V1, K2, V2>,实现 reduce 方法。只要保证最终不影响 reduce 输出结果便可。

总结

总结一下这篇文章,在优化 MR 做业的 Shuffle 时能够考虑引入 Combiner 来减小网络 IO 和磁盘 IO。但通常针对特定的统计任务才能够引入 Combiner ,如求最值、求和。同时,咱们也深刻分析引入 Combiner 在设计上的优点,既能够灵活应用在各个阶段进行聚合,又能够将调优与业务逻辑解耦。

相关文章
相关标签/搜索