web-dev-qa-db-ja.com

MapReduceソートアルゴリズムはどのように機能しますか?

MapReduceの威力を示す際に使用される主な例の1つは、 Terasortベンチマーク です。 MapReduce環境で使用されるソートアルゴリズムの基本を理解するのが困難です。

私にとってソートとは、他のすべての要素との関係で要素の相対的な位置を決定することだけです。したがって、ソートには「すべて」と「すべて」を比較することが含まれます。平均的なソートアルゴリズム(クイック、バブル、...)は、これを単にスマートな方法で実行します。

私の考えでは、データセットを多くの部分に分割するということは、1つの部分をソートできますが、これらの部分を「完全な」完全にソートされたデータセットに統合する必要があるということです。テラバイトのデータセットが数千のシステムに分散していることを考えると、これは大きな作業になると思います。

それで、これは実際にどのように行われますか?このMapReduceソートアルゴリズムはどのように機能しますか?

理解してくれてありがとう。

101
Niels Basjes

Terasort用のHadoopの実装 の詳細を次に示します。

TeraSortは標準のマップ/リデュースソートです。ただし、各リデュースのキー範囲を定義するN-1個のサンプリングキーのソート済みリストを使用するカスタムパーティショナーを除きます。特に、sample [i − 1] <= key <sample [i]などのすべてのキーは、iを減らすために送信されます。これにより、reduce iの出力がすべてreduce i + 1の出力よりも小さくなることが保証されます。

したがって、彼らのトリックは、マップフェーズでキーを決定する方法にあります。基本的に、単一のレデューサーのすべての値が、他のすべてのレデューサーに対して「事前ソート」されることが保証されます。

私は James Hamiltonのブログ投稿 を通じて論文の参照を見つけました。

58
Yuval F

Googleリファレンス: MapReduce:大規模クラスターでのデータ処理の簡素化

に表示される
OSDI'04:第6回オペレーティングシステムの設計と実装に関するシンポジウム、
2004年12月、カリフォルニア州サンフランシスコ。

そのリンクには、PDFおよびHTMLスライド参照があります。

説明付きのウィキペディアのページ 実装参照もあります。

批判も

並列データベースの先駆者であり、何も共有しないアーキテクチャーであるDavid DeWittとMichael Stonebrakerは、MapReduceを使用できる問題の幅について議論を呼んでいます。彼らはそのインターフェースを低レベルと呼び、それが支持者が主張しているパラダイムシフトを本当に表しているのかと疑問を呈した。彼らは、20年以上前から存在する先行技術の例としてTeradataを挙げて、MapReduceの支持者の新規性の主張に挑戦しています。彼らはMapReduceプログラマーをCodasylプログラマーと比較しました。両方とも「低レベルのレコード操作を実行する低レベル言語で記述している」ことに注意してください。 MapReduceの入力ファイルの使用とスキーマのサポートの欠如により、Bツリーやハッシュパーティションなどの一般的なデータベースシステム機能によるパフォーマンスの向上が妨げられますが、PigLatinやSawzallなどのプロジェクトはこれらの問題に対処し始めています。

3
nik

GoogleのMapReduce論文を読んでいるときに同じ質問がありました。 @ Yuval Fanswer 私のパズルをほとんど解決しました。

論文を読んでいるときに気づいたことの1つは、マジックがパーティション分割(マップ後、縮小前)で発生することです。

このペーパーではhash(key) mod Rをパーティション化の例として使用していますが、これが中間データを異なる削減タスクにパーティション化する唯一の方法ではありません。

@ Yuval Fanswer に境界条件を追加するだけです完了:min(S)およびmax(S)が、サンプリングされたキーの中で最小キーおよび最大キーであるとします。すべてのキー<min(S)は1つのリデュースタスクに分割されます。逆に、すべてのキー> = max(S)は1つのリデュースタスクに分割されます。

サンプリングされたキーには、minやmaxなどの厳しい制限はありません。ちょうど、これらのRキーがすべてのキーに均等に分散されるほど、この分散システムは「並列」になり、reduceオペレーターがメモリオーバーフローの問題を起こす可能性が低くなります。

1
edwinfj_

ただ推測...

膨大なデータのセットがある場合、データをいくつかのチャンクに分割して、並列処理します(たとえば、レコード番号で1-1000 =パーティション1など)。

クラスタ内の特定のノードに各パーティションを割り当て/スケジュールします。

各クラスターノードは、おそらくキーのアルファベット順で、パーティションを独自のミニパーティションにさらに分割(マップ)します。したがって、パーティション1で、Aで始まるすべてのものを取得し、xのミニパーティションAに出力します。新しいA(x)を作成します。現在A(x)が既に存在する場合。xを連番で置き換えます(おそらくこれが行うスケジューラジョブです)つまり)次のA(x)ユニークIDを教えてください。

マッパー(前のステップ)によって完了したジョブを「削減」クラスターノードに引き渡します(スケジュールします)。リデュースノードクラスターは、各マッパータスクが完了したときにのみ発生する各A(x)部分のソートをさらに絞り込みます(実際には、W/Aで始まるすべての単語のソートを開始することはできません作成中に別のAミニパーティションが存在する可能性がまだある場合)最終的な並べ替えられたパーティションに結果を出力します(つまり、並べ替えられたA、並べ替えられたBなど)。

完了したら、並べ替えられたパーティションを再度単一のデータセットに結合します。この時点では、n個のファイルを単純に連結しただけです(A〜Zのみを実行している場合、nは26になります)。

間に中間ステップがあるかもしれません...私にはわかりません:)。つまり最初の縮小ステップの後、さらにマッピングして縮小します。

0
Jimmy Chandra