关于Rails上的ruby:具有自动过期密钥的俄罗斯娃娃片段缓存-性能的优缺点

Russian doll fragment caching with auto expiring keys - performance pros and cons

该问题基于2篇文章:
-DHH来自37signals的Basecamp Next
-Rails中的高级缓存by Adam Hawkins

对于使用俄罗斯玩偶缓存的性能影响,我有些困惑,特别是:

  • 使用自动失效密钥时,似乎每个请求都将导致对数据库的访问以获取对象时间戳-我是否缺少某些东西? (我知道,在最佳情况下,您只需要对层次结构中的顶级键执行此操作,但仍然...)

  • 在第一篇文章中,他们缓存了一个待办事项列表以及每个待办事项。缓存列表非常合理,因为它可以节省大量工作(所有项目的数据库查询)。但是为什么要缓存单个项目?您已经在数据库中获取Item时间戳,那么您到底要保存什么?生成几行HTML代码?

  • 在第二篇文章中,Adam像这样缓存视图的大块:
    cache [post, 'main-content'] ...
    cache [post, 'comments']
    添加评论后,它会更改发布的时间戳记,因此会使全部消息无效。但是,main-content并没有改变-您不想重新生成它!!!如何使仅注释无效。 (这实际上是一个非常常见的用例-一个模型,该模型具有几个逻辑上独立的部分:对象本身,不同的关联,其他存储中的数据等)。

  • 在我看来,仅当您具有嵌套对象的较深层次时,俄罗斯玩偶缓存才有意义。但是,如果您的层次结构较浅,则最好自己进行失效处理。

    任何反馈将不胜感激!
    谢谢。


  • 顶级确实需要访问数据库。您可以通过将时间戳存储在单独的缓存条目中来避免这种情况,该条目由型号和ID键控。关于第1条的评论者之一(Manuel F. Lara)提出了相同的建议:"是否还有另一个缓存(例如project / 15-time),您始终具有项目列表的最后一个时间戳?"

  • 我认为您对嵌套中的"最低"级别是正确的。您可能需要进行一些测试,以查看数据库访问与呈现微小部分之间的相对性能。

  • 另一个好处。根据rails docs的说明,如果将符号传递给:touch,则除了updated_at之外还将更新该属性-也许有一种方法可以跳过更改Post#updated_at的操作,而仅更新诸如comments_updated_at的列。然后,您可以使用后者进行缓存。但是,如果要避免访问数据库,则必须为此时间戳存储另一个缓存键(例如上面的#1)。

  • 我想您必须确定所有这些是否值得您为之烦恼。这两篇文章展示了一些简单的,人为的例子来教授这些原理。在具有复杂关联的应用程序中,"分代"缓存方法可能更易于管理。


  • 是的。但是通常最好的情况和相当好的情况都会经常出现。
  • 是的。在我开发的某些应用中,渲染视图所需的时间是执行查询的10到20倍。查看您的基准。
  • 如果渲染帖子的成本很高,则您可能不想触摸该帖子,而是从[@post.comments.max(:updated_at), @post.comments.size]组成评论列表的缓存键。