NodeJS + Mongodb性能问题

我有一个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进行基准testing时,发现当并发连接数大于20(甚至2个或更多的并发连接似乎线性增加时间)时,它会挣扎(时间> = 1秒):

 [ { "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条logging),并且集合都被相应地索引到查询。

我被卡住的想法,任何人都知道为什么performance如此糟糕?

编辑:

对于一个简单的查询如:

 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反对它,数据库被损坏,与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版本:

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

除了默认的nodejs驱动程序poolSize为1,mongod是否允许限制并发连接的数量?

珠珠,一堆东西:

  • 你有没有尝试从mongo shell查询? 你可以尝试在shell中运行它,还可以使用.explain()函数来了解服务器的执行时间吗? 这将帮助您validation您的索引是否正确,并应帮助隔离性能问题是否在客户端或服务器端。

  • 你有写在同一时间吗? 这段代码是在基准testing运行时为数据库提供了唯一的工作负载,还是同时出现了这种情况呢?

  • 运行基准testing时,使用mongostat实用程序(请参阅mongodb文档)。 这会让你知道服务器正在做什么。 尤其要看locking%和qr / qw列。 qr / qw列告诉你有多less个读写操作正在排队(即被阻塞并等待执行)。

  • 请注意,将mongo服务器分析器打开到级别2(–profile = 2)将导致服务器logging所有操作,严重影响数据库性能。 使用–profile = 1只logging慢于slowMs的操作。 然后,在完成基准testing后,查看db.system.profile的内容,了解服务器执行的任何慢速操作的详细信息。

这应该可以帮助你开始。