MapReduce编程思想
MapReduce的程序分为两个阶段:Map阶段、Reduce阶段:
- Map阶段:在各个节点上计算自己节点的数据,并且将计算结果,保存到一个本地的文件中。
- Reduce阶段:将各个节点的结算结果汇总到一起。
Reduce阶段会将各个节点的计算结果汇总到一起,那么总得有一个节点来存储汇总之后的结果。将Map阶段产生的数据汇总到哪一台机器上?是由你在哪一个机器提交的任务来决定的。
MapReduce编程
wordcount的执行流程
combiner
在 不影响最终的结果的前提 下,可以在Map端进行一次小的合并操作,减少MapTask输出的文件的体积。
- 减小MapTask输出的文件体积,从而提高ReduceTask从不同节点拉取数据的数据量
- 减少ReduceTask阶段合并数据时候的次数
MapReduce核心理论
分片机制
Hadoop的数据是以块为单位进行存储的,以片为单位进行读取的!
块和片的区别:块是物理单位,片是逻辑单位!
片(FileSplit)在Hadoop的源码内,是一个类class。这个类中有一些属性,用来表示文件、起始位置、描述的数据量、数据有什么块,在什么节点上。
分片的时候会有1.1倍的溢出值。
默认的情况下,分片的大小与分块的大小是一致的。分片的逻辑是:
- 获取文件大小及位置信息。
- 判断文件是否可以分片(压缩格式有的是不支持分片的)。
- 获取分片的大小。(默认是块的大小)
- 剩余文件的大小 / 分片大小 > 1.1 的时候,循环执行封装分片信息的方法,将文件循环切片。
- 如果还有剩余的数据未分片,将其封装到一个分片中。
例子1:300M的文件切分:
- 300M / 128M > 1.1 => 第一个分片就是从0开始,长度128M
- 172M / 128M > 1.1 => 第二个分片就是从128M开始,长度是128M
- 44M / 128M <= 1.1 => 第三个分片就是从256M开始,长度是44M
例子2:260M的文件切分:
- 260M / 128M > 1.1 => 第一个分片就是从0开始,长度是128M
- 132M / 128M <= 1.1 => 第二个分片就是从128M开始,长度132M
因为有这样的溢出值的存在,可能会导致最后一个分片的数据,实际存储在两个块中。其实这里可能会发生移动数据。不过不用担心,小范围的数据移动是没有问题的。
为什么会有1.1倍的溢出值?
因为对于切分之后的小文件,没有必要启动一个MapTask单独处理数据。
分区机制
有时候我们需要将所有的数据,按照不同的分类,输出到不同的文件中。
文件的数量,是由ReduceTask来决定的,一个ReduceTask生成一个文件。
ReduceTask的数量是由分区数量来决定的,每一个ReduceTask处理一个分区的数据。
分区:其实就是我们为每一个MapTask输出的键值对,打上一个标签。在ReduceTask处理数据的时候,可以按照这个标签,处理数据。
分区器:其实就是一个类,为MapTask输出的键值对打上标签,可是打上什么标签?这类处理逻辑,是分区器。
MapReduce运行流程