【问题标题】:Rails: Cache or not CacheRails:缓存或不缓存
【发布时间】:2018-04-17 19:32:24
【问题描述】:

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

如果数据经常变化是缓存的好策略?

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

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

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

谢谢

【问题讨论】:

    标签: ruby-on-rails ruby performance caching


    【解决方案1】:

    简短回答:当缓存键无效时缓存会更新。在您的情况下,当特定帖子的 updated_at 字段晚于缓存中的内容时,缓存将被更新。需要注意的是,缓存更新发生在第一次渲染视图中的新数据时,而不是在数据库中更新数据时。

    详细回答:我强烈建议您阅读Caching with Rails 了解基础知识。

    问题中发布的代码块使用Rails' Fragment Cachingcache product 调用将生成一个缓存键,它是post.idpost.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 记录的updated_at 字段,则缓存提供的数据将无效。通过将touch: true 添加到belongs_to 关联来解决此问题:

    Class Comment < ActiveRecord:base
      belongs_to :post, touch: true
      ...
    end
    

    上述代码将在其 cmets 之一发生更改时更新 post 记录的 updated_at

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

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

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

    【讨论】:

      猜你喜欢
      • 2018-04-04
      • 1970-01-01
      • 2012-03-06
      • 2020-04-22
      • 1970-01-01
      • 2016-08-13
      • 2012-06-05
      • 2010-11-22
      • 1970-01-01
      相关资源
      最近更新 更多