2

基本的に次のようなことをしたいという問題があります。

    public void reduce(Text key, Iterable<Text> iterValues, Context context){

           for (Text val : iterValues){
               //do something
           }

           iterValues.reset()
           for (Text val : iterValues){
               //do something else
           }
}

これらの状況を回避するか、単にオブジェクトをメモリ内でインスタンス化するのが最善であることはわかっていますが、メモリに保持するものが多すぎて、これを分割すると構造的にはるかに複雑になる可能性があるという問題があります。さらにステップを減らします。

この機能を探しているのは私だけではないようです。実際、これは少し前に実装された機能のようです: https://issues.apache.org/jira/browse/HADOOP-5266

MarkableIterator クラスはまさに私が探しているもののようです: http://hadoop.apache.org/docs/current/api/org/apache/hadoop/mapreduce/MarkableIterator.html

ただし、hadoop 2.0.3-alpha でのみ使用できるようです。1.0.3 (現在使用しているもの) または 0.20.205 のみをサポートする EMR でこれを実行しようとしています。いろいろ試してみましたが、1.0.3 で同様の機能を提供するものは見つかりませんでした。最も近いのは、StreamBackedIterator を使用することです。これは、オブジェクトをメモリに蓄積しますが、ArrayList よりもメモリ効率が高いようです。

Hadoop 1.0.3 でこれを行う方法を知っている人はいますか?

4

1 に答える 1

1

これはちょっとしたハックですが、マッパーにすべての値を2回出力させることができますが、一方にフラグを設定し、もう一方にはフラグを設定しません。次に、最初にそのフラグに基づいて値を並べ替え、次に必要な自然順序に基づいて値を並べ替えます。次に、2番目の値のセットに到達したら、最初のループを停止するためにいくつかのカスタムロジックを実行する必要があります。

それ以外は、いいえ、単に自分でメモリに保存せずにこれを行う簡単な方法はわかりません。主な問題は、イテレータが実際には新しいオブジェクトを返さず、同じオブジェクトを返すが、への呼び出し間で変化することnext()です。舞台裏では、Hadoopが値のセット全体をキャッシュすることすらできない可能性があるため、イテレーターをリセットするには、ファイルを再スキャンする必要があります(新しいバージョンで実行していると思います)。

于 2013-03-07T01:25:55.777 に答える