背景
看了网上的教程,很多用的是这个WordCount的图,我无力吐槽,并不是说这个图不对,只是觉得站在新手的角度上来说:
- 最核心的Shuffle过程,这个图没有讲。
- Reduce过程有4个,容易让新手以为Reduce的数量和单词有关。
分析:
下面的图更细致一些,但是还是有对新手不了解的地方,我用最平实的语言来叙述。
还是统计单词,例如统计《莎士比亚全集》。
第一阶段 split: 假设这个文件太大了,有400MB,首先做切片,因为是存储在HDFS上的,所以可以默认分成4块(默认每块是128M),就像图中的split 0 - 3,虽然这4个分片的物理位置分布在多个HDFS节点上,但我们不需要关心(交给框架)。
第二阶段 map: 就是把单词转换成 Key,Value对,例如单词 Apple —> (Apple,1),这里的1代表这个单词出现了1次,因为我们要做的事是统计单词出现次数
第三阶段 partition:
需要注意的是,分区的数量等于Reduce的数量,而 Reduce的数量是我们自己来选择的,这里假设我们设置了三个。演示一下第一个分片的处理过程 即 map 0 任务。
假设我们输入的键值对是这些单词,首先 根据key计算hash值,这里hash值我随便写的。然后根据hash值对分区数取模,因为我们分区的数量是3,所以对3取模,可以得到这个键值对应该放到哪个分区。
放到分区里就是(对应刚才带红绿蓝颜色的图):
第四阶段 sort:
对分区内进行排序,分区之间不排序。这里对各个分区内的单词排序后就是:
第四阶段 spill:
这个阶段是溢写。因为我们刚才分区的操作在内存缓冲区中完成,万一我们处理的数据量很大,超过了某个阀值(默认80%),那么就要写入硬盘了。这里我们假设处理的数据量不大(这里我展示只有6个单词),不需要落盘。
第五阶段 merge:
因为刚才图里面,0,1,2号分区都好像是连续的,这只是为了展示方便而已,真实情况是分区所在的物理位置并不在一起,而是要通过Merge合并成图中连续的样子。
第六阶段 fetch:
到这里就进入了Reduce阶段,把刚才4个map任务的输出取到Reduce任务中当输入。具体怎么取呢,就是根据分区号对应Reduce任务号!,也就是 4个Map 任务中的 分区 0 应该输送到 Reduce 0 任务中,分区 1 输送到 Reduce 1 中。再看一下这个带颜色的图,更清晰
第七阶段 merge sort:
合并完了还要排序,因为4个Map任务的 0号分区内部是有序的,但4个0号分区之间,是无序的。很明显这种特征可以用归并排序。例如第一个Reduce任务merge srot的结果是(上图中红色的merge):
这里出现了其他单词,他们来自于其他3个map任务的 0号分区。
第八阶段 reduce:
有了刚才的结果,就可以根据key进行统计了,相信到了这里就不难理解了,统计完还要生成多个result文件存储起来。
总结:
感觉泛泛而谈对新手来说是最致命的,因为细节是最重要的,最核心的Shuffle过程,也就是分区排序了,理解了就真正明白了它的原理。