1

2つのEC2インスタンスがあります。1つはmongodbサーバーとして、もう1つはpython Webアプリ(同じアベイラビリティーゾーン)です。PythonサーバーはPyMongoを使用してmongoサーバーに接続し、すべてが正常に機能します。

問題は、Pythonで実行時間をプロファイリングすると、一部の呼び出し(5%未満)で戻るのに最大で数秒かかることです。問題を絞り込むことができ、時間遅延は実際にはmongoサーバーへのdb呼び出しにありました。

私が考えた2つの原因は、1。Mongoサーバーが遅い/過負荷である2.ネットワーク遅延

そこで、mongoサーバーを4倍高速のインスタンスにアップグレードしようとしましたが、問題は引き続き発生します(一部の呼び出しは、戻るのに3秒もかかります)両方のサーバーがEC2上にあるため、ネットワーク遅延は問題にならないはずです...しかし、私は間違っていた。

問題が実際にネットワーク自体にあるかどうかを確認するにはどうすればよいですか?もしそうなら、それを解決するための最良の方法は何ですか?他に考えられる原因はありますか?

どんな助けでもありがたいです...

ありがとう、

UPATE:フェッチしているエンティティは非常に小さく(インデックスが付けられています)、通常、呼び出しは0.01〜0.02秒で終了します。

アップデート:

「JamesWahlin」が示唆しているように、mongoサーバーでプロファイリングを有効にして、いくつかの興味深いログを取得しました。

金3月15日18:05:22[conn88635]クエリdb.UserInfoSharedクエリ:{$ or:[{_locked:{$ examples:false}}、{_locked:{$ lte:1363370603.297361}}]、_id: "750837091142" } nto return:1 nscanned:1 nreturned:1 reslen:47 2614ms

15年3月金曜日18:05:22[conn88635]コマンドdb。$cmdコマンド:{findAndModify: "UserInfoShared"、フィールド:{_id:1}、upsert:true、クエリ:{$ or:[{_locked:{$ examples :false}}、{_locked:{$ lte:1363370603.297361}}]、_ id: "750837091142"}、更新:{$ set:{_locked:1363370623.297361}}、new:true} ntoreturn:1 reslen:153 2614ms

これらの2つの呼び出しが完了するまでに2秒以上かかったことがわかります。このフィールド_idは一意のインデックスが付けられており、それを見つけるのにそれほど時間はかからなかったはずです。新しい質問を投稿する必要があるかもしれませんが、mongodb GLOBAL LOCKが原因である可能性がありますか?

4

1 に答える 1

2

@ジェームズワーリン、私を助けてくれてありがとう。

結局のところ、レイテンシーの主な原因はmongodbGLOBAL LOCK自体でした。ロック率は平均5%で、ピーク時には30〜50%でしたが、その結果、クエリが遅くなりました。

この問題に直面している場合は、最初にmongodb MMSサービス(mms.10gen.com)を有効にする必要があります。これにより、dbサーバーで何が起こっているかについて多くの洞察が得られます。

私たちの場合、LOCK PERCENTAGEは非常に高く、複数の理由がありました。それを理解するために最初にやらなければならないことは、並行性に関するmongodbのドキュメント( http://docs.mongodb.org/manual/faq/concurrency/ )を読むことです。

ロックの理由は、アプリケーションレベル、mongodb、またはハードウェアにある可能性があります。

1)私たちのアプリは多くのことを行っておりupdates、各更新(以上100 ops/sec)はglobal lockmongodbで保持されます。問題は、メモリ内にないエントリに対して更新が発生した場合、mongoは最初にデータをメモリにロードしてから(メモリ内で)更新する必要があり、プロセス全体がの内部で発生することでしたglobal lock。すべてが完了するまでに1秒かかるとすると(0.75secディスクからデータをロードし0.25secてメモリ内で更新するため)、残りの更新呼び出し全体が(全体を1 sec)待機し、そのような更新がキューに入れられ始めます...そしてあなたは気付くでしょうアプリサーバーでのリクエストがますます遅くなります。

その解決策は(ばかげているように聞こえるかもしれませんが)query、を作成する前に同じデータを取得することですupdate。それが効果的に行うことは、「データをメモリにロードする」(0.75秒)部分をそこから移動することですglobal locklock percentage

2)グローバルロックのもう1つの主な原因は、mongodbのflushディスクへのデータです。基本的に、60秒(またはそれ以下)ごとにmongodb(またはOS)がデータをディスクに書き込み、global lockこのプロセス中にaが保持されます。(これはちょっとランダムな遅いクエリを説明します)。MMS統計で、グラフを参照してくださいbackground flush avg...高い場合は、より高速なディスクを取得する必要があることを意味します。

私たちの場合、の新しいEBS optimizedインスタンスに移動し、プロビジョニングされたインスタンスをEC2バンプしました。これにより、サーバーはほぼ半分になり、サーバーははるかに幸せになりました。IOPS100500background flush avg

于 2013-03-18T13:28:14.837 に答える