这是db.currentOp()的输出:
> db.currentOp() { "inprog" : [ { "opid" : 2153, "active" : false, "op" : "update", "ns" : "", "query" : { "name" : "Run_KPIS", "profile" : "totals" }, "client" : ":34140", "desc" : "conn127", "threadId" : "0x7f1d0f03c700", "connectionId" : 127, "locks" : { "^cached_data" : "W" }, "waitingForLock" : true, "numYields" : 0, "lockStats" : { "timeLockedMicros" : { }, "timeAcquiringMicros" : { } } }, { "opid" : 2154, "active" : false, "op" : "getmore", "ns" : "", "query" : { }, "client" : ":34129", "desc" : "conn118", "threadId" : "0x7f1e32785700", "connectionId" : 118, "locks" : { "^cached_data" : "R" }, "waitingForLock" : true, "numYields" : 0, "lockStats" : { "timeLockedMicros" : { }, "timeAcquiringMicros" : { } } }, { "opid" : 1751, "active" : true, "secs_running" : 98, "op" : "query", "ns" : "cached_data.webtraffic", "query" : { "mapreduce" : "webtraffic", "map" : function () { if (this.Pages) for (var i in this.Pages) if (i.match(/(\/blogs\/|\/news\/)/)) emit({ 'page':i, 'profile':this.Profile },this.Pages[i]); }, "reduce" : function (k,vals) { for(var i=0,sum=0;i<vals.length;sum+=vals[i++]); return sum; }, "out" : { "inline" : 1 }, "query" : { "$or" : [ { "Profile" : "MEMBER" }, { "Profile" : "WEB" } ] } }, "client" : ":34111", "desc" : "conn112", "threadId" : "0x7f1d1768d700", "connectionId" : 112, "locks" : { "^" : "r", "^cached_data" : "R" }, "waitingForLock" : false, "msg" : "m/r: (1/3) emit phase M/R: (1/3) Emit Progress: 801/830 96%", "progress" : { "done" : 801, "total" : 830 }, "numYields" : 148, "lockStats" : { "timeLockedMicros" : { "r" : NumberLong(183690739), "w" : NumberLong(0) }, "timeAcquiringMicros" : { "r" : NumberLong(92296403), "w" : NumberLong(0) } } } ] }
我在所有相关集合上都有索引,但是当上述操作正在运行时,从MongoDB读取数据仍然有很大的延迟。
数据库重新读取可能需要5分钟的时间。
上面的map减less函数是否会导致这个读locking? 如果是这样,我怎么能运行一个非locking的地图减less收集?
奇怪的是,MongoDB仍然接受连接,在上面的操作正在运行时,它不会允许我们查询。
编辑说这是Mongo版本2.4.1。
首先,在这里运行查询。 它使用$or运算符来覆盖同一个字段的两个值。 如果这是典型的,请将其更改为$in运算符(按照此处的build议 )。 这应该有很大的帮助 – 当你使用$或者像你一样运行两个并行查询并合并结果时,当你使用一个查询。
接下来,由于这是一个内嵌的 Map Reduce作业,我build议在辅助(如果你还没有的话)上运行这个工具,并且在别的地方运行更实时的应用程序。 您可以通过多种方式来实现,但最灵活的是基于标签的读取首选项 。
在解释currentOp()输出方面,大写字母表示全局锁 ,这就是可能会阻止的东西(虽然它会尝试产生),但是你也可以看到,它花了很多时间来获取锁在首位。 我认为这代表了有关数据的大表扫描,并且数据并不全部适合RAM,并且正在从磁盘分页。 因此,该查询的产出数量(MongoDB每当发现磁盘故障时都会尝试产生)。
看一下MMS或者mongostat中的页面错误指标,看看那里的趋势,实际上MMS可能是一个很好的地方,可以看到这个实例在整体上随着时间的推移发生了什么。
上面这个$in的变化应该对此有所帮助,但是可能只能在路上走。 如果要在大量数据上进行聚合,则需要将其存储在快速存储的RAM中,或者需要将其存储到辅助存储中,以便慢速访问磁盘不会将所有数据它。