2012-02-29 3 views
1

私は現在、論文を読んでいますが、ライターたちは、すべてのマップタスクのメモリにいくつかの配列があり、マップタスクが終了すると、その配列を出力すると言っています。Hadoop:マップ関数のメモリ構造を持ち、それらを集約することは可能ですか?

この私が参照していた紙さ:http://research.google.com/pubs/pub36296.html

これはやや行うにはビット非のMapReduceのものに見えるが、私はこのプロジェクトを実装しようとしていると私がポイントになってきたが、これはあるし、唯一の解決策です。私は共通のマップを使用する多くの方法を試しています。これは、各行を処理し、キーと値のペアを出力しますが、そのようにして、私は入力のあらゆる行に対して、何千ものコンテキスト書き込みを行い、それら。だから私の地図の仕事はボトルネックです。これらのコンテキスト書き込みはコストがかかる。

もし私がそれを行うなら、私はキーと値のペアの数を劇的に減らすことができます。だから私はすべてのマップタスクのメモリ構造を持つ方法を見つける必要があります。 私はこれらの構造をセットアップ機能で静的なものとして定義できますが、マップタスクが終了したときにその構造を出力できるようにする方法を見つけることができます。私はちょっと変わったと思っていますが、効率的に働く唯一の方法です。

これは起動時に、彼らはその紙に言う

で、各マッパーは それぞれ注文した属性のために考慮すべき分割点の集合をロードします。各ノードn∈N と属性Xについて、マッパーはキーのテーブルTn、Xを保持します。 値のペア。

:、 プットフォームのキーN、Xおよび値v OUT-マッパーをすべての入力データを処理した後

、Tnは、X [V]ここで

は、いくつかの編集はショーンの答えの後にあります

私は自分の仕事でコンバイナーを使用しています。実際には、マップ関数内のこれらのcontext.write(Text、Text)コマンドは本当に時間がかかります。私の入力はcsvファイルまたはarffファイルです。すべての行に例があります。私の例には、何千もの属性があるかもしれません。私はすべての属性のために、<(n、X、u)、Y>の形のキーと値のペアを出力しています。ここで、はノードの名前(私は決定木を構築しています)、Xは属性の名前、 uは属性の値、Yはテキスト形式の統計値です。私が100,000の属性を持っているなら、すべての例について100,000のcontext.write(Text、Text)コマンドを持つ必要があります。これらのコマンドを使わずにマップタスクを実行すると、風のように動作します。私はcontext.writeコマンドを追加すると、それは永遠にかかる。 2,000,000の属性トレーニングセットでさえも。私は実際にファイルで書いているのであって、記憶ではないようです。だから私は本当にそれらの書き込みを減らす必要があります。それらをメモリに集約する必要があります(マップ関数ではなくコンバイナで)。

答えて

1

異なる答えを追加します。マップタスクが終了したときに、よく、あなたがclose()を上書きすることができます知っている

。これがあなたが望むものなのかどうかわかりません。 50のマッパーを使用している場合、それぞれの入力の50分の1がわかっていないか保証されていません。それはあなたのユースケースには問題ありません - あなたは、見て、出力したもののためにメモリ内の統計を集計するだけで各作業者が必要ですか?

あなたの手順はうまくいくかもしれませんが、おそらくメモリ内のデータ構造を作ることはありませんstatic - 誰も2つを1つのJVMクラスローダーで実行できないと言っています。

このパターンのより一般的なバージョンは、Reducerで再生されます。そこでは、1つのレコードを作成する前に、入ってくるキーの既知のサブセットに関する情報を収集する必要があります。パーティショナーを使用して、キーがソートされていることを確認して、ある従業員のすべてのサブセットを表示していることを知ることができます。それで、サブセットの処理中にデータを収集して結果を出力し、新しいサブセットが入ったときにクリアするのは簡単です。Reducerの前にボトルネックが発生するので、ここではうまくいきません。

+0

はい、これは私が欲しいものです。集約してレデューサーに出力する(そして、コンバイナーを持つかもしれない)。閉じることは良い解決策のようです。そして、静的変数を持つことによっていくつかの問題を引き起こす可能性があります。それを指摘してくれてありがとう。だから、私はclose(私はちょうどそれがクリーンアップと呼ばれることを確認した)の中でcontext.writeのようなことをしようとします。それがうまくいくかどうか私はあなたに知らせます。私はちょっとしたテキスト変数を書こうとしましたが、もっと速くなりました。両方のお返事ありがとう。彼らはもっと役に立たなかった。 – jojoba

+0

私はそれをしました。これは完全に紙がそれを記述する方法です。それはずっと速くなります。私はまだ私のコードを少し最適化する必要があり、それはうまくいくでしょう。あなたの提案に感謝します。 – jojoba

1

あなたが出力しているものの詳細についてもう少し分かりませんが、これが助けになるかどうかは確信できませんが、これはコンバイナが助けてくれるもののようです。これは小型レデューサーのようなものです(実際にはコンバイナーの実装はReducerの別の実装です)Mapperの出力に添付されています。その目的は、メモリにマップ出力レコードを収集し、ディスクに書き込まれる前に集計しようとしてからReducerによって収集することです。

古典的な例は、値を数えています。マップから「キー、1」を出力してレデューサーに1を追加することができますが、「キー、1000」で1000回のキーが表示される場合は、「キー、1」をマッパーから1000回出力します。コンバイナがそれを行います。もちろん、問題の操作が連想型/可換型であり、副作用なしで繰り返し実行できる場合にのみ適用されます - 追加が良い例です。

別の答え:Mahoutの中で私たちは簡単な方法を行えば、奇妙なビット複雑で、かつ非常に遅いの両方で多くのものを実装しています。 Mapperでメモリ内のデータを収集するような仕掛けを引き出すことは、時には些細なことであり、時には必要な罪でもありません。これは、Hadoopが保証するセマンティクスをよく知り、よくテストし、慎重ではないにしてもメモリ不足を考える必要があることを意味します。私は今、私が思う疑問のポイントを参照してくださいので、

+0

ありがとうSean。詳細については私の編集を参照してください。私はコンバイナを使用しています。ところで、私はMahoutを使いました。私はあなたの本を読んでいます。私はいくつかの新しいバージョンを見るのを待つことができません。 – jojoba

+0

(マップ出力圧縮をオンにしていると仮定します)名前や機能、統計情報をあとで再構成できる小さな識別子にハッシュできますか?少なくとも普通のテキストよりもコンパクトなもの。 –

+0

私は圧縮をしていませんでしたが、今は何も起こりませんでした。それは私のテキスト変数のサイズが、書き込みの数に問題があるようにではありません。地図のタスクがいつ終わりそうになったかを知る方法はありませんか?おそらく、Googleの実装にはそのことを知る方法があり、それを使用した理由です。私は本当にあなたの興味に感謝します。 – jojoba

関連する問題