9

观察者和清扫者从 Rails 4 中移除。很酷。但是缓存和清除缓存的方法是什么?

我读到了俄罗斯娃娃缓存。它很好,但它只涉及视图渲染缓存。它不会阻止数据库被击中。

例如:

<% cache @product do %>
  Some HTML code here
<% end %>

您仍然需要@product从 db 获取它的cache_key. 所以页面或动作缓存对于防止不必要的负载仍然很有用。

我有时可以使用一些超时来清除缓存,但如果记录没有改变怎么办?

至少对于扫地机,您可以控制这方面。什么是/将是做缓存和清除它的正确方法?

谢谢 !:)

4

1 回答 1

8

欢迎来到计算机科学中的两个难题之一,缓存失效 :)

您必须手动处理该问题,因为缓存对象的逻辑与缓存视图不同,缓存视图可以简单地从它显示的对象派生,应该失效是应用程序和情况相关的。

你去这个方法就是Rails.cache.fetch方法。Rails.cache.fetch接受 3 个参数;缓存键、选项哈希和块。它首先尝试根据 key 读取有效的缓存记录;如果该键存在并且尚未过期,它将从缓存中返回该值。如果它找不到有效的记录,它会从块中获取返回值,并使用您指定的键将其存储在缓存中。

例如:

@models = Rails.cache.fetch my_cache_key do
  Model.where(condition: true).all
end

这将缓存块并重用结果,直到某些东西 (tm) 使密钥无效,从而强制重新评估块。还要注意.all方法链末尾的 。通常,Rails 会返回一个 ActiveRecord 关系对象,该对象将被缓存,然后在您@models第一次尝试使用时对其进行评估,巧妙地避开缓存。该.all调用强制 Rails 急切加载记录并确保它是我们缓存的结果,而不是问题。

因此,现在您已打开所有缓存并且不再与数据库通信,我们必须确保覆盖另一端,使缓存无效。这是通过Rails.cache.delete简单地获取缓存键并将其删除的方法完成的,这会在您下次尝试获取它时导致丢失。您还可以使用force: truefetch 选项来强制重新评估块。哪个适合你。

这一切的科学是在哪里调用Rails.cache.delete,在幼稚的情况下,这将是对单个实例的更新和删除以及对集合的任何成员的更新、删除、创建。总会有一些角落案例,它们总是特定于应用程序,所以我在那里帮不了你太多。

我假设在这个答案中您将设置一些健全的缓存存储,例如 memcached 或 Redis。

还要记住将其添加到 config/environments/development.rb:

config.cache_store = :null_store

或者你的开发环境会缓存,你最终会因为沮丧而变得无毛。

如需进一步参考,请阅读:Everyone should be using low level caching in Rails and The rails API docs

还值得注意的是,Rails 4 中并没有删除功能,只是将其提取到 gem 中。如果您需要或想要扫地机的全部功能,只需将其添加回您的应用程序,并gem 'rails-observers'在您的 Gemfile 中添加一行。该 gem 包含从 Rails 4 核心中删除的清扫器和观察器。

我希望这可以帮助您入门。

于 2013-01-09T10:18:50.233 回答