【问题标题】:Reserve documents in sharded mongodb在 sharded mongodb 中保留文档
【发布时间】:2014-02-01 15:31:51
【问题描述】:

我在 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”是否保证更新后的文档与更新前的查询匹配?

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

【问题讨论】:

    标签: mongodb horizontal-scaling


    【解决方案1】:

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

    任何其他程序都不应该能够根据每个文档进行窃取。

    进一步解释一下,因为我意识到这个答案有点简单:MongoDB 在数据库级别上有一个写入器贪婪读/写锁。

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

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

    在实际更新时并不重要,因为您知道这些文档是您需要更新的文档,但是,$set 等运算符会在单个文档上按顺序运行,因为此类更新操作本身不能获取部分文档状态或者,他们要么接受claim false,要么什么都不接受。更新还将直接从数据文件中选择行,而不是从写出的静态结果集中。

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

    【讨论】:

    • 谢谢!所以要清楚; update(w/wo multi)和 findAndModify 都不能在不匹配查询的情况下更新文档?因此,我唯一的挑战是确保如果有十个或更多可用文档(我正在考虑某种排队方案),应用程序不会为了实际保留文档而争吵不休。
    • @ThomasJensen 我不明白怎么做,所有系统都应该阻止它,如果有机会那么它肯定是一个错误
    猜你喜欢
    • 2019-12-12
    • 2018-02-02
    • 2016-02-14
    • 1970-01-01
    • 1970-01-01
    • 2017-06-24
    • 2014-07-18
    • 1970-01-01
    • 2020-01-03
    相关资源
    最近更新 更多