21

谁能解释一下 hadoop 中的二次排序是如何工作的?
为什么必须使用GroupingComparator它以及它如何在 hadoop 中工作?

我正在浏览下面给出的链接,并对 groupcomapator 的工作方式产生疑问。
谁能解释一下分组比较器的工作原理?

http://www.bigdataspeak.com/2013/02/hadoop-how-to-do-secondary-sort-on_25.html

4

5 回答 5

48

我发现借助图表很容易理解某些概念,这当然是其中之一。

假设我们的二级排序是在由姓氏和名字组成的复合键上进行的。

复合键

排除了复合键,现在让我们看看二级排序机制

二次排序步骤

分区器和组比较器仅使用自然键,分区器使用它将具有相同自然键的所有记录引导到单个减速器。这种分区发生在 Map 阶段,来自各种 Map 任务的数据由 reducer 接收,并在其中分组,然后发送到 reduce 方法。这种分组是组比较器出现的地方,如果我们没有指定自定义组比较器,那么 Hadoop 将使用默认实现,该实现会考虑整个复合键,这将导致不正确的结果。

MR 步骤概述

在此处输入图像描述

于 2014-04-15T08:30:27.230 回答
16

分组比较器

一旦数据到达reducer,所有数据都按key分组。由于我们有一个复合键,我们需要确保记录仅按自然键分组。这是通过编写自定义 GroupPartitioner 来完成的。我们有一个 Comparator 对象,仅考虑 TemperaturePair 类的 yearMonth 字段,以便将记录分组在一起。

public class YearMonthGroupingComparator extends WritableComparator {

    public YearMonthGroupingComparator() {
        super(TemperaturePair.class, true);
    }

    @Override
    public int compare(WritableComparable tp1, WritableComparable tp2) {
        TemperaturePair temperaturePair = (TemperaturePair) tp1;
        TemperaturePair temperaturePair2 = (TemperaturePair) tp2;
        return temperaturePair.getYearMonth().compareTo(temperaturePair2.getYearMonth());
    }
}

以下是运行我们的二级排序作业的结果:

new-host-2:sbin bbejeck$ hdfs dfs -cat secondary-sort/part-r-00000

190101 -206

190102 -333

190103 -272

190104 -61

190105 -33

190106 44

190107 72

190108 44

190109 17

190110 -33

190111 -217

190112 -300

虽然按值对数据进行排序可能不是常见的需求,但它是一个在需要时可以放在后兜里的好工具。此外,通过使用自定义分区器和组分区器,我们能够更深入地了解 Hadoop 的内部工作原理。另请参阅此链接.. hadoop map reduce中分组比较器的用途是什么

于 2013-08-23T06:28:16.437 回答
16

这是分组的示例。考虑一个复合键(a, b)及其值v。让我们假设在排序之后,您最终得到以下一组(键,值)对:

(a1, b11) -> v1
(a1, b12) -> v2
(a1, b13) -> v3

使用默认的组比较器,框架将reduce使用各自的 (key, value) 对调用该函数 3 次,因为所有的键都是不同的。但是,如果您提供自己的自定义组比较器,并将其定义为仅依赖于a, 忽略b,那么框架会得出结论,该组中的所有键都是相等的,并且仅使用以下键和列表调用 reduce 函数一次价值观:

(a1, b11) -> <v1, v2, v3> 

请注意,仅使用了第一个复合键,并且 b12 和 b13 是“丢失的”,即没有传递给 reducer。

在“Hadoop”书中著名的示例中,按年份计算最高温度,a是年份,并且b's 是按降序排序的温度,因此 b11 是所需的最高温度,您不必关心其他b's。reduce 函数只是将接收到的 (a1, b11) 写入该年的解决方案。

在您来自“bigdataspeak.com”的示例b中,reducer 中需要 all ,但它们可以作为相应值 (objects) 的一部分使用v

这样,通过在键中包含您的值或其部分,您可以使用 Hadoop 不仅对您的键进行排序,而且对您的值进行排序。

希望这可以帮助。

于 2013-10-20T07:09:00.067 回答
1

分区器只是确保一个reducer 接收属于一个键的所有记录,但它不会改变reducer 在分区内按键分组的事实。

在二级排序的情况下,我们形成复合键,如果我们让默认行为继续分组逻辑,则会认为键是不同的。

所以我们需要控制分组。因此,我们必须向框架指示基于密钥的自然部分而不是复合密钥进行分组。因此分组比较器必须用于相同的。

于 2017-11-23T13:16:31.593 回答
0

上面提到的例子有很好的解释,让我简化一下。我们需要执行三个主要步骤。

  1. 映射应该是(键+值,值)
  2. 当我们加入 Key&Value。我们仍然需要对原始键和值进行排序的机制。所以我们将添加一个自定义比较器。
  3. 现在数据按原始键排序,但是如果我们将此数据发送到减速器,它不能保证将给定键的所有值都发送到一个减速器,因为我们使用键+值作为键。为了确保它,我们将添加组比较器。
于 2014-09-12T08:17:50.877 回答