26

次のように接続するnodejs + mongodbアプリケーションがあります。

var dbConfig = new mongo.Server(config.db.host, config.db.port, {auto_reconnect: true, poolSize: 20});

var db = new mongo.Db(config.db.name, dbConfig);

ベンチマーク(apache abを使用)すると、同時接続数が20を超えると(時間> = 1秒)苦労することがわかりました(2つ以上の同時接続でも時間が直線的に増加するようです):

[
    {
        "key": "mongoQuery1",
        "min": 2,
        "max": 598,
        "mean": 387.60683760683764,
        "sd": 134.56045668980255,
        "variance": 18106.51650456823
    },
    {
        "key": "mongoQuery2",
        "min": 8,
        "max": 149,
        "mean": 73.14120370370358,
        "sd": 25.141715811881994,
        "variance": 632.1058739654371
    },
    ...
]

上記は、ノード アプリからプロファイリング情報を取得するために使用したプロファイリング サーバーからの出力です。基本的に、私はアプリをプロファイリングするために次のようなものを入れました:

var start = new Date().getTime();

db.collection('TheCollection', query, function(err, col) {
  col.find(query).toArray(function(err, items) {
    var elapsed = new Date().getTime() - start;
    profiler.send('mongoQuery1', elapsed);
  });
});

コレクションのサイズは最小 (700 レコード) であり、コレクションはすべてクエリに従ってインデックス化されていることに注意してください。

私はアイデアに行き詰まっています。パフォーマンスがなぜそんなに悪いのか、誰にも分かりますか?

編集:

次のような単純なクエリの場合:

db.user_permission.find({ username: 'a', permission_type: 'vehicle'})

インデックスを持つ user_permission を使用:

db.user_permission.ensureIndex({username: 1, permission_type: 1});

時間は同時ユーザーに比例して増加します

編集2

mongod のプロファイリングをオンにしてみました (--profile=2 --slowms=100)

それに対して ab を実行するたびに、db が破損し、mongod ログに次のように記録されます。

Wed Nov 21 10:41:54 [conn4] creating profile collection: knightsbridge.system.profile
Wed Nov 21 10:41:54 [FileAllocator] allocating new datafile /Users/dzhu/data/mongodb/knightsbridge.ns, filling with zeroes...
Wed Nov 21 10:41:54 [FileAllocator] creating directory /Users/dzhu/data/mongodb/_tmp
Wed Nov 21 10:41:54 [FileAllocator] done allocating datafile /Users/dzhu/data/mongodb/knightsbridge.ns, size: 16MB,  took 0.018 secs
Wed Nov 21 10:41:54 [FileAllocator] allocating new datafile /Users/dzhu/data/mongodb/knightsbridge.0, filling with zeroes...
Wed Nov 21 10:41:54 [FileAllocator] done allocating datafile /Users/dzhu/data/mongodb/knightsbridge.0, size: 64MB,  took 0.152 secs
Wed Nov 21 10:41:54 [conn5] Assertion: 10334:Invalid BSONObj size: 0 (0x00000000) first element: EOO
0x10037637b 0x1000afc2e 0x1000b005c 0x10001ea53 0x100233529 0x1002a9b0b 0x1001a0a9f 0x10069518b 0x1002a2a4e 0x1005ca15e 0x10064a0ca 0x100018681 0x10019302c 0x1005a7823 0x7fff8a42f8bf 0x7fff8a432b75 
 0   mongod                              0x000000010037637b _ZN5mongo15printStackTraceERSo + 43
 1   mongod                              0x00000001000afc2e _ZN5mongo11msgassertedEiPKc + 206
 2   mongod                              0x00000001000b005c _ZN5mongo11msgassertedEiRKSs + 12
 3   mongod                              0x000000010001ea53 _ZNK5mongo7BSONObj14_assertInvalidEv + 1475
 4   mongod                              0x0000000100233529 _ZN5mongo13unindexRecordEPNS_16NamespaceDetailsEPNS_6RecordERKNS_7DiskLocEb + 265
 5   mongod                              0x00000001002a9b0b _ZN5mongo11DataFileMgr12deleteRecordEPKcPNS_6RecordERKNS_7DiskLocEbbb + 587
 6   mongod                              0x00000001001a0a9f _ZN5mongo16NamespaceDetails11cappedAllocEPKci + 1535
 7   mongod                              0x000000010069518b _ZN5mongo16NamespaceDetails5allocEPKciRNS_7DiskLocE + 123
 8   mongod                              0x00000001002a2a4e _ZN5mongo11DataFileMgr17fast_oplog_insertEPNS_16NamespaceDetailsEPKci + 126
 9   mongod                              0x00000001005ca15e _ZN5mongo7profileERKNS_6ClientERNS_5CurOpE + 3134
 10  mongod                              0x000000010064a0ca _ZN5mongo16assembleResponseERNS_7MessageERNS_10DbResponseERKNS_11HostAndPortE + 4010
 11  mongod                              0x0000000100018681 _ZN5mongo16MyMessageHandler7processERNS_7MessageEPNS_21AbstractMessagingPortEPNS_9LastErrorE + 257
 12  mongod                              0x000000010019302c _ZN5mongo3pms9threadRunEPNS_13MessagingPortE + 1084
 13  mongod                              0x00000001005a7823 thread_proxy + 163
 14  libsystem_c.dylib                   0x00007fff8a42f8bf _pthread_start + 335
 15  libsystem_c.dylib                   0x00007fff8a432b75 thread_start + 13

モンゴッドのバージョン:

mongod --version
db version v2.2.0, pdfile version 4.5
Wed Nov 21 10:47:24 git version: f5e83eae9cfbec7fb7a071321928f00d1b0c5207

また

デフォルトの nodejs ドライバーの poolSize が 1 である以外に、mongod は許可される同時接続数に制限を設けますか?

4

2 に答える 2

7

Dzhu、たくさんのもの:

  • mongo シェルからこのクエリを試しましたか? シェルで実行し、.explain() 関数を使用してサーバーの実行時間を把握できますか? これは、インデックスが正しいことを確認するのに役立ち、パフォーマンスの問題がクライアント側にあるのかサーバー側にあるのかを特定するのに役立ちます。

  • 同時に書き込みが行われていますか? ベンチマークの実行中にデータベースのワークロードを提供したのは、このコードの部分だけですか? それとも、同時に他の作業が行われていますか?

  • ベンチマークの実行中に、mongostat ユーティリティ (mongodb のドキュメントを参照) を使用します。これにより、サーバーがリアルタイムで何をしているかがわかります。特に、lock % と qr/qw 列を見てください。qr/qw 列は、キューに入っている (つまり、ブロックされて実行を待機している) 読み取り + 書き込み操作の数を示します。

  • mongo サーバー プロファイラーをレベル 2 (--profile=2) でオンにすると、サーバーがすべての操作をログに記録し、データベースのパフォーマンスに深刻な影響を与えることに注意してください。--profile=1 を使用して、slowMs より遅い操作のみをログに記録します。次に、ベンチマークが完了したら、db.system.profile の内容を調べて、サーバーが実行した遅い操作の詳細を確認します。

これは、開始するのに役立ちます。

于 2013-02-01T18:15:02.437 に答える
1

mongo db と node js を使用するには、https://docs.mongodb.comのドキュメントに問題があることがわかりました。

これは私のために働いた:

  • プロファイリング レベルを設定するには: const set = await db.setProfilingLevel('all')

  • プロファイリングを読むには:

コード

function profile (db, limit = 10) {
  const mc = db
  return new Promise((resolve, reject) => {
    mc.collection('system.profile').find().limit(limit)
      .sort({ ts: -1 }).toArray((err, res) => {
        if (err) return reject(err)
        resolve(!!res && !!res[0] && res)
      })
  })
}
于 2018-07-02T15:38:57.907 に答える