5

削減フェーズに関するMongoDBの説明は次のように述べています。

map / reduceエンジンは、reduce関数を繰り返し呼び出す場合があります。したがって、これらの関数はべき等でなければなりません。

これが、一般的なマップリデュース環境で機能するリデュースを常に理解していた方法です。ここでは、各マシンの値を減らし、それらの出力を別のレデューサーに送信することで、N台のマシンの値を合計できます。

ウィキペディアによると

フレームワークは、ソートされた順序で一意のキーごとにアプリケーションのReduce関数を1回呼び出します。Reduceは、そのキーに関連付けられている値を反復処理して、0個以上の出力を生成できます。

ここでは、(同じキーを持つ)すべての値を同じマシンに移動して合計する必要があります。データを関数に移動することは、mapreduceが行うことになっていることとは逆のようです。

ウィキペディアの説明は具体的すぎますか?または、MongoDBはmap-reduceを破りましたか?(または、ここで何かが欠けていますか?)

4

3 に答える 3

4

これは、元のMapReduceフレームワークがGoogleによって記述された方法です

2プログラミングモデル

[...]

中間値は、イテレータを介してユーザーのreduce関数に提供されます。これにより、大きすぎてメモリに収まらない値のリストを処理できます。

以降:

3実装

[...]

6.reduceワーカーは、並べ替えられた中間データを繰り返し処理し、検出された一意の中間キーごとに、キーと対応する中間値のセットをユーザーのReduce関数に渡します。

したがって、の呼び出しは1つだけですReduce。多数の小さな中間ペアを移動する問題は、特別なコンバイナー関数をローカルで使用することで解決されます。

4.3コンバイナー機能

場合によっては、各マップタスクによって生成される中間キーにかなりの繰り返しがあります[...]Combinerネットワーク経由で送信される前に、このデータの部分的なマージを行うオプションの関数をユーザーが指定できるようにします。

このCombiner関数は、マップタスクを実行する各マシンで実行されます。通常、コンバイナとリデュース関数の両方を実装するために同じコードが使用されます。[...]

部分的に組み合わせると、特定のクラスのMapReduce操作が大幅に高速化されます。

TL; DR

ウィキペディアは元のMapReduceデザインに従い、MongoDBデザイナーはわずかに異なるアプローチを採用しました。

于 2012-10-18T14:35:02.870 に答える
2

GoogleMapReduceの論文によると

リデュースワーカーがすべての中間データを読み取ると、同じキーのすべてのオカレンスがグループ化されるように、中間キーでデータを並べ替えます。

MongoDBドキュメントによると

map / reduceエンジンは、reduce関数を繰り返し呼び出す場合があります。したがって、これらの関数はべき等でなければなりません。

したがって、Googleの論文で定義されているMapReduceの場合、特定のキーのデータがレデューサーに転送されると、reduceはキーと値のペアの処理を開始します。しかし、Tomaszが述べたように、MongoDBはわずかに異なる方法でMapReduceを実装しているようです。

Googleが提案したMapReduceでは、MapタスクまたはReduceタスクのいずれかがKVペアを処理しますが、MongoDB実装では、MapタスクとReduceタスクが同時にKVペアを処理します。ノードが効率的に使用されておらず、クラスター内のMapスロットとReduceスロットがいっぱいで、新しいジョブを実行できない可能性があるため、MongoDBアプローチは効率的ではない可能性があります。

Hadoopの欠点は、マップがデータの処理を完了するまでレデューサータスクがKVペアを処理しないことですが、マッパーが処理を完了する前にレデューサータスクを生成できます。パラメータ「mapreduce.job.reduce.slowstart.completedmaps」は「0.05」に設定されており、説明には「削減がジョブにスケジュールされる前に完了する必要があるジョブ内のマップ数の割合」と記載されています。

ここでは、(同じキーを持つ)すべての値を同じマシンに移動して合計する必要があります。データを関数に移動することは、mapreduceが行うことになっていることとは逆のようです。

また、データの局所性は、reduceタスクではなく、mapタスクで考慮されます。リデュースタスクの場合、データは、集約のために、異なるノード上の異なるマッパーからレデューサーに移動する必要があります。

ちょうど私の2c。

于 2012-10-18T15:11:39.400 に答える
0

TLDR:reduce(mongo)はコンバイナーに似ており、finalize(mongo)は、キー/値を1つだけ取る点を除けば、ほとんどレデューサーに似ています。すべてのデータをreduce(hadoop)関数に含める必要がある場合は、reduce(mongo)を使用してデータを大きな配列に集約し、それを渡してファイナライズします。これを行うには、出力値にある種のフラグを使用します。

それが私がそれを行う方法であり、それは大量のデータを吸うだろうと思いますが、mongodb mapreduceでそれを行う他の方法を知りません:((しかし私はそれについてあまり経験がありません)

于 2013-09-09T09:09:26.080 に答える