Rails可回收缓存键不起作用(仍然包含cache_version)

时间:2019-05-22 00:26:24

标签: ruby-on-rails

我有一个Rails 5.2应用程序,该应用程序配置为使用可回收缓存键的新功能。

我可以确认在控制台中启用了该设置:

Rails.application.config.active_record.cache_versioning
=> true

ActiveRecord::Base.cache_versioning
=> true

BlogPost.cache_versioning
=> true

使用此设置,blog_post.cache_key现在返回一个稳定的字符串,因为cache_version实际上存储在缓存项中(如this article的详细信息):

blog_post.cache_key
=> "blog_posts/10317"

blog_post.cache_version
=> "20190417193345000000"

但是问题是,即使一切都可以在控制台中正常运行,但我似乎看不到监视服务器日志,因为它一直在生成包含cache_version的cache_keys:

In my view:

<% cache(['blog_post_list_item_v2', blog_post, I18n.locale, browser.device.mobile?]) do %>
  ...
<% end %>

In the server logs:

Rendered blog/blog_posts/_blog_post_list_item.html.erb (2.5ms) [cache miss]
Read fragment views/blog/blog_posts/_blog_post_list_item:0bdff42a9193ea497e5ed4a9cc2f51e8/blog_post_list_item_v2/blog_posts/10317-20190417193345000000/pt-br/ (0.5ms)

如您所见,缓存键应为.../blog_posts/10317/,但实际上它包含时间戳记。

1 个答案:

答案 0 :(得分:0)

在通过Rails代码调试之后,我可以确认key实际上是稳定的。服务器日志中打印的内容仅包括用于调试目的的版本,但是存储在缓存中的密钥实际上并不包含该版本。

版本而是存储在缓存中的序列化对象中,该对象是ActiveSupport::Cache::Entry的实例,并且包含attr_reader :version。因此,如果您像我一样,可以假设缓存(例如原始HTML)直接存储在memcached中,但实际上存储在该value的{​​{1}}属性中(如果您打开了ActiveSupport::Cache::Entry,则该属性也具有version属性),并且整个对象被序列化保存到缓存中。

如果您想自己确认,则可以检查自己的memcached实时日志。如果您使用的是Mac,请先使用cache_versioning将其停止(我假设它是通过Homebrew安装的),然后使用brew services stop memcached以详细模式在前台启动它,并查看一下按键要求由铁轨。学习结束后,memcached -vv将重新启用memcached作为守护程序。

此外,如果要从旧方法迁移(没有可回收的缓存键),则应首先在控制台中使用brew services start memcached擦除缓存。记住在生产中也要这样做。

如果您想更多地了解它是如何工作的,请阅读Rails.cache.clear,但是对我来说,使用https://dzone.com/articles/cache-invalidation-complexity-rails-52-and-dalli-c通过rails代码进行调试是很容易的。

简而言之,我认为这是一个非常出色的实现,并且缓存回收只会使它变得更好(本文引用DHH的话说,“我们从只能保留18小时的缓存过渡到了我认为,三周。这是Basecamp 3所见过的最大的性能提升。')