自动过期键的俄罗斯套娃片段缓存——性能优缺点

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

我有点困惑于使用俄罗斯套娃缓存的性能影响,具体如下:
  1. 使用自动过期键时,似乎每个请求都会导致访问数据库以获取对象时间戳。 我错过了什么吗?(我理解,在最佳情况下,您只需要为层次结构中的顶层键执行此操作,但仍然...)

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

  3. 在第二篇文章中,亚当像这样缓存视图块:cache [post, 'main-content']... cache [post,'comments']。 当添加评论时,它会更改帖子的时间戳,从而使两个条目无效。 但是,“main-content”没有更改-您不想重新生成它! 如何仅使评论无效?(这实际上是一个非常常见的用例-具有几个逻辑独立部分的模型:对象本身,不同的关联,其他存储中的数据等)

对我来说,只有当您具有深层次的嵌套对象时,俄罗斯套娃缓存才有意义。(在basecamp中,您有project->todos列表->todo->项目列表)。 但是,如果您具有浅层次结构,最好自己进行无效处理。
任何反馈都将不胜感激!
谢谢。

更多讨论请参见这里 - Kelvin
2个回答

6
  1. 顶层确实需要访问数据库。您可以通过将时间戳存储在单独的缓存条目中,以模型和ID为键来避免这种情况。文章1的评论者之一(Manuel F. Lara)提出了同样的建议:"是否有另一个缓存,像projects/15-time,你总是拥有项目列表的最后一个时间戳?"

  2. 我认为你关于嵌套中的“最低”级别是正确的。您可能需要进行一些测试,以查看DB访问与渲染小部分之间的相对性能。

  3. 另一个很好的观点。根据Rails文档,如果您将符号传递给:touch,它将更新该属性以及updated_at -也许有一种方法可以跳过更改Post#updated_at,只更新像comments_updated_at这样的列。然后,您可以将后者用于缓存。但是,如果您试图避免DB访问,那么您将不得不为此时间戳存储另一个缓存键(就像上面的#1)。

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


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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接