4

2 つのキーと値のデータ セット (データ セット A と B) があるとします。セット A のすべてのデータを、2 つのキーが一致するセット B のデータで更新したいと考えています。

私は非常に大量のデータを扱っているため、Hadoop を使用して MapReduce を行っています。私が懸念しているのは、A と B の間でこのキー マッチングを行うには、すべてのセット A (大量のデータ) をすべてのマッパー インスタンスのメモリにロードする必要があることです。それはかなり非効率的なようです。

毎回 A にロードする作業を繰り返す必要のない、これを行うための推奨される方法はありますか?

私が現在行っていることを明確にするための擬似コード:

Load in Data Set A # This seems like the expensive step to always be doing
Foreach key/value in Data Set B:
   If key is in Data Set A:
      Update Data Seta A
4

3 に答える 3

3

これまでに投稿された回答はすべて正しいです。これは Reduce 側の結合である必要がありますが、車輪を再発明する必要はありません。これについてPigHive、またはCascadingを検討しましたか? それらはすべて結合が組み込まれており、かなり最適化されています。

于 2012-09-13T18:30:44.513 に答える
3

ドキュメントによると、MapReduce フレームワークには次の手順が含まれます。

  1. 地図
  2. ソート/パーティション
  3. 組み合わせる(オプション)
  4. 減らす

結合を実行する 1 つの方法について説明しました。Set A のすべてを各 Mapper のメモリにロードします。これが非効率的であることは間違いありません。

代わりに、両方のセットがキーでソートおよび分割されている場合、大きな結合を任意の数の小さな結合に分割できることに注意してください。MapReduce は、上記の手順 (2) で各 Mapper の出力をキーで並べ替えます。その後、ソートされたマップ出力はキーによって分割され、Reducer ごとに 1 つのパーティションが作成されます。一意のキーごとに、Reducer はセット A とセット B の両方からすべての値を受け取ります。

結合を完了するために、Reducer はキーと、セット B からの更新された値 (存在する場合) を出力するだけで済みます。それ以外の場合は、セット A からキーと元の値を出力します。セット A とセット B の値を区別するには、Mapper からの出力値にフラグを設定してみてください。

于 2012-09-13T00:34:38.670 に答える
2

Cloudera によるこのビデオ チュートリアルでは、MapReduce を介して大規模な Join を行う方法を 12 分前後から説明しています。
ファイル B のレコードをファイル A のレコードにキー K で結合するための基本的な手順を、疑似コードを使用して以下に示します。ここで不明な点がある場合は、ビデオを見ることをお勧めします。彼は私よりもずっと上手に説明しています。

マッパーで:

K from file A:
  tag K to identify as Primary Key
  emit <K, value of K>

K from file B:
  tag K to identify as Foreign Key
  emit <K, record>

PK/FK タグを無視する Sorter と Grouper を作成して、レコードが PK レコードか FK レコードかに関係なく同じ Reducer に送信され、グループ化されるようにします。

PK キーと FK キーを比較し、最初に PK を送信する Comparator を作成します。

このステップの結果、同じキーを持つすべてのレコードが同じ Reducer に送信され、削減される値の同じセットになります。PK でタグ付けされたレコードが最初になり、結合する必要がある B からのすべてのレコードが続きます。さて、リデューサー:

value_of_PK = values[0] // First value is the value of your primary key
for value in values[1:]:
  value.replace(FK,value_of_PK) // Replace the foreign key with the key's value
  emit <key, value>

この結果はファイル B になり、K のすべての出現箇所がファイル A の K の値に置き換えられます。これを拡張して、完全な内部結合を実行したり、直接データベース ストレージ用に両方のファイル全体を書き出すこともできます。しかし、これが機能するようになると、それらはかなり些細な変更です。

于 2012-09-13T17:50:51.707 に答える