web-dev-qa-db-ja.com

hadoop map reduceでのグループ化コンパレーターの使用とは

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

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

キーの並べ替え順序を年(昇順)、次に気温(降順)にする必要があります。

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

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

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

前もって感謝します

23
Pramod

選択した回答をサポートするために、私は追加します:

続く この説明

**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.]]**
36
jakstack

「...特定のレデューサーに行くマップ出力キーに注意してください」という文を改善させてください。

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

この例では、マップ出力キーを「年と気温」に変更して並べ替えを実現しています。マップ出力キーの「年」部分のみを使用するグループ化コンパレータを定義しない限り、同じ年のすべてのレコードを作成することはできません同じreduceメソッド呼び出しに移動します。

24

年と気温を組み合わせた中間キーを導入する必要があります。自然キー(年)でパーティション分割し、複合キー全体でソートするコンパレータを導入します。その年に分割することで、同じレデューサーで1年のすべてのデータを取得できるので、コンパレーターは各年のデータを温度で効率的にソートします。

2
Mike DeLong

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

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

}

1
Sambit Tripathy