Rails:缓存或不缓存

时间:2017-11-05 15:35:19

标签: ruby-on-rails ruby performance caching

我正在尝试使用缓存,但我想知道是否有可能缓存频繁更改的数据。

如果数据更改通常会缓解一个好的策略?

如果我使用片段缓存缓存帖子列表,并且用户编辑他的帖子,缓存会自动上传吗?缓存如何处理个性化数据? (例如,带有current_user.data eccc的页面)

在这种情况下,更新@posts会自动缓存上传吗?

<% @posts.each do |post| %>
  <% cache post do %>
    <%= render partial: 'shared/post_list', locals: {post: post} %>
  <% end %>
<% end %>

谢谢

1 个答案:

答案 0 :(得分:4)

简答:缓存密钥无效时缓存会更新。在您的情况下,当特定帖子的updated_at字段晚于缓存中的字段时,将更新缓存。请务必注意,缓存更新是在第一次呈现视图中的新数据时发生的,而不是在数据库中更新数据时发生的。

长答案:我强烈建议您阅读基础知识Caching with Rails

问题中发布的代码块使用Rails' Fragment Cachingcache product调用将生成一个缓存键,该缓存键是post.idpost.updated_at和视图模板的MD5哈希的组合。 Rails将在缓存中搜索该密钥,如果找到,将返回缓存值而不必渲染部分。这是缓存命中。如果未找到缓存键,则Rails将呈现部分并将结果存储在缓存中以供将来使用。这是一个缓存未命中。

任何缓存方案的棘手部分都是缓存验证,这就是确保缓存提供的数据有效且准确。例如,如果数据库中的数据已更改,我们希望提供数据库数据而不是过时(旧)缓存数据。

Rails解决了这个问题&#34;自动化&#34;通过构建上述缓存键。如果post记录中的数据发生更改,则post.updated_at将更新,并且将使用新的缓存密钥,这将导致缓存未命中。这是您希望在缓存中的数据旧时发生的情况。同样,如果视图模板更改,则视图的MD5哈希值将更改,缓存键也将更新,从而导致缓存未命中。

如果这可能成为一个问题,那就是shared/post_list部分引用了post记录中未捕获的数据或变量。例如,如果部分更改取决于用户是否是管理员,则您需要在缓存键中捕获用户的管理员状态。你会做这样的事情:

<% cache [post, current_user.admin?] do %>

另一个常见示例是,如果部分引用与post相关的其他数据库对象。让我们为了论证而说你的部分呈现post.comments的列表。如果评论发生更改,但该更改未触及updated_at记录的post字段,则缓存提供的数据将无效。将touch: true添加到belongs_to关联:

即可解决此问题
Class Comment < ActiveRecord:base
  belongs_to :post, touch: true
  ...
end

上述代码会在其中一条评论发生变化时随时更新post条记录updated_at

最后,Rails提供了一种称为Collection Caching的东西,这是一种渲染部分/模板集合的更有效方法。您可以在示例中通过用一行代码替换整个each循环来实现这种形式的缓存:

<%= render partial: 'shared/post_list', collection: @posts, cached: true %>

缓存比此处描述的要多得多。我建议您阅读本文中链接的指南,以便全面了解缓存验证。您可以通过缓存显着提高服务器速度。在某些情况下,我看到服务器响应时间下降了一个数量级。但是,除非您小心,否则最终可能会在缓存中提供过时日期。