2011-11-04 9 views
13

ログデータのコレクションがあります。コレクションの各ドキュメントは、MACアドレスと暦日で識別されます。基本的には:MongoDBでは、日々のログ文書への書き込みパフォーマンスを最大化するための戦略

{ 
    _id: <generated>, 
    mac: <string>, 
    day: <date>, 
    data: [ "value1", "value2" ] 
} 

5分ごとに、私たちは、当日のドキュメント内のデータ配列に新しいログエントリを追加します。ドキュメントは、MACごとに新しいドキュメントを作成するUTCの真夜中にロールオーバーします。

書込みバイト単位で測定されたIOが1日中増加し、UTCの午前0時に戻ってきたことに気付きました。ログメッセージのレートが一定であるため、これは発生しません。予期せぬ挙動は、Mongoの移動文書によるものであり、ログ配列の更新とは対照的です。価値があるものについては、stats()は、paddingFactorが1.0299999997858227であることを示しています。

いくつかの質問:

  1. モンゴの場所に更新したり、移動しているかどうかを確認する方法はありますか?私たちは、低速のクエリログでいくつかの動きを見ていますが、これは事例証拠のようです。私はdb.setProfilingLevel(2)、次にdb.system.profile.find()、そして最後に"moved:true"を探すことができると知っていますが、忙しいプロダクションシステムでこれを行うことが大丈夫かどうかはわかりません。
  2. 各文書のサイズは非常に予測可能で規則的です。モンゴが多くの動きをしていると仮定すると、モンゴがなぜより正確にプリフォーマットすることができないのかを理解する最良の方法は何ですか?あるいは、モンゴがより正確にプレサイズされるようにするには?上記の問題の説明が正しいと仮定すると、パディングファクタを調整することは、そのトリックを行うようには見えません。
  3. 私は文書を整理し、Mongoからの推測を​​取り除くのに十分なはずです。 (私はpadding factor文書は、私はこれを行う必要はありませんが、私はこの問題を私の後ろに置く必要があると言うことを知っています。)文書をpresizeするための最良の方法は何ですか?ガベージバイト配列フ​​ィールドを持つ文書を書いてすぐに文書からそのフィールドを削除するのは簡単ですが、私が知っておかなければならない問題はありますか?たとえば、ガベージフィールドを削除する前に、書き込み操作(つまり、安全な書き込みを行う)のためにサーバー上で待機する必要があると考えられます。
  4. 私は、この時点でディスクが飽和しているように見えるので、1日のドキュメントをすべて同時に前もって割り当てることを心配していました。これは有効な懸念事項ですか?事前配分費を前日よりも引き上げるべきですか?
+0

Scott HernandezさんがGoogleグループでこの質問に回答しましたので、私は彼の答えに投稿しています:http://groups.google.com/group/mongodb-user/browse_thread/thread/8a24e7f3faf95f71# – jtoberon

+0

最新のアップデート:私たちはまだ何が起こっているのか把握しようとしています。 – jtoberon

答えて

4

次の組み合わせは、書き込み性能が崖から落ちるさせているようだ:

  1. ジャーナリングがオンになっています。
  2. 書き込みはおそらくI/Oが飽和大きい文書

の大部分を構成する配列にエントリを追加します。これらの要因のいずれかを変更すると、これが発生しないように見えます。

  1. ジャーナリングをオフにします。代わりに、より多くのレプリカを使用してください。
  2. 小さい文書を使用してください。ここでの文書サイズは、文書内の任意の配列の長さではなく、バイト単位で測定されることに注意してください。
  3. 別ファイルシステム上のジャーナル。

さらに、書き込みスループットを改善するいくつかのその他のトリックがあります。シャーディングを除いて、私たちは「これはまったく問題はありません」という問題を解決しようとしていたのに対し、改善は段階的であると感じましたが、ここではインクリメンタルな改善を探しています。 10Genの人々did some testing and got similar results

  1. シャード
  2. 長い配列を複数の配列に分割すると、全体の構造がネストされたツリーのようになります。 1時間の時間をキーとして使用すると、日次ログ文書は
    {"0":[...], "1":[...],...,"23":[...]}になります。
  3. 手動による事前割り当てを試してください。 (これは私たちを助けませんでした。モンゴの敷き詰めは、宣伝されているように動作するようですが、私の元の質問は間違っていました)
  4. 別の--syncdelay値を試してみてください。 (これは私たちを助けませんでした)
  5. 安全な書き込みなしで試してください。 (ログデータ用に既にこれを行っていましたが、多くの状況でこれを行うことはできませんでした)。

私はいくつかの提案をコピーしていますここ10Genから、完全性のために。うまくいけば、私はそう正確にした!彼らが料理本の例を発表した場合は、ここにリンクを投稿します。

0

mongodbは、ある期間にわたってドキュメントをどのように更新しているかを学習するので、ドキュメントを適切にプリサイズしようとします。さらに詳しい情報はhttp://www.mongodb.org/display/DOCS/Padding+Factor

にあります。mongodbがまだドキュメントを移動していることがわかっている場合は、手作業でドキュメントをパディングしてみてください。ドキュメントを移動する必要はありません。

1日のサンプル数が(5分間隔で)一定であるという事実を考えれば、そうすることができるはずです。db。{yourcollectionname}の出力を印刷できますか? .stats()?ポイント#4について

:uが述べたようにあなたはコストを分散することができますが、私はあなたが彼らにそれを実行する方法を参照して、他のものを試してみる最初の時間を必要とするとき、文書を挿入してみます。

他のスキーマを調べることで、この特定の問題を回避できるかもしれませんが、試してみたことがすべてわからないことがあります。タイムスタンプをキーにして、キー値のペアを配列内に格納していますか? 変更例は次のように移動するであろう: {ID:1、 メトリクス: { "0:05":{ "metric1": "値1"}、 "0時10分":{ "}

+0

私は適応型のプレサイズについて認識していますが、それが機能していれば、私が記述したIOパターンは見えないと思います。私は質問に統計を追加します。はい、ドキュメントを手作業で埋めたいと思います。私の質問3を参照してください。あなたはそうする方法についての詳細を提供できますか?はい、私たちは物事を試していますが、私が言ったように、経験を持つ誰かからの答えがより役立つように、問題を期待しています。私はスキーマがこの問題の中核であるとは考えていません。それぞれの書き込みは配列フィールドの最後に値を追加するだけなので、私は質問に例を追加しました。 – jtoberon

+0

あなたのコレクションに対してmongodbが計算したパディングファクタは何ですか? – Shekhar

+0

それは問題です:1.0299999997858227 – jtoberon

0

データ配列には、予測可能な/一定のプッシュ回数があります。 1日で (24 * 60)/ 5 = 288 文書内で288要素の配列(または3分ごとに実行することにした場合の柔軟性と拡張性のために1000)を事前に割り当て、各データ入力の追加に従って文書を更新することを強くお勧めします。 これを進める方法です:

- 各ドキュメントに1つ以上のキーを追加すると、関連付けられるdata配列のキー番号が更新されます。例えば。最初の文書は、更新によって データ配列の最初の挿入またはリフレッシュのようになります。それぞれの更新のために

{ 
     _id: <generated>, 
     mac: <string>, 
     day: <date>, 
     data: { "1" : "myGarbageValue","2" : "myGarbageValue", 
       "3" : "myGarbageValue"....."1000": "myGarbageValue" } 
     n: 1 
} 

、あなたはnに等しいキーdataにアップサートをしなければならない、とのn 2の後にアップデートをインクリメントデータ:

{ 
      _id: <generated>, 
      mac: <string>, 
      day: <date>, 
      data: { "1" : "myFirstValue","2" : "mySecondValue", 
        "3" : "myGarbageValue"....."1000": "myGarbageValue" } 
      n: 3 
    } 

長所:

    文書の
  • あまり成長、bのでしょうあなたのmyGarbageValuemyFirstValuemySecondValueがサイズとフォーマットに合っていれば最高です。
  • nは常にあなたのdata配列の現在のサイズを伝え、あなたが唯一の正確なサイズの試合ではなく、範囲を返すことができます$サイズ演算子として以前stuctureでは不可能であったdata配列のサイズを、見つけるために、範囲クエリを実行することができます。 http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24size
  • 文書が展開されていない場合は、パフォーマンスが向上します。ここでは、例えばdata.23のクリーンなキーベースのアップサートですが、古い構造の場合は$pushでしたが、直線的な挿入パフォーマンスを持ち、dataの配列が大きくなるにつれて遅くなります。

短所:あなたは24時間ごとにデータを更新するよう

  • さらにディスク領域がデータで使用されているが、それが問題になることはありません。

これらの提案が役立つことを願っています。試してみて、あなたに利益をもたらすかどうか私たちに知らせてください。

+0

「プッシュ・ライン・インサート性能」の正式な情報は知っていますか?私はこのテストhttp://blog.axant.it/archives/236を知っていますが、「おそらく」としか言いません。連想配列の提案を試してみるが、これがうまくいくなら私は驚くだろう。私たちは言及されている5000の閾値の下にあります。また、線形挿入アルゴリズムが、実際にすべてのエントリを移動することができないため、私たちが見る物理IO動作に変換する理由についての説明も考えられません。 – jtoberon

+0

こんにちは、jtoberon、正式には文書化されていませんが、一部のベンチマーク中に観察されました。しかし、あなたのような288の小さなサイズの配列の場合、それは大きな違いはありません。 あなたが正しいです、IOの違いは、挿入/更新アルゴリズムの違いによって作られたものではありません。連想配列の要素の事前割り当てにより、ドキュメントオブジェクトは成長しません。mongodb 、少ないIO。 – DhruvPathak

+0

連想配列の変更は役に立たなかった。 IO負荷は平滑化されますが、通常の配列と '$ push'を使うときに見られるピークよりも悪いレベルです。 – jtoberon

関連する問題