1

mapreduce 用語でアルゴリズムを表現するのに問題があります。

2 つの大きな入力テキスト ファイルがあります。最初のファイルを「R」、2 番目のファイルを「P」と呼びましょう。通常、R は P よりもはるかに大きいですが、どちらも大きいです。

mapreduce 以外のアプローチでは、P の内容がメモリに読み込まれ (ハッシュされ)、R のすべての行に対して反復処理が開始されます。R の行は単なる文字列であり、部分文字列のいずれかを確認したいR では、P の任意の文字列に一致します。

この問題は、bigfile 内の単語を grep するのと非常によく似ています。問題は、単語のリストが非常に大きいため、マップ ルーチンでそれらをハードコーディングできないことです。

私が直面している問題は、P ファイルのすべての分割が R ファイルの分割ごとにマップ ジョブになるようにする方法がわからないことです。したがって、これらの分割を想定すると、次のようになります。

R = R1, R2, R3;
P = P1, P2

6 つのマップ ジョブには、次の分割が含まれている必要があります。

(R1, P1) (R1, P2);
(R2, P1) (R2, P2);
(R3, P1) (R3, P2);

この問題を mapreduce で表現するとどうなりますか?

ありがとう。

4

2 に答える 2

1

私はこれにしばらく取り組んできましたが、いくつかの解決策を考え出しました。1つ目はHadoopストリーミングに基づいており、2つ目はネイティブJavaを使用しています。

最初の解決策として、rubyの興味深い機能を使用します。コードの最後にキーワードを追加すると、__END__それ以降のすべてのテキストは、グローバル変数DATAを介してインタープリターによって公開されます。この変数はFileオブジェクトです。例:

$ cat /tmp/foo.rb
puts DATA.read

__END__
Hello World!
$ ruby /tmp/foo.rb
Hello World!

ファイルRを入力として使用します(HDFSファイルシステム全体に配布されます)。Pファイルを反復処理し、特定の行数をトラバースした後、マッパースクリプトの最後にそれらを追加します。次に、ジョブをHadoopクラスターに送信します。すべての行を消費するまで、Pの内容を繰り返し処理します。ジョブあたりの行数とPのサイズに基づいて、複数のジョブがクラスターに送信されます。

これは私が実装した優れたアプローチであり、非常にうまく機能します。でも、特にエレガントだとは思いません。Javaでネイティブのmapreduceアプリを作成することで、より良い結果を得ることができます。

ネイティブJavaアプリを使用する場合、HadoopHDFSAPIへのフルアクセスがあります。つまり、コードからファイルの内容を読み取ることができます。それはストリーミング時に利用できるとは思わないものです。

ストリーミング方法と同様のアプローチに従いますが、特定の行数を通過すると、コードに追加するのではなく、それらをhadoopクラスターに送信します。これは、ジョブをスケジュールするコード内で実行できます。

次に、Pの分割数と同じ数のジョブを実行する必要があります。特定のジョブのすべてのマッパーは、特定の分割をロードし、それを使用してRの分割を計算します。

于 2012-07-08T00:32:08.120 に答える
0

良い問題です。

私が思いつく簡単な方法の 1 つは、P ファイルを複数のファイルに分割し、P ファイルの各分割と完全な R ファイルを入力として複数の MR ジョブを実行することです。

于 2012-07-01T16:21:28.527 に答える