mongodb表现不佳

时间:2012-01-30 10:55:59

标签: java performance 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服务器)。当然所有读取都会进入辅助节点并写入主节点。 我没有测试分片,因为我认为6,000,000不是一个巨大的收藏,不是吗?

此外,我运行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})

我对查询中的非法“点”有错误

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

非常感谢 朱莉娅

2 个答案:

答案 0 :(得分:5)

MongoDB有一个global write lock。这意味着一次只能进行一次更新。

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

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

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

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

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

答案 1 :(得分:1)

有关更新,请查看positional operator

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

要了解查询的费用,请使用explain并确保查询有效。