Hadoop 首先运行的是什么:分区器还是合并器?

Hadoop 首先运行的是什么:分区器还是合并器?,hadoop,Hadoop,我想知道分区器和合并器之间,哪个先运行 我认为首先是partitiner,然后是combiner,然后键被重定向到不同的reducer,看起来像partitiner,所以我很困惑。 请帮助我理解。组合器在partitioner之前运行 合并器在映射之后运行,以减少映射输出的项目计数。从而减少了网络过载。减少partitioner之后的运行次数您的问题的直接答案是=>COMBINER 详情: 合路器在map阶段可视为小型减速器。在进一步分发之前,它们会对映射器结果执行局部缩减。一旦组合器功能被执行

我想知道分区器和合并器之间,哪个先运行

我认为首先是partitiner,然后是combiner,然后键被重定向到不同的reducer,看起来像partitiner,所以我很困惑。
请帮助我理解。

组合器在partitioner之前运行


合并器在映射之后运行,以减少映射输出的项目计数。从而减少了网络过载。减少partitioner之后的运行次数

您的问题的直接答案是=>COMBINER

详情: 合路器在map阶段可视为小型减速器。在进一步分发之前,它们会对映射器结果执行局部缩减。一旦组合器功能被执行,它就被传递给减速器进行进一步的工作

何处为

当我们在一个以上的减速器上工作时,分割器出现在画面中。因此,分区程序决定哪个减速机负责特定的密钥。他们基本上获取映射器结果(如果使用了合并器,则返回合并器结果)并根据密钥将其发送给负责的还原器

为了更好地理解,您可以参考下面的图片,这是我从Hadoop上的Yahoo开发者教程中获取的。
(来源:)

下面是分区优先的部分

根据“Hadoop,权威指南”,映射器的输出首先写入内存缓冲区,然后在缓冲区即将溢出时溢出到本地目录。溢出数据根据分区器进行划分,如果给定合并器,则在每个分区中对结果进行排序和组合

您只需修改wordcount MR程序即可进行验证。我的结果是: (“敏捷的棕色狐狸跳过了一只懒狗”)


单词、步骤、时间

福克斯,地图绘制者,**********754

福克斯,分居者,*************754

福克斯,组合机,**********850

福克斯,减速器,**********904



显然,合并器在分区器之后运行。

合并器是一个映射侧减速机。这意味着减速机执行合路器所做的一切。组合器的主要用途是调整/优化性能。组合器优化代码后,请求器分离并协助获得多个输出。合并器是可选的,但对于大文件,强烈建议使用

分区器根据减速机的数量划分数据,并取决于输出的需求。 例如:输出公端、母端,使用分割器分离2个输出


第一个合并器将出现,然后分区器将出现,两者都只出现在映射侧,但不出现在减速机侧

Mapper->Combiner->Partitionar->Reducer

在Hadoop-权威指南第三版第209页中,我们有以下文字:

在写入磁盘之前,线程首先将数据划分为与最终将发送到的还原器相对应的分区。在每个分区内,后台线程执行内存中的按键排序,如果有合并器函数,则在排序的输出上运行。运行combiner函数可以实现更紧凑的映射输出,因此要写入本地磁盘和传输到reducer的数据更少

每次内存缓冲区达到溢出阈值时,都会创建一个新的溢出文件,因此在映射任务写入其最后一条输出记录后,可能会有几个溢出文件。在任务完成之前,溢出文件将合并到单个分区和排序的输出文件中。配置属性io.sort.factor控制一次合并的最大流数;默认值为10

如果至少有三个溢出文件(由min.num.spips.for.combine属性设置),则在写入输出文件之前,将再次运行合并器。回想一下,组合器可以在输入端重复运行,而不会影响最终结果。如果只有一个或两个溢出,映射输出大小的潜在减少不值得调用合并器的开销,因此不会再次为此映射输出运行合并器。因此,合并溢出文件期间会运行合并器

因此,答案似乎是:

映射->分区->排序->合并器->溢出->合并器(如果溢出>=3)->合并

但是,在以下文字中:

映射器输出被排序,然后按减速机进行分区

内容与最终指南不同。答案似乎是:

映射->排序->组合器->分区器->溢出->组合器(如果溢出>=3)->合并


哪一个是正确的?我倾向于接受Apache教程中的后一个,但不太确定。

Combiner不会更改输出映射任务的键值对。它基于相同的键进行组合,并发出相同的键/列表值对

Partitioner从map/combiner(如果存在)获取输入,然后对数据进行分段,并在过程中发出新的K列表值对


因此,映射-->合并->分区-->减少。

分区器
在组合器之前运行

您可以使用自定义分区逻辑,在对映射器结果进行分区后,对分区进行排序,并将
Combiner
应用于已排序的分区

我通过运行一个带有自定义
Combiner
和带有时间戳日志的
Partitioner
的字数计算程序来检查它:

Apr 23, 2018 2:41:22 PM mapreduce.WordCountPartitioner getPartition
INFO: Partitioner: 1524483682580 : hello : 1
Apr 23, 2018 2:41:22 PM mapreduce.WordCountPartitioner getPartition
INFO: Partitioner: 1524483682582 : hello : 1
Apr 23, 2018 2:41:22 PM mapreduce.WordCountPartitioner getPartition
INFO: Partitioner: 1524483682583 : hello : 1
Apr 23, 2018 2:41:22 PM mapreduce.WordCountPartitioner getPartition
INFO: Partitioner: 1524483682583 : world : 1
Apr 23, 2018 2:41:22 PM mapreduce.WordCountPartitioner getPartition
INFO: Partitioner: 1524483682584 : world : 1
Apr 23, 2018 2:41:22 PM mapreduce.WordCountPartitioner getPartition
INFO: Partitioner: 1524483682585 : hello : 1
Apr 23, 2018 2:41:22 PM mapreduce.WordCountPartitioner getPartition
INFO: Partitioner: 1524483682585 : world : 1
18/04/23 14:41:22 INFO mapred.LocalJobRunner: 
18/04/23 14:41:22 INFO mapred.MapTask: Starting flush of map output
18/04/23 14:41:22 INFO mapred.MapTask: Spilling map output
18/04/23 14:41:22 INFO mapred.MapTask: bufstart = 0; bufend = 107; bufvoid = 104857600
18/04/23 14:41:22 INFO mapred.MapTask: kvstart = 26214396(104857584); kvend = 26214368(104857472); length = 29/6553600
Apr 23, 2018 2:41:22 PM mapreduce.WordCountCombiner reduce
INFO: Combiner: 1524483682614 : hello 
Apr 23, 2018 2:41:22 PM mapreduce.WordCountCombiner reduce
INFO: Combiner: 1524483682615 : world

毕竟,对可能永远无法到达reducer的数据进行分区是没有用的。JFYI:但是有一个问题:Combiner也可能在reducer端运行。中间输出被复制到reducer的JVM内存中。当内存缓冲区达到阈值大小时,intrim输出被合并并溢出到磁盘。如果指定了合并器,它将在合并期间运行,以减少写入磁盘的数据量。我注意到你们中的一些人参考了Yahoo的教程。然而,这张图表有误导性。你可以在这里核对答案。这个