实战录 | Hadoop Mapreduce shuffle之Combine探讨

来源:互联网 发布:下单约会软件 编辑:程序博客网 时间:2024/05/17 00:04
《实战录》导语

云端卫士工程师朱震华之前一直从事业务MR的开发,他说一直觉得这是大数据开发中最low的技术。但是,要真正搞清MR的具体实现细节,其实也不简单哦,今天就来简单说说combine的问题。 大牛们请轻喷。


一、Hadoop


若干年前,google发布了三篇论文,分别对应google fs,mapreduce,和bigtable。震惊了全世界。由Doug Cutting领衔的技术大牛们,对其进行了开源实现,这就是hadoop的由来。hadoop也因此成为了大数据的代名词,在长达数十年内一直成为大数据领域内最火的技术,没有之一,并且由hadoop引申出来的其他一些技术,如,hive,pig,mahout,等也迅速发展壮大起来,形成了整个hadoop生态圈。近年来,spark以其内存计算,迭代处理计算,成为云计算领域的继Hadoop之后的下一代的最热门的通用的并行计算框架开源项目,不过不在本文的探讨范围内哦。


二、Hadoop MapReduce


Hadoop作为大数据解决方案的首选,其核心技术分为,hdfs和mapreduce。hdfs是分布式文件系统,提供数据的存储。mapreduce是一种并行计算的框架。核心思想是“分而治之”,举个简单的例子,一个人去沙滩淘金要淘N天,那么N个人一起去淘的话,可能就只需要一天了哦。对应到hadoop中,一台机器要做的事情,现在交给N台机器去做,那么,速度自然就是原来的N倍啦,不过,实际情况,肯定达不到N倍,分布式系统,不是简单的相加那么简单,具体还和每台机器的性能,数据的最终合并,等其他多种因素有关哦,这边不做详细探讨。


作为Mapreduce开发人员,我们只需要实现map方法(分)和reduce方法(合)就可以实现业务,其实框架隐藏了很多实现,帮我们做了很多事情哦。了解内部的实现机制,还是有必要的。


三、Combine


Hadoop一般是做离线数据分析,数据存储在HDFS上,以block的形式存储(默认一个block为64M,hadoop1.x),mapreduce程序运行的时候,一个loock默认对应一个map任务,而map方法具体对每一行数据进行处理,map处理完之后,reduce负责把每个map处理完的结果进行汇总,得到最终输出。


那么问题来了,从map的输出到reduce的输入,这中间hadoop究竟为我们做了什么?这就是mapreduce里面最核心的过程,shuffle。这里我简单讲一下自己的理解,书上可能讲的不是很清晰。


shuffle过程:




【1】每一个map任务完成之后,会根据Key进行分区,确定它之后由哪个reduce进行处理(默认是hash分区,也可以自定义分区方法),然后写入对应的内存缓冲区
【2】当内存缓冲区数据量达到一定值的时候,会flush到本地磁盘哦(溢写过程)
【3】如果数据量比较大,或者单节点map任务比较多,或者分区比较多,会在本地磁盘生成多个文件,当所有map任务全部跑完之后,这些本地磁盘的文件,会进行一次合并,生成最终的map输出文件
【4】reduce端会启动多个http线程去对应的节点拷贝它需要处理的数据,先将数据缓存至内存中,当数据量不断增大,也会有一个溢写的过程
【5】如果溢写多个文件,那么也会进行合并生成最终文件,作为reduce的输入


shuffle过程中还有一些排序的过程,这里我没有进行说明(其实是我自己不是很清楚,哈哈)。有兴趣的可以自己去了解哦。


combine被称作是map端的reduce,其作用是对map端的数据进行合并,逻辑一般与reduce类似,可以减少网络上传输的数据量,提高带宽的利用率。因为hadoop很大一部分瓶颈是在网络带宽方面。那么combine究竟什么时候会执行,编写combine类又需要注意些什么呢?


我原来一直以为,combine只会在map端执行一次。直到某一天,某个同事的mapreduce程序数据出现了错乱,找了好几天都没找到错误,后来才发现,是因为combine输出了多种数据格式,combine的数据与map输出不同,且逻辑也不同。导致了数据错乱,那么,为什么会错乱呢?


于是,打开mapreduce源码,去找combine被调用的代码。




这是一个map任务溢写的源码,第9行,如果没有定义combine,则map直接写文件,如果定义了combine,在35行,会执行combine操作。


再来看merge过程。



13-17行,如果定义了combine,会再次被调用。


至于在reduce端,在spill后的merge过程中,也会再次调用combine。有兴趣的朋友可以自己去看哦。


由于combine会被多次调用,所以,combine的存在,会使数据质量更高,善用combine能使mapreduce程序性能更好。


四、总结


Combine是mapreduce中很重要的一个环节,合理的使用combine能减少数据量.有人说,不写combine的mapreduce不是一个好的mapreduce。但是,并不是所有的mapreduce程序都适合用combine,求和运算可以使用combine提高性能,但是求平均值用combine就会导致错误的结果。所以,也不可盲目的使用combine,具体问题具体分析。另外,如果设定了combine,它会在多处被执行。所以,应尽量保持,combine逻辑与reduce大致相同,combine的输出也应与map的输出尽量保持一致,防止,产生错误的结果。好了,combine就先说到这里了。


0 0
原创粉丝点击