Hadoop MapReduce中的随机播放阶段
在MapReduce作业中,当Map任务开始产生输出时,输出将按键排序,并且Map输出也将传输到运行reducer的节点。这整个过程在Hadoop MapReduce中被称为洗牌阶段(shuffle phase)。
尽管shuffle阶段是Hadoop框架的内部功能,但是有几个配置参数可以控制它。此调整有助于有效地运行MapReduce作业。在这篇文章中,我们将看到在mapper和reducer端进行排序和改组时会发生什么。
在Map端进行打乱和排序
当映射任务开始产生输出时,首先将其写入默认为100 MB的内存缓冲区。使用mapred-site.xml中的mapreduce.task.io.sort.mb参数进行配置。
当内存缓冲区达到某个阈值时,只有映射输出会溢出到磁盘。它的配置参数是mapreduce.map.sort.spill.percent,默认情况下为分配的内存缓冲区大小的80%。一旦达到此阈值,线程将开始在后台将内容溢出到磁盘。
在将映射输出写入磁盘之前,需要执行以下操作:
- 输出根据减速器的数量划分为多个分区。例如,如果有4个reducer,则每个映射输出都分为4个分区。一个分区可以具有多个密钥的数据,但是任何特定密钥的数据都位于单个分区中。如果有10个运行的映射器,则将每个映射器的输出划分为4个分区,然后将具有类似键类型的分区转移到reducer。
- 在每个分区中,数据也按键排序。
- 如果定义了一个合并器,则该合并器也将执行。
每次缓冲存储器达到阈值时,都会创建一个新的溢出文件,并执行上述操作。最后,在映射任务完成之前,所有溢出到磁盘的文件都合并在一起以创建一个文件,同时仍然遵守分区边界和每个分区中键的排序。
Reduce端洗牌
将Map输出写入运行Map任务的节点的本地磁盘后,分区将转移到reducer。每个化简器将从所有映射器获取其特定分区的数据。
例如,如果有4个映射任务和2个reducer,则所有这4个map的输出将分为2个分区,每个reducer一个。
传输分区数据
映射任务完成并通知ApplicationMaster后,reduce任务将开始复制该特定映射的数据。它不会等待所有正在运行的Map任务完成。 Reducer使用线程并行复制映射输出。运行多少个线程是可配置的,并且相同的参数是" mapreduce.reduce.shuffle.parallelcopies"。在复制(随机)阶段,由reduce运行的并行传输的默认数量为5.
在reduce方面,数据也会保留在内存缓冲区中,如果它适合内存本身,则有助于reduce任务更快地执行。使用" mapreduce.reduce.shuffle.input.buffer.percent"参数配置内存缓冲区的大小。它表示在随机播放期间从最大堆大小分配到存储映射输出的内存百分比。默认值为70%。
如果数据不足以容纳内存,则会将其溢出到磁盘上。使用以下2个配置参数设置的阈值-
mapreduce.reduce.merge.inmem.threshold –阈值,以内存中合并过程的文件数表示。当我们累积文件的阈值数量时,我们将启动内存中合并并溢出到磁盘。默认文件数为1000。
mapreduce.reduce.shuffle.merge.percent –初始化内存合并的使用阈值,表示为分配给存储内存映射输出的总内存的百分比,由mapreduce.reduce.shuffle定义。 input.buffer.percent。
一旦复制并合并了所有映射器的数据,就创建了一个排序文件(所有映射器的分区,按键排序),该文件成为化简任务的输入。