mongodb表现不佳

我目前正在使用mongodb,我看到查询的性能非常差(可能需要几秒钟)。 方案如下:

我有一个结构文件:

{_id:"xxx", userId:"yyy", a:1 ,b:2, counter:1} 

在测试中:

 "userId" value could be {1..200,000} "a" values could be {1..30} "b" values could be {1} 

因此,我的最大大小集合将为6,000,000。目前,为此集合定义了两个索引: default _id and useId

业务逻辑查询所有用户条目,然后通过递增计数器来更新一个特定用户条目(查询更新由“_id”写入)。 此外,如果这是一个新实体,则有一个插入查询。

我在ubuntu上使用mongo 1.8.2和8g ram运行

我有一个主辅助复制(所有mongo运行本地磁盘存储和一个子网与tomcat服务器)。 当然所有的读取都是二级的,并写入master。 我没有测试分片,因为我认为6,000,000不是一个巨大的collections,不是吗?

另外,我运行jmetter测试,一次使用不同的userIds生成500个线程请求。

当我运行mongostat时,我看到%锁定非常高(大约70%),大约5-10分钟的加载后我看到qw(写入队列)是500(作为我打开的连接的数量)当我停止服务器需要mongo大约10-20分钟来完成所有排队的任务

我也运行了db.serverStatus()并解释,结果看起来很好。 当我运行db.currentOp()时,我看到等待’write’锁定的查询我无法将currentOp的输出文件完全分析,因为我从命令行执行查询并且只有窗口缓冲区尺寸。 但是从那里我看到了许多等待写锁的更新(通过_id)。

我会感激任何想法。

还有一件事:因为每个查询可能会带来30个文档,我认为可能会有不同的moddeling如下:

 {_id:"xxx", userId:"123", bs: [{b:1, cs[{c:1, cnt:1}, {c:2, cnt:1}}, {{b:2 cs: [{c:1, cnt:1}]}}] 

但是当我尝试这种建模时,我无法增加计数器,我只是没有找到正确的方法来做到这一点。 我可以做插入和推芽无法更新以下查询:

 db.coll.update({userId:"123", "bs.b":1, "bs.cs.c":1}, {"bs.cs.cnt" : {$inc : 1}) 

我在查询中有关于非法“点”的错误

我现在很累。 等待一些好主意

非常感谢
朱莉娅

MongoDB具有全局写锁定 。 这意味着一次只能进行一次更新。

db.serverStatus()命令可以帮助您诊断全局写锁定的问题。

以下是您可以尝试的一些事项:

1)确保你使用的是mongodb 2.0。 它比旧版本具有更好的并发性。 2.2将具有更好的并发性。

2)对您的写入进行排队,使它们是异步的,并使用单个线程执行所有操作。 这可能有助于并发,因为通常一次只有一个线程会尝试使用全局写锁。

3)如果您使用的是最新版本,并且无法使用单线程编写,则请考虑分片。 分片不仅仅是大小; 它对于写并发性至少同样重要。 如果您进行了分片,那么每个段将在其自己的进程中运行,并具有自己的全局写锁定。 这将允许整个系统处理更多写入。

要更新,请查看位置运算符 :

 db.coll.update({userId:"123", "bs.b":1, "bs.cs.c":1}, {"bs.$.cs.$.cnt" : {$inc : 1}) 

要了解查询的成本,请使用说明并确保查询有效。