【问题标题】:How does Rails fragment caching work?Rails 片段缓存是如何工作的?
【发布时间】:2015-12-24 23:42:03
【问题描述】:

我刚刚开始在生产应用程序中使用缓存来加快速度。我已经阅读了主要的 Rails 指南、各种博客、源代码本身等。但是当谈到片段缓存时,我的头脑仍然不清楚一件简单的事情:

更新对象后销毁缓存时,是只更新单个对象,还是类?我认为只是单个对象。

这是一个例子:

<% @jobs.each do |job| %>
   <% cache("jobs_index_table_environment_#{session[:merchant_id]}_job_#{job}") do %>
    stuff
   <% end %>
<% end %>

我在我的工作索引页面中使用了上面的代码。每一行都呈现了一些用户想要的信息、一些 CSS、可单击以查看单个作业等。

我在我的 Job 类(模型)中写了这个

after_save do
    Rails.cache.delete("jobs_index_table_environment_#{merchant_id}_job_#{self}")
  end

  after_destroy do
    Rails.cache.delete("jobs_index_table_environment_#{merchant_id}_job_#{self}")
   end

如果单个作业对象被更新或销毁,我希望从缓存中销毁它们,当然,新创建的作业在页面上第一次弹出时会获得自己的缓存键。

我不会用@jobs 做俄罗斯娃娃的事情,因为这是我的“上帝”对象,并且一直在变化。缓存几乎永远不会有帮助,因为集合可能会按分钟变化。

我的理解是否正确,在上面的视图中,如果我将 25 个作业渲染到第一页,我将使用缓存键在我的缓存中获得 25 个对象,然后如果我只更改第一个,它会被缓存value 会被销毁,下次加载作业页面时,它会被重新缓存,而其他 24 个只会从缓存中拉出?

【问题讨论】:

  • 如果您阅读终端输出,您将看到“写入片段”或“读取片段”的行。我认为检查出来会帮助你弄清楚你的代码在做什么。

标签: ruby-on-rails ruby-on-rails-3 caching dalli


【解决方案1】:

我也是片段缓存的新手,我刚刚遇到了一个非常相似的用例,所以我觉得我的(有限的)知识足够新鲜,可以提供帮助。

Trosborn 是正确的,您的终端会在您读取和写入时突出显示,这会显示您在缓存中获得了多少“命中”。它应该只在您更改对象时写入。根据我在上面看到的,您的删除只是删除个别记录。

不过,我认为有一种可能更简单的方法来实现这一点,即将 ActiveRecord 对象传递给缓存,例如:

<% @jobs.each do |job| %>
   <% cache(job) do %>
    stuff
   <% end %>
<% end %>

阅读this post from DHH 了解其工作原理。简而言之,当一个 AR 对象被传递到缓存时,不仅会在模型名称上生成密钥,还会在 idupdated_at 字段上生成密钥。

当内存耗尽时,过时的片段最终会被推出缓存,因此您无需担心删除旧的缓存对象。

【讨论】:

  • 在我的情况下,复杂性在于“作业”会在各个页面上呈现,实际上,当我尝试您所说的方法时,我得到了 CSS 和作业/索引的所有其他信息,例如,客户/显示该工作属于特定客户的位置。仅将 AR 对象提供给缓存是不够的。
  • 您可以使用用户:cache [current_user, job] 来补充缓存键,或者可能使用特定于视图的字符串作为键的前缀:cache ["this one view", current_user, job]。这样能行吗?
  • 这是我在最初的帖子中已经完成的。问题是“缓存是使所有 25 条记录无效还是仅使更改的记录无效?”我为各个页面正确设置了唯一键。
  • 你完全正确。这就说得通了。不,它只会使个人记录无效。不过,同样,您根本没有必须删除缓存。无效的(由 AR 时间戳确定)将被推出。我不认为这个选择有什么本质上的错误。这并不是绝对必要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-18
  • 1970-01-01
  • 1970-01-01
  • 2015-05-31
  • 2014-08-02
  • 1970-01-01
  • 2012-03-07
相关资源
最近更新 更多