【问题标题】:Best way to maintaining a cascaded set of Max/Min stats in MongoDB在 MongoDB 中维护一组级联的 Max/Min 统计数据的最佳方法
【发布时间】:2012-07-04 11:37:39
【问题描述】:

我们有一个系统,我们希望在其中维护拆分为单独通道的大量记录信息的统计信息,每个通道将有一个概述文档维护统计信息,包括小时、天、月和年的最大值和最小值层叠时尚。

我们可以维护一个文档来保存一个月的频道统计信息,其中将有一个每月最大/最小、31 个每日最大/分钟和 24 小时最大分钟的每一天。

使用 $inc 进行计数的文档非常适合就地原子更新,更新修饰符上的 $max 和 $min 可以解决我们的问题,但遗憾的是不可用。

我们可以将 max 和 min 保留在任务处理器中并发出 $set ,但这在协调系统中所有任务处理器(可能在不同的机器上)时存在问题,因此我们决定保留 mongo 作为主要参考。此外,在不同任务处理器实例上同时运行的两个单独任务可能会更新相同的统计信息。

因此我们正在寻找关于最佳解决方案的评论/建议(我们不一定会保留原始数据,因此无法进行后期处理)

  1. 每次我们需要更新时都读取、更新和保存?

  2. 使用 db Eval 执行 JavaScript 服务器端,通过传入单个值来更新 max/man 级联?

  3. 还有其他方法吗?

非常感谢您的帮助。

【问题讨论】:

    标签: mongodb


    【解决方案1】:

    我认为您正在寻找乐观锁定。您可以通过在文档中存储版本字段来确保更新是原子的。考虑以下示例:

    {_id: xyz, version: 2, max: 10}
    

    首先找到文档:

    db.example.find({_id:xyz})
    

    存储版本号并确定(客户端)是否需要更新最大值。如果是这样,

    db.example.update({id:xyz, version: 2}, {$set: {max: 12}, $inc: {version: 1}})
    

    如果版本在查询和更新发生之间发生更改,则此更新将失败,从而防止与并发相关的数据损坏。您可以使用 getLastError 来确定更新是否失败,然后从第一步开始重试。

    您应该避免使用 db.eval(),因为此操作需要全局锁。

    有关乐观锁定的其他资源可在此处找到: http://www.mongodb.org/display/DOCS/Atomic+Operations#AtomicOperations-%22UpdateifCurrent%22 http://code.google.com/p/morphia/wiki/MongoNewsletterArticleDec2010

    MongoDB 并发文档:http://www.mongodb.org/display/DOCS/How+does+concurrency+work

    【讨论】:

    • 感谢 Jenna,这几乎是我现在想出的确切解决方案,很高兴得到验证!我在这里看到了单个最大值的解决方案cookbook.mongodb.org/patterns/track_max_value_in_array,但是因为我有多个字段可能会使用 FindAndModify 的版本或修订号进行更新可以解决这个问题,非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2017-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-27
    • 2016-12-17
    • 1970-01-01
    • 2014-10-13
    相关资源
    最近更新 更多