これを知って驚くかもしれませんが、Iterableの値を繰り返すたびに、実際にはキー参照も更新されます。
protected void reduce(K key, Iterable<V> values, Context context) {
for (V value : values) {
// key object contents will update for each iteration of this loop
}
}
私はこれが新しいmapreduceAPIで機能することを知っていますが、古いmapredAPIではトレースしていません。
したがって、あなたの質問に答えると、すべてのキーが使用可能になり、最初のキーはグループの最初にソートされたキーに関連付けられます。
編集:これがどのようにそしてなぜ機能するかに関するいくつかの追加情報:
レデューサーがマップステージによって出力されたキー/値ペアを処理するために使用する2つのコンパレータがあります。
- キー順序付けコンパレーター-このコンパレーターが最初に適用され、すべてのKVペアを順序付けます。概念的には、この段階ではまだシリアル化されたバイトを処理しています。
- キーグループコンパレータ-このコンパレータは、前のキーと現在のキーがいつ「異なる」かを判断し、KVペアの1つのグループと別のグループの間の境界を示します。
内部的には、キーと値への参照は変更されません。Iterable.Iterator.next()を呼び出すたびに、基になるバイトストリーム内のポインターが次のKVペアに進みます。キーグルーパーが、現在のキーバイトのセットと前のセットが比較的同じキーであると判断した場合、値Iterable.iterator()のhasNextメソッドはtrueを返し、それ以外の場合はfalseを返します。trueが返された場合、バイトは、reduceメソッドで使用するためにKeyインスタンスとValueインスタンスに逆シリアル化されます。