我应该如何使用MongoDB实现"使用对象更改"模式?

Hav*_*c P 6 mongodb

我有一组对象,假设它们是"帖子",并且可以修改这些对象.我想在客户端显示一个动态更新的列表.所以在客户端,如果通过轮询执行此操作,客户端将调用以下API:

getPostsChangedSince(serial)
Run Code Online (Sandbox Code Playgroud)

哪里serial可能是一个单调递增的数字,可能是一个时间戳.客户端返回自那时以来已更改的帖子列表,存储新的最新序列,以及下次客户端轮询它自最新序列以来的请求更改.

我认为这个问题(关于ASP.NET)的基本思想是一样的:如何使用ADO.NET数据服务实现"获取最近更改的项目"?

我正在尝试找到在MongoDB中实现它的最佳方法.

我喜欢将时间用于串口的想法,因为即使有多个应用服务器,它至少可以自动正常工作.序列将存储在每个post对象中,并在对象被修改时更新.

基于时间戳的序列可以实现为:

解决方案中的一些不错的功能包括:

  • 确保创建然后立即更新OS定时器分辨率内​​的对象仍然会增加序列,尽管它是同一时间
  • 更好的是保证所有对象的全局单调增加,而不仅仅是保证更改给定对象会撞击该对象上的序列(没有这个,getPostsChangedSince()调用可能需要及时向后模糊,以避免遗漏更改 - 在两次变更的价格)
  • mongodb-side时间戳可能很好,因为在应用程序中获取时间会在您获得时间和保存新对象以及查询中可用时间之间产生差距
  • 使用包含旧序列的查询使用findAndModify()更新,因此"冲突"(一次两次更改)将引发错误,允许应用重试

我意识到这里的一些角落案件有点"学术性",很可能在现实生活中被捏造.

到目前为止我的方法是:

  • 使用序列的日期类型
  • 修改对象时,获取当前时间,如果它与对象的旧序列匹配,则添加1毫秒(如果快速进行两次修改而不从mongodb重新获取,则会中断,但这似乎没问题)
  • 使用findAndModify(),但是基于https://jira.mongodb.org/browse/JAVA-276,可能没有办法检测它是否最终没有找到任何要修改的内容(即,如果是冲突)

问题:

  • 我觉得我应该使用Timestamp; 真正?有任何缺点吗?
  • 如果你有一个mongo集群,那么以毫秒为单位的时间可能比Timestamp的时间(以秒为单位)加上一个数字更加独特和正确,而有一个mongod时间戳更独特吗?
  • 有没有办法检测findAndModify()是否更新了什么?
  • 有关这个问题的一般建议/经验吗?你会怎么做?

小智 0

您是否考虑过“外部化”序列号生成器?MongoDB 的时间精度很好,但在涉及多台机器时可能会变得难以同步。一种选择是您可以使用 memcached 或类似的东西,它是基于内存的、速度极快并且可以序列化(memcached 有 CAS 操作)。

因此,您要做的就是在 memcached 中存储一个“种子”,并使用一个键(例如计数器)。每次应用程序需要执行插入时,它都会从 memcached 获取下一个数字并递增计数器。

再想一想,您甚至可以放弃 memcached,只使用只有计数器的单行(抱歉文档)集合。您可以获取计数器并递增它,这将是一个非常快的操作,模仿 memcached。

然后自然地,您可以适当地对数据建立索引。然而,我想知道这会导致指数非常不平衡(右侧倾斜)。根据具体情况,探索使用上限集合可能是值得的。因此,当您将数据插入主集合时,也将其插入上限集合并从该集合中读取数据。