保持mongodb数据的一致性

时间:2013-08-13 22:03:35

标签: mongodb caching

以下两个选项在MongoDB中保持数据一致性的最佳做法或权衡或有效性是什么?

  1. 使用cron作业进行手动缓存(也就是存储冗余数据并使用脚本定期传播更改)
  2. 每次动态加载数据但具有缓存层(或利用内置的mongodb缓存)
  3. 例如,假设有commentsusers。使用选项1,每个comment将包含:

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

    如果user决定更改其显示名称,user对象将更改,但脚本将运行所需的MongoDB命令以更新所有user的{​​{1}} comments 1}}反映变化。

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

    { 
        user_id:
        [comment fields]
    }
    

    如果user决定更改其显示名称,则只会在user对象本身中进行更改。在不访问缓存的情况下访问comment时,它会将user对象与缓存中的comment对象相关联。将来,如果在comment仍在缓存中时再次访问user,则会跳过comment和{{1}}个查询。 (我基本上是在描述内置的MongoDB缓存吗?)

    是否值得完成选项1中描述的数据冗余?或者MongoDB足够智能,已经缓存了额外但等效的查询?或者是否值得使用像Redis这样的其他东西自己制作缓存层?

    谢谢!

2 个答案:

答案 0 :(得分:1)

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

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

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

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

答案 1 :(得分:1)

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

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

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

然后,我们还必须提出一些问题,就像评论上的名字一样简单:“你是否需要更新旧评论上的名字?”

当您在Twitter上关注新人时,您过去的时间表不会继承该人过去的推文。只有你的新时间表。与评论相同,为什么要在过去的评论中更新此人的姓名?

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