9

レデューサーに膨大な数の値が含まれる可能性のある MapReduce ジョブを作成しています。これらすべての値が一度にメモリに読み込まれることを懸念しています。

値の基礎となる実装は、Iterable<VALUEIN> values必要に応じて値をメモリにロードしますか? Hadoop: The Definitive Guide は、これが事実であることを示唆しているようですが、「決定的な」答えは示していません。

レデューサーの出力は値の入力よりもはるかに大きくなりますが、出力は必要に応じてディスクに書き込まれると思います。

4

3 に答える 3

15

あなたは本を正しく読んでいます。レデューサーはすべての値をメモリに格納するわけではありません。代わりに、Iterable 値リストをループすると、各 Object インスタンスが再利用されるため、一度に 1 つのインスタンスだけが維持されます。

たとえば、次のコードでは、objs ArrayList はループ後に予想されるサイズになりますが、すべての要素は同じになります。b/c Text val インスタンスは反復ごとに再利用されます。

public static class ReducerExample extends Reducer<Text, Text, Text, Text> {
public void reduce(Text key, Iterable<Text> values, Context context) {
    ArrayList<Text> objs = new ArrayList<Text>();
            for (Text val : values){
                    objs.add(val);
            }
    }
}

(何らかの理由で各 val に対してさらにアクションを実行したい場合は、ディープ コピーを作成してから保存する必要があります。)

もちろん、単一の値でもメモリよりも大きくなる可能性があります。この場合、開発者は、値がそれほど大きくならないように、前の Mapper でデータを切り詰める手順を実行することをお勧めします。

更新: Hadoop The Definitive Guide 2nd Edition の 199 ~ 200 ページを参照してください。

This code snippet makes it clear that the same key and value objects are used on each 
invocation of the map() method -- only their contents are changed (by the reader's 
next() method). This can be a surprise to users, who might expect keys and vales to be 
immutable. This causes prolems when a reference to a key or value object is retained 
outside the map() method, as its value can change without warning. If you need to do 
this, make a copy of the object you want to hold on to. For example, for a Text object, 
you can use its copy constructor: new Text(value).

The situation is similar with reducers. In this case, the value object in the reducer's 
iterator are reused, so you need to copy any that you need to retain between calls to 
the iterator.
于 2012-06-13T23:28:01.910 に答える
2

完全にメモリ内にあるわけではありません。一部はディスクから取得されます。コードを見ると、フレームワークが Iterable をセグメントに分割し、ディスクからメモリに 1 つずつロードしているように見えます。

org.apache.hadoop.mapreduce.task.ReduceContextImpl org.apache.hadoop.mapred.BackupStore

于 2014-09-12T16:59:22.017 に答える
0

他のユーザーが引用したように、データ全体がメモリにロードされませんでした。Apacheドキュメント リンクからいくつかの mapred-site.xml パラメータを見てください。

mapreduce.reduce.merge.inmem.threshold

デフォルト値: 1000。これは、メモリ内マージ プロセスのファイル数に関するしきい値です。

mapreduce.reduce.shuffle.merge.percent

デフォルト値は 0.66 です。インメモリ マージが開始される使用量のしきい値。 で定義されているように、インメモリ マップ出力の保存に割り当てられた合計メモリのパーセンテージとして表されmapreduce.reduce.shuffle.input.buffer.percentます。

mapreduce.reduce.shuffle.input.buffer.percent

デフォルト値は 0.70 です。シャッフル中に最大ヒープ サイズからマップ出力の格納に割り当てられるメモリの割合。

mapreduce.reduce.input.buffer.percent

デフォルト値は 0 です。削減中にマップ出力を保持するための、最大ヒープ サイズに対するメモリの割合。シャッフルが終了すると、メモリ内の残りのマップ出力は、削減を開始する前に、このしきい値を下回る量を消費する必要があります。

mapreduce.reduce.shuffle.memory.limit.percent

デフォルト値: 0.25。1 回のシャッフルで消費できるメモリ内制限の最大割合

于 2016-01-21T18:36:30.920 に答える