俄罗斯娃娃片段缓存与自动过期密钥 - 性能的利弊

时间:2012-10-12 17:07:27

标签: ruby-on-rails fragment-caching 37-signals

问题基于2篇文章:
- 来自37signals的DHH的 Basecamp Next
- Adam Hawkins的 Advanced Caching in Rails

我对使用俄语玩偶缓存的性能影响有点困惑,具体来说:

  1. 使用自动过期密钥时,似乎每个请求都会导致访问数据库以获取对象时间戳 - 我错过了什么吗? (我知道在最好的情况下,你必须只对层次结构中的顶级密钥执行此操作,但仍然......)

  2. 在第1篇文章中,他们会缓存待办事项清单以及每个待办事项。缓存列表非常有意义,因为它节省了大量工作(所有项目的数据库查询)。但为什么要缓存单个项目?您已经访问数据库以获取Item时间戳,那么您究竟要保存什么?生成一些html行?

  3. 在第二篇文章中,Adam缓存了大量的视图: cache [post, 'main-content'] ... cache [post, 'comments'] 添加注释后,它会更改帖子的时间戳,因此会使两个队列无效。但是,main-content没有改变 - 你不想再生它!如何才能使评论无效。 (这实际上是一个非常常见的用户案例 - 一个具有一些逻辑上独立的部分的模型:对象本身,不同的关联,其他商店中的数据等)

  4. 对我而言,只有当您拥有嵌套对象的深层次结构时,俄罗斯玩偶缓存似乎才有意义。(在basecamp中,您有project-> todos list - > todo - > items list)。但是,如果您的层次结构较浅,则最好自己进行无效。

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

2 个答案:

答案 0 :(得分:6)

  1. 顶层确实需要访问数据库。您可以通过将时间戳存储在单独的缓存条目中来避免这种情况,该条目由model和id键入。第1条评论者之一(Manuel F. Lara)提出了同样的建议:“是否有另外一个像项目一样的缓存/ 15次你总是有项目清单的最后一个时间戳?”

  2. 我认为你对嵌套中的“最低”水平是正确的。您可能需要进行一些测试,以查看数据库访问与呈现微小部分的相对性能。

  3. 另一个好处。根据rails文档,如果您将符号传递给:touch,除了updated_at之外,它还会更新该属性 - 可能有一种方法可以跳过更改Post#updated_at并仅更新列comments_updated_at。然后您可以使用后者进行缓存。但是,如果您试图避免数据库访问,则必须为此时间戳存储另一个缓存密钥(如上面的#1)。

  4. 我想你必须决定这一切是否值得给你带来麻烦。这两篇文章展示了教授这些原则的简单,人为的例子。在具有复杂关联的应用程序中,“世代”缓存方法可能更易于管理。

答案 1 :(得分:2)

  1. 是。但通常会出现最佳情况和非常好的情况。
  2. 是。在我开发的一些应用程序中,渲染视图所需的时间是执行查询的10-20倍。看看你的基准。
  3. 如果呈现帖子的费用很高,您可能不想触及帖子,而是从[@post.comments.max(:updated_at), @post.comments.size]撰写评论列表的缓存键。