私は、MongoDBを使用して、かなり多数の着信要求を取得しているアプリケーションを使用していますが、要求の数が増えるにつれて応答が遅くなっていることに気付きました。
データベースに何らかの非効率性があるのではないかと思います。負荷の高い期間の1つにmongostatを実行しましたが、結果はロックの割合が高いことを示しているようです。
insert query update delete getmore command flushes mapped vsize res faults locked db idx miss % qr|qw ar|aw netIn netOut conn set repl time
*0 1120 479 *0 179 472|0 0 72.1g 146g 1.31g 0 server-prod:15.7% 0 0|0 1|0 1m 4m 298 rs0 PRI 15:37:28
*0 1192 509 *0 178 428|0 0 72.1g 146g 1.3g 0 server-prod:18.9% 0 0|0 0|0 1m 5m 298 rs0 PRI 15:37:29
*0 1107 456 *0 174 362|0 0 72.1g 146g 1.3g 0 server-prod:20.4% 0 0|0 2|1 1m 5m 298 rs0 PRI 15:37:30
*0 1320 556 *0 211 532|0 0 72.1g 146g 1.3g 0 server-prod:19.5% 0 0|0 0|1 1m 6m 298 rs0 PRI 15:37:31
*0 1094 474 *0 179 449|0 0 72.1g 146g 1.3g 0 server-prod:15.7% 0 0|0 0|0 1m 5m 298 rs0 PRI 15:37:32
*0 1120 487 *0 184 458|0 0 72.1g 146g 1.3g 0 server-prod:20.8% 0 0|0 1|1 1m 5m 298 rs0 PRI 15:37:33
*0 807 299 *0 108 270|0 0 72.1g 146g 1.3g 0 server-prod:15.3% 0 103|1 0|3 1m 3m 298 rs0 PRI 15:37:34
*0 1613 709 *0 161 146|0 0 72.1g 146g 1.3g 0 server-prod:63.5% 0 0|0 1|0 2m 7m 298 rs0 PRI 15:37:35
*0 1133 472 *0 167 341|0 0 72.1g 146g 1.31g 0 server-prod:21.2% 0 1|0 0|1 1m 6m 298 rs0 PRI 15:37:36
*0 1292 555 *0 189 440|0 0 72.1g 146g 1.31g 0 server-prod:23.3% 0 5|0 1|4 2m 6m 298 rs0 PRI 15:37:37
下から3番目の行のロック率は60%で、平均ロック率が約20%であることを考えると、かなりおかしいです。負荷が高い場合、平均は35〜40%になります。
プロダクションモンゴシェルでshow logも実行しましたが、100ミリ秒未満で実行されたクエリは1つもありません。一部のクエリの実行時間は、約700ミリ秒から1秒です。
データベースが実行されているマシンも問題である可能性があります(n1-standard-1(1 vCPU、3.8 GBメモリ)google compute engine VM instance)。データベースは、 3メンバーのレプリカセット(アービターのない1つのプライマリと2つのセカンダリ)。
トラブルシューティングを行ってクエリ速度を向上させる方法は何ですか?
ありがとう!
編集:私がMongo v2.6を使用していることを言及するのを忘れました
編集:db.stats()の出力は次のとおりです
{
"db" : "server-prod",
"collections" : 20,
"objects" : 36560,
"avgObjSize" : 359.20568927789935,
"dataSize" : 13132560,
"storageSize" : 43479040,
"numExtents" : 62,
"indexes" : 24,
"indexSize" : 6189232,
"fileSize" : 67108864,
"nsSizeMB" : 16,
"dataFileVersion" : {
"major" : 4,
"minor" : 5
},
"extentFreeList" : {
"num" : 0,
"totalSize" : 0
},
"ok" : 1
}
編集:昨夜、ピーク負荷時にCPUが128%に達するのを見ましたが、これはどのようにして可能ですか? (これはシングルコアマシンです)
編集:最もクエリの多いフィールドのいくつかにインデックスを作成し、パフォーマンスの向上に気づきましたが、更新クエリはまだ時間がかかりすぎています(約500〜800ミリ秒)。更新/挿入のパフォーマンスを向上させるために、どのような最適化を行うことができますか?
ハードウェアが制限していないかどうかを確認するには:
ロックについて:
1つの巨大なコレクション(server-prod)がある場合、おそらくShardingが負荷を分散するためのオプション、またはMongo3.0でより多くのコア+より少ないロック
インデックスを改善する:-インデックスを増やす=書き込みを遅く+読み取りを速くする-インデックスを少なくする=書き込みを速く+読み取りを遅くする
セカンダリから読み取り、プライマリにのみ書き込みます。
> db.setProvilingLevel(1,4) ## save slow logs for that db slower than 4ms
> db.system.profile.find({millis:{$gt:100}}).sort({ts:-1}) ## find queries slower than 100ms, order by timestamp descending
> ....query.explain() ## find out which indexes it uses
情報: http://docs.mongodb.org/manual/administration/optimization/