我正在尝试使用缓存,但我想知道是否有可能缓存频繁更改的数据。
如果数据更改通常会缓解一个好的策略?
如果我使用片段缓存缓存帖子列表,并且用户编辑他的帖子,缓存会自动上传吗?缓存如何处理个性化数据? (例如,带有current_user.data eccc的页面)
在这种情况下,更新@posts会自动缓存上传吗?
<% @posts.each do |post| %>
<% cache post do %>
<%= render partial: 'shared/post_list', locals: {post: post} %>
<% end %>
<% end %>
谢谢
答案 0 :(得分:4)
简答:缓存密钥无效时缓存会更新。在您的情况下,当特定帖子的updated_at
字段晚于缓存中的字段时,将更新缓存。请务必注意,缓存更新是在第一次呈现视图中的新数据时发生的,而不是在数据库中更新数据时发生的。
长答案:我强烈建议您阅读基础知识Caching with Rails。
问题中发布的代码块使用Rails' Fragment Caching。 cache product
调用将生成一个缓存键,该缓存键是post.id
,post.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 %>
缓存比此处描述的要多得多。我建议您阅读本文中链接的指南,以便全面了解缓存验证。您可以通过缓存显着提高服务器速度。在某些情况下,我看到服务器响应时间下降了一个数量级。但是,除非您小心,否则最终可能会在缓存中提供过时日期。