分布式计算框架 / MapReduce
核心思想
• 分而治之,并行计算
• 移动计算,而非移动数据
Split
• 输入数据被划分成等长的小数据块,称为输入切片(Input Split),简称切片
• Split是逻辑概念,仅包含元数据信息,如:数据的起始位置、长度、所在节点等
• 每个Split交给一个Map任务处理,Split的数量决定Map任务的数量
• Split的大小默认等于Block大小
Map阶段
• 由若干Map任务组成,任务数量由Split数量决定
• 输入:Split切片(key-value),输出:中间计算结果(key-value)
一般来说一个map任务启动一个线程
在实际情况下,map任务的个数是受多个条件的制约,一般一个DataNode的map任务数量控制在10到100比较合适。
控制Map任务的个数:
1、增加map个数,可增大mapred.map.tasks
2、减少map个数,可增大mapred.min.split.size
如果要减少map个数,但有很多小文件,可将小文件合并成大文件,再使用准则2
Reduce阶段
• 由若干Reduce任务组成,任务数量由程序指定
• 输入:Map阶段输出的中间结果(key-value),输出:最终结果(key-value)
reduce任务数并不像map任务数那样受多个因素的制约,hadoop提供了修改reducer任务的数量,最大72
调整方式有二:
1)mapred.reduce.tasks
2)Java代码中job.setNumReduceTasks(int n)二、一个mapreduce作业中,一下三者的数量是相等的。
1)partitioner的数量
2)reduce任务的数量
3)最终输出文件的数量
Shuffle阶段
-
负责执行Partition(分区)、Sort(排序)、Spill(溢写)、 Merge(合并)、抓取(Fetch)等工作
-
Partition决定了Map任务输出的每条数据放入哪个分区,交给哪个Reduce任务处理
-
Reduce任务的数量决定了Partition数量
-
Partition编号 = Reduce任务编号 =“key hashcode % reduce task number”
-
避免和减少Shuffle是MapReduce程序调优的重点
Shuffle详解
Map端
- Map任务将中间结果写入专用内存缓冲区Buffer(默认100M),同时进行Partition和Sort(先按“key hashcode % reduce task number”对数据进行分区,分区内再按key排序)
- 当Buffer的数据量达到阈值(默认80%)时,将数据溢写(Spill)到磁盘的一个临时文件中,文件内数据先分区后排序
- Map任务结束前,将多个临时文件合并(Merge)为一个Map输出文件,文件内数据先分区后排序
Reduce端
- Reduce任务从多个Map输出文件中主动抓取(Fetch)属于自己的分区数据,先写入Buffer,数据量达到阈值后,溢写到磁盘的一个临时文件中
- 数据抓取完成后,将多个临时文件合并为一个Reduce输入文件,文件内数据按key排序
MapReduce 作业运行模式
1.0 JobTracker TaskTracker
2.0 YARN