ruby-on-rails - 尽管 expires_in 24.hours,Rails 缓存值丢失/为零

标签 ruby-on-rails ruby caching memcachier

我将 ruby​​ 2.3.3 和 Rails 4.2.8 与 Puma(1 个工作人员,5 个线程)一起使用,在我的管理(即不重要)页面上,我想显示我的数据库中的一些统计信息(整数值)。有些请求需要很长时间才能执行,所以我决定缓存这些值并使用 rake 任务每天重写它们。

Admin#index Controller

require 'timeout'
begin
  timeout(8) do
    @products_a = Rails.cache.fetch('products_a', :expires_in => 24.hours) { Product.where(heavy_condition_a).size }

    @products_b = Rails.cache.fetch('products_b', :expires_in => 24.hours) { Product.where(heavy_condition_b).size }
    @products_c = Rails.cache.fetch('products_c', :expires_in => 24.hours) { Product.where(heavy_condition_c).size }
    @products_d = Rails.cache.fetch('products_d', :expires_in => 24.hours) { Product.where(heavy_condition_d).size }              
  end
rescue Timeout::Error
  @products_a = 999
  @products_b = 999
  @products_c = 999
  @products_d = 999   

end

Admin#index View

    <li>Products A: <%= @products_a %></li>
    <li>Products B: <%= @products_b %></li>
    <li>Products C: <%= @products_c %></li>
    <li>Products D: <%= @products_d %></li>

抽取任务

task :set_admin_index_stats => :environment do
    Rails.cache.write('products_a', Product.where(heavy_condition_a).size, :expires_in => 24.hours)
    Rails.cache.write('products_b', Product.where(heavy_condition_b).size, :expires_in => 24.hours)
    Rails.cache.write('products_c', Product.where(heavy_condition_c).size, :expires_in => 24.hours)
    Rails.cache.write('products_d', Product.where(heavy_condition_d).size, :expires_in => 24.hours)                     
end

我在生产中使用它并使用 Memcachier(在 Heroku 上)作为缓存存储。我还将它用于网站上的页面缓存,并且在那里工作正常。我有:

production.rb

config.cache_store = :dalli_store

我遇到的问题是缓存的值几乎立即从缓存中消失,而且间歇性消失。在我试过的控制台中:

  1. 我在 Rails.cache.write 中写入一个值(例如 product_a)并在一分钟后检查它,它仍然存在。虽然很粗糙,但我可以在 Memcachier 管理工具中看到“Set cmds”递增 1。
  2. 但是,当我添加下一个值(例如 product_b)时,第一个值消失了(变为零)!有时,如果我将所有 4 个值相加,2 似乎会保留下来。这些并不总是相同的值。就像打地鼠!
  3. 如果我运行 rake 写入值,然后尝试读取值,通常只留下两个值,而其他值会丢失。

我看到了一个与此相关的类似问题,其中解释的原因是使用了多线程服务器。缓存值保存在一个线程中,无法在另一个线程中访问,解决方案是使用内存缓存,我就是这样做的。

不仅仅是控制台。如果我只是重新加载 admin#index View 来存储值或运行 rake 任务,我会遇到同样的问题。这些值(value)观不坚持。

我怀疑我没有正确使用 Rails.cache 命令,或者这些命令实际上没有使用 Memcachier。我无法确定我的值是否实际上存储在 Memcachier 中,但是当我在控制台中使用我的第一个命令时,我确实得到以下信息:

Rails.cache.read('products_a')
Dalli::Server#connect mc1.dev.eu.ec2.memcachier.com:11211
Dalli/SASL authenticating as abc123
Dalli/SASL authenticating as abc123
Dalli/SASL: abc123
Dalli/SASL: abc123
=> 0

但我没有得到后续写入的信息(我认为这是控制台中的可读性问题,而不是未使用 Memcachier 的证据。

我在这里错过了什么?为什么这些值不会保留在我的缓存中?

最佳答案

Heroku DevCenter陈述了一些不同的缓存配置,并提供了一些关于使用 connection_pool gem 的线程 Rails 应用程序服务器(如 Puma)的建议:

config.cache_store = :mem_cache_store,
  (ENV["MEMCACHIER_SERVERS"] || "").split(","),
  { :username => ENV["MEMCACHIER_USERNAME"],
    :password => ENV["MEMCACHIER_PASSWORD"],
    :failover => true,
    :socket_timeout => 1.5,
    :socket_failure_delay => 0.2,
    :down_retry_delay => 60,
    :pool_size => 5
  }

关于ruby-on-rails - 尽管 expires_in 24.hours,Rails 缓存值丢失/为零,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57918468/

相关文章:

ruby-on-rails - 在 Rails 上使用机架超时 gem

ruby - 比较 Rails 中两个对象数组的最佳方法

ruby-on-rails - Rails 3.2 流媒体

caching - SSRS 报告不通过 URL 访问刷新

ruby-on-rails - "gem install rails"因 DNS 错误而失败

ruby-on-rails - 在 rails 3 中使用其他插件修改 Ckeditor

ruby-on-rails - 如何自定义 Mailboxer 电子邮件主题?

ruby-on-rails - Rails 3.0 发送邮件安全最佳实践

CSS-从缓存加载图像

AWS Redis 缓存的 ASP.NET 输出缓存提供程序