hadoop map reduce中分组比较器有啥用

Posted

技术标签:

【中文标题】hadoop map reduce中分组比较器有啥用【英文标题】:What is the use of grouping comparator in hadoop map reducehadoop map reduce中分组比较器有什么用 【发布时间】:2013-02-06 11:54:53 【问题描述】:

我想知道为什么在 mapreduce 的二级排序中使用分组比较器。

根据二次排序的权威指南示例

我们希望键的排序顺序是按年份(升序)然后按 温度(下降):

1900 35°C
1900 34°C
1900 34°C
...
1901 36°C
1901 35°C

通过设置一个partitioner来按key的year部分进行分区,我们可以保证 同一年的记录转到同一个减速器。这仍然不足以实现我们的 然而目标。分区器确保只有一个 reducer 接收所有记录 一年;它不会改变 reducer 在分区内按 key 分组的事实。

既然我们已经编写了自己的分区器来处理映射输出键到特定的reducer,那么我们为什么要对它进行分组。

提前致谢

【问题讨论】:

【参考方案1】:

为了支持我选择的答案,我添加:

继续this explanation

**Input**:

    symbol time price
    a      1    10
    a      2    20
    b      3    30

**Map output**: create composite key\values like so:

> symbol-time time-price
>
>**a-1**         1-10
>
>**a-2**         2-20
>
>**b-3**         3-30

分区器:将 a-1 和 a-2 键路由到同一个 reducer,尽管键不同。它还将 b-3 路由到单独的减速器。

GroupComparator:一旦复合键\值到达reducer而不是reducer得到

>(**a-1**,1-10)
>
>(**a-2**,2-20)

由于组合后的唯一键值,会发生上述情况。

组比较器将确保 reducer 获得:

(a-1,**1-10,2-20**)

分组值的键将是组中的第一个。这可以通过 Key 比较器来控制。

**[[In a single reduce method call.]]**

【讨论】:

我的 map reduce 工作没有使用我的分组比较器,它使用的是复合键的比较方法。分组知道为什么会这样吗?【参考方案2】:

让我改进一下语句“...照顾到特定 reducer 的映射输出键”。

Reducer 实例与 reduce 方法: 每个 Reduce 任务创建一个 JVM,每个都有一个 Reducer 类的实例。这是 Reducer 实例(我从现在开始称它为 Reducer)。在每个 Reducer 中,根据“键分组”多次调用 reduce 方法。每次调用 reduce 时,'valuein' 都有一个 map 输出值列表,这些值按您在 'grouping comparison' 中定义的键分组。默认情况下,分组比较器使用整个 map 输出键。

在示例中,map output key 改为 'year and temperature' 来实现排序。除非你定义一个分组比较器,只使用 map output key 的'year'部分,否则你不能做所有的记录同年去同一个reduce方法调用。

【讨论】:

你能用手头的场景来解释你的答案吗,举一个关于字数的更简单的例子。我正在寻找的是整个工作的系统级功能。还有一个疑问:我们能否将传递给单个减速器的键分组在某个参数上让我们说这种情况:从 2013 年传递给减速器的数据开始的所有星期天的温度【参考方案3】:

您需要引入一个由年份和温度组合而成的中间键;对自然键(年份)进行分区并引入一个比较器,该比较器将对整个复合键进行排序。没错,通过按年份进行分区,您将在同一个减速器中获得一年的所有数据,因此比较器将有效地按温度对每年的数据进行排序。

【讨论】:

【参考方案4】:

默认的 partitioner 计算 key 的 hash,那些 hash 值相同的 key 会被发送到同一个 reducer。如果您的映射器中有一个复合(自然+增强)键,并且如果您想将具有相同自然键的键发送到同一个减速器,那么您必须实现一个自定义分区器。

public class SimplePartitioner implements Partitioner 
@Override
public int getPartition(Text compositeKey, LongWritable value, int numReduceTasks) 
    //Split the key into natural and augment
    String naturalKey = compositeKey.toString().split("separator")


    return naturalKey.hashCode();

现在,如果您希望数据分区中的所有相关行都发送到单个 reducer,您还必须实现一个仅考虑自然键的分组比较器

public class SimpleGroupingComparator extends WritableComparator 

@Override
public int compare(Text compositeKey1, Text compositeKey2) 


return compare(compositeKey1.getNaturalKey(),compositeKey2.getNaturalKey());

【讨论】:

以上是关于hadoop map reduce中分组比较器有啥用的主要内容,如果未能解决你的问题,请参考以下文章

Hadoop Mapreduce分区分组二次排序

hadoop离线day06--Hadoop MapReduceHDFS高阶

hadoop离线day06--Hadoop MapReduceHDFS高阶

hadoop-初学者写map-reduce程序中容易出现的问题 3

如何确定 Hadoop map和reduce的个数

mapreduce 分区和分组的区别