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

Eug*_*eMi 12 ruby-on-rails fragment-caching 37-signals

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

我对使用俄罗斯娃娃缓存的性能影响有点困惑,具体来说:

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

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

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

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

对于任何反馈,我们都表示感谢!
谢谢.

Kel*_*vin 6

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

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

  3. 另一个好点.根据rails文档,如果你传递一个符号,:touch它将更新该属性除了updated_at- 也许有一种方法可以跳过更改Post#updated_at并只更新列comments_updated_at.然后您可以使用后者进行缓存.但是如果你试图避免数据库访问,你将不得不为这个时间戳存储另一个缓存键(如上面的#1).

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