0

我们有一个系统,我们希望在其中维护大量记录信息的统计信息,这些信息拆分到单独的通道中,每个通道都有一个概览文档,以级联方式维护统计信息,包括小时、天、月和年的最大值和最小值。

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

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

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

所以我们正在寻找关于最佳解决方案的评论/建议(我们不一定会保留原始数据,因此不能选择后处理)

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

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

  3. 还有其他方法吗?

非常感谢您的帮助。

4

1 回答 1

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/ Mongo 通讯文章 2010 年 12 月

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

于 2012-07-06T17:43:58.440 回答