あなたは正しく本を読んでいます。レジューサーは、すべての値をメモリーに格納しません。代わりに、Iterable値リストをループするとき、各Objectインスタンスは再利用されるので、特定の時刻に1つのインスタンスを保持します。
たとえば、次のコードでは、objs ArrayListはループの後に予想されるサイズを持ちますが、すべての要素は同じb/cであり、テキスト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);
}
}
}
(何らかの理由であなたが各ヴァルにさらなる行動を取るようにしたいなかった場合、あなたは深いコピーを作成し、それを保存する必要があります。)もちろん
も、単一の値がメモリよりも大きくなる可能性があり。この場合、開発者は前のMapperでデータをpareしてその値がそれほど大きくないようにすることを推奨します。
更新:Hadoop The Definitive Guide第2版の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.
あなたの答えは混乱しています。まず、「減速機はすべての値をメモリに格納しません」ということは、Iterableが必要に応じて値をロードすることを意味します。後で、「値リストのインスタンスが1つでもメモリよりも大きくなる可能性があります」ということは、値リストが最初にメモリに読み込まれることを意味します。あなたは明確にしていただけますか? – Zach
編集して明確にします。私はちょうど単一の価値が大きいかもしれないことを意味しました。これは起こりそうもない。 「減速機はすべての値を記憶していません」というのは真実です。それは理にかなっていますか? –
はい。説明をありがとうございます。あなたはこれを参考にしていますか? – Zach