MapReduce运行原理
![](https://img2018.cnblogs.com/i-beta/1598893/201911/1598893-20191129161220288-1905876521.png)
inputSplit
1. Block
块是以 block size 进行划分数据。 因此,如果群集中的 block size 为 128 MB,则数据集的每个块将为128 MB,除非最后一个块小于block size(文件大小不能被 block size 完全整除)。例如下图中文件大小为513MB,513%128=1,最后一个块(e)小于block size,大小为1MB。 因此,块是以 block size的硬切割,并且块甚至可以在逻辑记录结束之前结束(blocks can end even before a logical recordends)。假设我们的集群中block size 是128 MB,每个逻辑记录大约100 MB(假设为巨大的记录)。所以第一个记录将完全在一个块中,因为记录大小为100 MB小于块大小128 MB。但是,第二个记录不能完全在一个块中,因此第二条记录将出现在两个块中,从块1开始,在块2中结束。
2. InputSplit
如果分配一个Mapper给块1,在这种情况下,Mapper不能处理第二条记录,因为块1中没有完整第二条记录。因为HDFS不知道文件块中的内容,它不知道记录会什么时候可能溢出到另一个块(becauseHDFS has no conception of what’s inside the fifile blocks, it can’t gauge when a record mightspill over into another block)。InputSplit这是解决这种跨越块边界的那些记录问题,Hadoop使用逻辑表示存储在文件块中的数据,称为输入拆分(InputSplit)。当MapReduce作业客户端计算InputSplit时,它会计算出块中第一个完整记录的开始位置和最后一个记录的结束位置。在最后一个记录不完整的情况下,InputSplit 包括下一个块的位置信息和完成该记录所需的数据的字节偏移(In cases where the last record in a block is incomplete, the input splitincludes location information for the next block and the byte offffset of the data needed tocomplete the record)。下图显示了数据块和InputSplit之间的关系:块是磁盘中的数据存储的物理块,其中InputSplit不是物理数据块。 它是一个Java类,指向块中的开始和结束位置。 因此,当Mapper尝试读取数据时,它清楚地知道从何处开始读取以及在哪里停止读取。InputSplit的开始位置可以在块中开始,在另一个块中结束。InputSplit代表了逻辑记录边界,在MapReduce执行期间,Hadoop扫描块并创建InputSplits,并且每个InputSplit将被分配给一个Mapper进行处理。
什么是combiner
在Hadoop中,有一种处理过程叫Combiner,与Mapper和Reducer在处于同等地位,但其执行的时间介于Mapper和Reducer之间,其实就是Mapper和Reducer的中间处理过程,Mapper的输出是Combiner的输入,Combiner的输出是Reducer的输入。例如获取历年的最高温度例子,以书中所说的1950年为例,在两个不同分区上的Mapper计算获得的结
果分别如下:
第一个Mapper结果:(1950, [0, 10, 20])
第二个Mapper结果:(1950, [25, 15])
如果不考虑Combiner,按照正常思路,这两个Mapper的结果将直接输入到Reducer中处理,如下所示:MaxTemperature:(1950, [0, 10, 20, 25, 15])最终获取的结果是25。
如果考虑Combiner,按照正常思路,这两个Mapper的结果将分别输入到两个不同的Combiner中处理,获得的结果分别如下所示:第一个Combiner结果:(1950, [20])第二个Combiner结果:(1950, [25])然后这两个Combiner的结果会输出到Reducer中处理,如下所示MaxTemperature:(1950, [20, 25])最终获取的结果是25。
由上可知:这两种方法的结果是一致的,使用Combiner最大的好处是节省网络传输的数据,这对于提高整体的效率是非常有帮助的。
但是,并非任何时候都可以使用Combiner处理机制,例如不是求历年的最高温度,而是求平均温度,则会有另一种结果。同样,过程如下,
如果不考虑Combiner,按照正常思路,这两个Mapper的结果将直接输入到Reducer中处理,如下所示:
AvgTemperature:(1950, [0, 10, 20, 25, 15])
最终获取的结果是14。
如果考虑Combiner,按照正常思路,这两个Mapper的结果将分别输入到两个不同的Combiner中处理,获得的结果分别如下所示:
第一个Combiner结果:(1950, [10])
第二个Combiner结果:(1950, [20])
然后这两个Combiner的结果会输出到Reducer中处理,如下所示
AvgTemperature:(1950, [10, 20])
最终获取的结果是15。
由上可知:这两种方法的结果是不一致的,所以在使用Combiner时,一定三思而后行,仔细思量其是否适合,否则可能造成不必要的麻烦。