Rails 低级缓存不适用于活动记录

Posted

技术标签:

【中文标题】Rails 低级缓存不适用于活动记录【英文标题】:Rails low level caching is not working for active records 【发布时间】:2020-10-07 20:19:16 【问题描述】:

我将graphql 用于我的rails api。并使用redis 进行缓存存储。

在 graphql 查询中,我使用缓存来优化性能:

graphql/types/query_type.rb

field :labels, [Types::LabelType], null: false do
  description 'Get all food labels'
end

def labels
  Rails.cache.fetch("labels", expires_in: 24.hours) do
    Label.all
  end
end

在数据库中播种了 10 个标签,当我在 localhost:3000/graphiql 中测试查询时,它正确显示了 10 个结果。但是,如果我在数据库中手动删除一行,它会返回 9 条记录,而不是缓存 10 条结果。

这是我的环境配置:

config/environments/development.rb

if Rails.root.join('tmp', 'caching-dev.txt').exist?
  config.action_controller.perform_caching = true
  config.cache_store = :redis_cache_store,  url: ENV.fetch("REDIS_URL_CACHING", "redis://localhost:6379/0") 
  config.public_file_server.headers = 
    'Cache-Control' => "public, max-age=#2.days.to_i"
  
else
  config.action_controller.perform_caching = false
  config.cache_store = :null_store
end

我跑了rails dev:cache,在tmp 目录中有caching-dev.txt。 我在这里错过了什么?

【问题讨论】:

你的意思是rails dev:cache 是的,抱歉打错了。 我认为我对这个关于Model Fragment Caching 的问题的回答可能与此相关。 (不确定问题本身是否足够接近重复,并且提问者说答案对他们没有帮助,但我觉得这可能是我认为是他们的问题) @SimpleLime 您好,感谢您的关注。我想出了一个解决方案,但我猜不出背后的原因。有什么建议吗? 【参考方案1】:

我发现了类似的问题并尝试了他们的答案。 建议的解决方案是:

加载模型:Label.all.load (Rails 5.2.1 - Model & Fragment Caching) 将它们转换为数组:Label.to_a (Low level caching in rails 4) 将结果存储到局部变量:labels = Label.all (Rails 4 low-level caching not working)

第一个和第二个工作正常。

graphql/types/query_type.rb

def labels
  Rails.cache.fetch("labels", expires_in: 24.hours) do
    Label.all.load
  end
end

提示:每当您更改缓存块时,请在 rails 控制台中运行 Rails.cache.clear

问题在于缓存的是块Label.all,而不是结果。

无论我如何更改块,它已经被缓存了,所以结果是缓存的。

我在 Rails 控制台中运行了Rails cache clear,它运行正常。

【讨论】:

以上是关于Rails 低级缓存不适用于活动记录的主要内容,如果未能解决你的问题,请参考以下文章

如何加快rails3.2中的活动记录?我的活动记录查询时间超过 3 分钟

不适用于经过审核的 4.7 gem 更新模型

Rails 记录 VIP 用户活动

Rails 4 - 如何在活动记录查询中为包含()和连接()提供别名

如何要求在 Rails 之外工作的活动记录

Rails活动记录查询检索IDS数组中包含ALL IDS的所有记录