23

グループ化コンパレータが mapreduce の二次ソートで使用される理由を知りたいです。

二次選別の決定的なガイドの例によると

キーのソート順を年順 (昇順) にしてから温度順 (降順) にします。

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

キーの年の部分で分割するようにパーティショナーを設定することで、同じ年のレコードが同じリデューサーに送られることを保証できます。ただし、これでも目標を達成するにはまだ十分ではありません。パーティショナーは、1 つのレデューサーだけが 1 年間のすべてのレコードを受け取ることを保証します。レデューサーがパーティション内のキーによってグループ化されるという事実は変わりません。

特定のレデューサーに送られるマップ出力キーを処理する独自のパーティショナーを既に作成しているので、なぜそれをグループ化する必要があるのでしょうか。

前もって感謝します

4

4 に答える 4

37

選択した回答を支持して、次を追加します。

この説明の続き

**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

Partitioner : キーが異なっていても、a-1 と a-2 キーを同じレデューサーにルーティングします。また、b-3 を別のレデューサーにルーティングします。

GroupComparator : レデューサーが取得する代わりに、複合キー\値がレデューサーに到着すると

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

上記は、合成後の一意のキー値が原因で発生します。

グループ コンパレータは、リデューサーが確実に取得するようにします。

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

グループ化された値のキーは、グループ内で最初に来るものになります。これは、キー コンパレータで制御できます。

**[[In a single reduce method call.]]**
于 2013-11-01T23:02:50.243 に答える
25

「...特定のリデューサーに向かうマップ出力キーに注意してください」というステートメントを改善させてください。

Reducer インスタンスと reduce メソッド: Reduce タスクごとに 1 つの JVM が作成され、それぞれに Reducer クラスのインスタンスが 1 つあります。これが Reducer インスタンスです (以降は Reducer と呼びます)。 reduce が呼び出されるたびに、「valuein」には、「グループ化コンパレーター」で定義したキーによってグループ化されたマップ出力値のリストがあります。デフォルトでは、グループ化コンパレーターはマップ出力キー全体を使用します。

例では地図出力キーを「年と気温」に変更してソートを実現しています。同じreduceメソッド呼び出しに行きます。

于 2013-02-07T05:53:07.580 に答える
2

年と気温の合成である中間キーを導入する必要があります。自然キー (年) で分割し、複合キー全体でソートするコンパレータを導入します。おっしゃる通り、年ごとに分割すると、同じレデューサーで 1 年のすべてのデータが取得されるため、コンパレーターは各年のデータを気温で効果的に並べ替えます。

于 2013-02-07T03:19:29.193 に答える
1

デフォルトのパーティショナーはキーのハッシュを計算し、同じハッシュ値を持つキーは同じレデューサーに送信されます。マッパーで複合 (ナチュラル + オーグメント) キーを発行し、同じ自然キーを持つキーを同じリデューサーに送信する場合は、カスタム パーティショナーを実装する必要があります。

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();
}

}

そして、データのパーティション内の関連するすべての行を単一のレデューサーに送信する場合は、自然キーのみを考慮するグループ化コンパレーターも実装する必要があります

public class SimpleGroupingComparator extends WritableComparator {

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


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

}

于 2014-06-19T23:49:41.967 に答える