我正在尝试使用缓存,但我想知道是否有可能缓存频繁变化的数据。
如果数据经常变化,缓存是一个好策略吗?
如果我缓存带有片段缓存的帖子列表,而用户编辑他的帖子,那么缓存是自动上传的吗?缓存是如何处理个性化数据的?(例如,带有current_user.data的网页)
在这种情况下,是否会在@post更新时自动上传缓存?
<% @posts.each do |post| %>
<% cache post do %>
<%= render partial: 'shared/post_list', locals: {post: post} %>
<% end %>
<% end %>谢谢
发布于 2017-11-05 16:12:29
简短回答:缓存将在缓存键无效时更新。在您的示例中,当特定post的updated_at字段晚于缓存中的内容时,缓存将被更新。请注意,缓存更新是在视图中的新数据首次呈现时发生的,而不是在数据库中更新数据时发生的。
长篇回答:,我强烈建议您阅读带Rails的缓存的基本知识。
在问题中发布的代码块使用Rails片段缓存。cache product调用将生成一个缓存键,它是post.id、post.updated_at和视图模板的MD5哈希的组合。Rails将在缓存中搜索该键,如果找到,将返回缓存值,而不必呈现部分。这是一个缓存命中。如果没有找到缓存键,那么Rails将呈现部分,并将结果存储在缓存中供以后使用。这是一个缓存丢失。
任何缓存方案的棘手部分是缓存验证,即确保缓存提供的数据是有效和准确的。例如,如果数据库中的数据发生了更改,我们希望提供数据库数据,而不是陈旧的(旧的)缓存数据。
Rails通过构建上面描述的缓存键“自动”解决了这个问题。如果post记录中的数据发生变化,那么post.updated_at将被更新,并将使用一个新的缓存键,这将导致缓存丢失。当缓存中的数据陈旧时,这就是您想要的结果。同样,如果视图模板发生变化,则视图的MD5哈希将发生变化,缓存键也将被更新,从而导致缓存丢失。
这可能成为一个问题,如果shared/post_list部分引用了post记录中没有捕获的数据或变量。例如,如果部分更改取决于用户是否是管理员,则需要在缓存键中捕获用户的管理员状态。你会做这样的事:
<% cache [post, current_user.admin?] do %>另一个常见的例子是,如果部分引用了与post相关的其他数据库对象。让我们来讨论一下,您的部分呈现了一个post.comments列表。如果注释发生更改,但该更改没有触及post记录的post字段,则缓存提供的数据将无效。通过将touch: true添加到belongs_to关联中,可以解决此问题:
Class Comment < ActiveRecord:base
belongs_to :post, touch: true
...
end上面的代码将在post记录的注释更改时随时更新它的updated_at。
最后,Rails提供了一个名为集合缓存的东西,它是一种更有效地呈现部分/模板集合的方法。您可以在示例中通过用一行代码替换整个each循环来实现这种形式的缓存:
<%= render partial: 'shared/post_list', collection: @posts, cached: true %>缓存比这里描述的要多得多。我建议您阅读这篇文章中链接的指南,以便您对缓存验证有一个全面的了解。通过缓存,可以大大加快服务器的速度。在某些情况下,我看到服务器响应时间下降了一个数量级。但是,除非您很小心,否则您可能会在缓存中提供过期日期。
https://stackoverflow.com/questions/47123360
复制相似问题