以分片mongodb保留文件

时间:2014-02-01 15:31:52

标签: mongodb horizontal-scaling

我在mongodb中有一个分片的文档集,还有几个访问它的应用程序服务器。

每个应用程序都提供新文档,最终还需要删除一些文档。

删除哪些文件并不重要,但关键是它删除(声明)一个确切的数字,并且没有其他应用程序正在删除(声明)相同的文档。

我的想法是:

unique = makeUniqueValue()
docs = []

for (i = 0;i < 10;i++) {
    r = findAndModify( claim: false, $set: { claim: unique });
    if (r.value) docs.push(r);
}

if (docs.length < 10)
    "release all docs by updating (claim: false) and try again in some time"

此解决方案的一个潜在问题是,由于应用程序太多(文档很少),他们只会继续声明某些文档并再次发布它们。

这个问题的众所周知且经过充分测试的解决方案是什么?

“update”和“findAndModify”是否保证更新的文档在更新前与查询匹配?

或者另一个应用程序是否可以在匹配和更新之间“窃取”它,因此两个应用程序都认为他们已经声明了该文档?

1 个答案:

答案 0 :(得分:1)

在该文档上运行更新后,它将确保查询与文档匹配,并且它是最新版本。

任何其他程序都无法在每个文档的基础上窃取。

为了进一步解释,因为我意识到这个问题很简单:MongoDB在数据库级别上有一个写作者贪婪的读/写锁。

这意味着findAndModify在写入操作被赋予运行能力时将无法找到某些内容。因此,它无法找到即将在另一个线程/应用程序中声明的文档。

因此,此代码会立即将文档声明隔离到一个应用程序,因为另一个应用程序对循环的每次迭代都会导致无人认领的文档,而MongoDB服务器上永远不会出现中间/部分状态。

实际更新时无关紧要,因为您知道这些文档是您需要更新的文档,但是$set等运算符在单个文档上按顺序运行,因为更新操作本身不能文档状态要么是claim false,要么是空。更新还将直接从数据文件中选取行,而不是从写出的静态结果集中选择行。

如果您使用_id或其他静态数据进行更新,则会有所不同。