【问题标题】:Maintaining consistency of mongodb data维护mongodb数据的一致性
【发布时间】:2013-08-13 22:03:34
【问题描述】:

在以下两个选项中维护 MongoDB 中数据一致性的最佳实践、权衡或有效性是什么?

  1. 使用 cron 作业进行手动缓存(也就是存储冗余数据并使用脚本定期传播更改)
  2. 每次动态加载数据,但有缓存层(或利用内置的 mongodb 缓存)

例如,假设有commentsusers。使用选项 1,每个 comment 将包含:

{
    user_id:
    user_displayname:
    user_gravatar:
    [comment fields]
}

如果user 决定更改他或她的显示名称,user 对象会更改,但脚本也会运行所需的 MongoDB 命令来更新所有usercomments 以反映更改。

使用选项 2,每个 comment 将包含:

{ 
    user_id:
    [comment fields]
}

如果user 决定更改他或她的显示名称,它只会在user 对象本身中更改。当comment 被访问而不命中缓存时,它会将user 对象与缓存中的comment 对象相关联。这样以后,如果在此comment 仍在缓存中时再次访问它,则usercomment 查询都将被跳过。 (我基本上是在描述内置的 MongoDB 缓存吗?)

是否值得做选项 1 中描述的数据冗余?或者 MongoDB 是否足够聪明以至于已经缓存了额外但等效的查询?或者是否值得使用 Redis 等其他东西自己制作缓存层?

谢谢!

【问题讨论】:

    标签: mongodb caching


    【解决方案1】:

    MongoDB 本身没有“缓存”。 MongoDB 使用内存映射文件,它的性能很大程度上取决于它是否可以将最常用的文档(应用程序的“工作集”)映射到主内存中,而不是在访问之前从磁盘中分页每个文档。

    您正在描述非规范化数据库设计,其中每个文档都包含规范化形式中不存在的属性。这是有道理的,而且它实际上是 MongoDB 的一种非常常见的技术,如果它允许您在一次操作中获取所需的所有数据,而不必执行多个查询。

    正如您所指出的,缺点是它需要更昂贵的更新,因为您需要更新所有已将特定属性非规范化的文档。不利的一面是,如果您的文档较大,将工作集保存在内存中可能会更加困难。

    因此,答案取决于您的数据访问模式。通常,如果您的应用程序读取量很大,并且往往需要将所有这些非规范化属性放在一起,那么非规范化方法是一个不错的选择。如果应用程序的写入量很大,特别是如果它频繁更新这些特定属性,那么非规范化不是一个好的选择。

    【讨论】:

      【解决方案2】:

      如果您谈论的是用于 100 GB 数据的缓存机制,那么您谈论的是一种严重的权衡。任何小于 5 GB 的数据,权衡都无关紧要。在 100GB 和 5GB 之间,有一个灰色区域。

      您的数据最糟糕的情况是:

      200 GB 数据。每秒 4,000 次读取。拥有 9,000 cmets 的用户更改了他/她的名字。您的应用程序还会根据此名称值索引 cmets。然后,您的应用程序必须更新 9,000 个 cmets 和 9,000 个索引键。这将在您的应用程序中造成一段时间的严重拖累。

      那么,我们还必须针对像 cmets 上的名称这样简单的问题提出问题:“您必须更新旧 cmets 上的名称吗?”

      当您在 Twitter 上关注新人时,您过去的时间线不会继承此人过去的推文。只有你的新时间线。与 cmets 一样,为什么要在过去的 cmets 上更新此人的姓名?

      所以,我会在您的列表中添加 #3:“不要更新用户名”

      【讨论】:

        猜你喜欢
        • 2016-04-13
        • 2011-06-15
        • 1970-01-01
        • 2015-12-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-21
        • 1970-01-01
        相关资源
        最近更新 更多