1

mysql から mongodb に移行しようとしています。mysql 構造は id_src int id_dest int 一意のキー: id_src,id_dest

それらはmysqlの約2億行です

データ例 : {id_src,id_dest} {1,2} {1,3} {1,10} {2,3} {2,10} {4,3}

データを取得する必要があります: {id_dest,count} {3,3} {10,2} {2,1}

mongodb で mysql の構造を再現し始めました。挿入のパフォーマンスは非常に優れていました (非常に優れていました)。2 億行を挿入するのに約 1 時間かかりました。

しかし、グループを取得するには map reduce を使用する必要がありました。マップ縮小は約1時間かかりました。

そこで、別の mongodb 構造を作成しようとしました: {id_dest,{id_src1,id_src2}}

各ドキュメントには、10 万個の id_src を含めることができます。

これが私のinsert.phpコードです

$res=mysql_unbuffered_query("select * from ids limit 10000100");  
while ($tab=mysql_fetch_array($res)) {  
$collection->update(array('_id'=>(int)$tab['id_dest']),array('$push' => array('src'=>(int)$tab['id_src'])),array("upsert" => true));  
}  

ただし、その場合、パフォーマンスは非常に悪く、1 秒あたりの更新はわずかです。

私は何か間違っていますか?

4

1 に答える 1

6

まず第一に、Map / Reduce はリアルタイム分析用に設計されていません。さらに、MongoDB は現在、M/R 用に 1 つのコアに制限されているため、処理がさらに遅くなります。

したがって、M/R を使用してデータを取得する場合、「リアルタイム」ではなく、X 分 (または時間) ごとに更新されます。

ここには 2 つの効率的なアプローチがあります。

  1. 増分 M/R
  2. リアルタイムカウンター

オプション #1: 増分 M/R

このオプションでは、すべてのデータに対して M/R を 1 回実行します。その後、変更されたデータに対してのみ M/R を実行します。現在 2 億のドキュメントがある場合、次は 2 億 1000 万のドキュメントがある可能性があります (つまり、M/R はさらに遅くなります)。ただし、新規/変更されたドキュメントのみを実行する必要がある場合は、1 時間もかからないはずです。

こちらのドキュメントのreduce出力オプションをご覧ください。

ここでも前提として、関連するデータのみを M/R し、システムは既存のデータに対して「再削減」します。このようにして、「増分」M/R を取得します。

オプション #2: リアルタイム カウンター

この方法では、2 つのコレクションがあります。1 つはデータ用、もう 1 つは「要約」の結果用です。データに挿入すると、集計もインクリメントされます。

次のデータがあるとします。

Main Collection
{src: 1, dest: 2}
{src: 1, dest: 3}
{src: 1, dest: 10}
{src: 2, dest: 3}
{src: 2, dest: 10}
{src: 4, dest: 3}

Summary Collection
{dest: 3, count: 3}
{dest: 10, count: 2}
{dest: 2, count: 1}

新しいデータを受け取ります{src: 5, dest: 2}。次の 2 つの更新を行います。

db.main.insert({src: 5, dest: 2});
db.summary.update({dest: 2}, { $inc : { count: 1 } }, true); // upsert true

新しいデータは次のとおりです。

Main Collection
{src: 1, dest: 2}
...
{src: 4, dest: 3}
{src: 5, dest: 2}

Summary Collection
{dest: 3, count: 3}
{dest: 10, count: 2}
{dest: 2, count: 2}

概要が更新されたことにお気付きでしょう: {dest: 2, count: 2}

明らかに、ここにはトレードオフがあります。より多くの更新/挿入 (2x) が必要ですが、リアルタイム カウンターが得られます。現在、MongoDB にはトランザクションがないため、両方の更新が確実に行われるようにするための戦略を決定する必要があります。これを行う方法はたくさんありますが、ここでは説明しません (1 つの方法についてはメッセージ キューを参照してください)。

于 2011-07-26T20:17:48.403 に答える