Hadoop MapReduce的数据处理过程 | 搜不狐
Hadoop MapReduce的数据处理过程
Hadoop MapReduce作为一个大数据处理工具,非常的好用,但是如果我只需要单机处理不是特别庞大的数据,比如4G的查询日志,那么在没有现成环境的情况下,搭起来一个Hadoop环境还是挺烦的,直接用C/Java写一个简单的单机多进程Map Reduce数据处理工具岂不是更方便?
为了实现这个目标,我们首先要研究一下Map Reduce是如何工作的,这篇文章是从Yahoo的开发者中心的找到摘抄了其中一部分有趣的内容。
整体流程
从图中我们可以看到MapReduce的整体执行过程,主要是Map和Reduce两个过程:
很多的Mapper首先从HDFS中分别读取一部分数据,每次Mapper处理一行数据并返回一组key-value对,单个Mapper不需要与其他的mapper进行交互通信。
当Mapping过程结束之后,所有的Mapper会把具有相同key的键值对放松到相同的Reducer进行处理。
Reducer会把对具有相同key值的数据进行处理之后(如计数等),写回到HDFS,Hadoop平台会对所有Reducer写回的数据进行排序归档。
更进一步
对总体流程有了大概的认识之后,我们来对单个节点内的流程细节进行一下观察:
我们需要对图中的所有过程进行详细的了解:
1)输入文件(File)
最常用的输入文件是文本文件,系统会逐行读取进行处理,还可以是二进制文件或其他任何形式,这些文件保存在HDFS中,他们通常都比较大,往往在10G以上。
2)格式化输入文件(InputFormat)
输入文件如何被分割和读取是由InputFormat来定义的,InputFormat主要提供三个方面的功能:
- 选择要作为当前节点输入的文件
- 把输入的大文件分割成多个小文件,为每个小文件定义一个具体的分割器(InputSplit),开始一个单独的map任务。
- 创建RecordReader来读取输入文件内的内容,如单行读取、多行读取等
Hadoop本身提供了三种InputFormat实现:
3)分割器(InputSplit)
如上面的介绍,大文件被InputFormat分割成小文件后,InputSplit会按照InputFormat的类型依次读取小文件内的数据,如逐行读取,多行读取等方式。
4)RecordReader
分割器把数据读取出来之后还只是普通的文本,需要RecordReader把一次读取的数据转换成map接收的key value类型。
5)Mapper
Mapper就是用户定义的,如何对数据进行处理的函数了,它接收RecordReader的键值对输出作为自己的输入,从整体上看,单个InputFormat会生成很多个map子任务,每一个map子任务都包含一个单独的InputSplit和RecordReader实例。
Mapper的输出由OutputCollector收集并返回,通常是一组key-value对。
6)分区和洗牌(Partition & Shuffle)
这一步非常重要,当一个Map任务结束后,Map的输出要交给Reducer。每一个Reducer会有单独的分区(Partition),Map的输出要暂存到这些分区中,当所有的Map执行完毕后就可以开始Reducer了。
所有Map的输出中,具有相同key的键值对要放到同一个Reducer中进行处理,把这些输出搬运到Reducer的暂存分区的过程叫做洗牌(Shuffle)。
Hadoop使用Partitioner类计算每一个key的hash值,通过hash值把相同key的数据映射到相同的Reducer上去。
7)Sort
在所有的Map输出到达Reducer的暂存分区后,Hadoop会对分区内的数据进行排序处理,排序后再进行Reducer操作(博主:这一步不是很理解是为什么,因为所有Reducer后再排序更有意义)。
8)Reducer
和Mapper一样,Reducer也是用户用来进行处理数据的具体函数,接收Partition中暂存的Mapper输出数据,对具有相同key的数据进行处理后返回一组新的键值对。
9)格式化输出(OutputFormat)
同InputFormat一样,输出的格式化也有多个标准实现:
OutputFormat接收Reducer的输出之后,会把结果数据写回HDFS,进一步的操作就可以在HDFS中实现了,如整体的排序。
原文地址:http://developer.yahoo.com/hadoop/tutorial/module4.html#dataflow
更进一步阅读:http://developer.yahoo.com/hadoop/tutorial/module5.html