在Passenger fork上重新启动Rails Redis缓存存储连接

时间:2012-07-08 13:17:13

标签: ruby-on-rails caching redis passenger

我想使用redis缓存存储(使用redis-store gem)。

它在本地工作正常,但在生产中,Passenger分叉Rails工作者的多个实例时,我们得到Redis错误,这表明有关Redis访问的不同实例之间存在同步问题。

此类错误的一个示例是

 Got '7' as initial reply byte. If you're running in a multi-threaded environment, make sure you pass the :thread_safe option when initializing the connection. If you're in a forking environment, such as Unicorn, you need to connect to Redis after forking.
  redis (2.2.2) lib/redis/connection/ruby.rb:78:in `format_reply'

我做了一些阅读并了解到每个Passenger worker实例必须创建自己的Redis连接。这可以使用以下代码实现

#config/initializers/redis_fork_init.rb
if defined?(PhusionPassenger)
  PhusionPassenger.on_event(:starting_worker_process) do |forked|
    if forked
      $redis = Redis.new
    end
  end
end

假设Redis访问是通过遍布代码的$ redis完成的 - 这个解决方案很棒。

我的问题是 - 如何创建一个新的Redis连接,当我执行Rails.cache操作(例如读,写等)时将使用它?

我的config / environments / production.rb包含以下内容:

config.cache_store = :redis_store, { :host => 'localhost', :port => 6379, :thread_safe => true } 

使用Rails 3.2.3,Redis 2.2.2,redis-store 1.1.1,Passenger 3.0

2 个答案:

答案 0 :(得分:6)

看看redis商店的重新连接方法: https://github.com/jodosha/redis-store/blob/master/redis-activesupport/lib/active_support/cache/redis_store.rb

所以基本上你的fork块应该是这样的:

if defined?(PhusionPassenger)
  PhusionPassenger.on_event(:starting_worker_process) do |forked|
    if forked
      Rails.cache.reconnect
    end
  end
end

答案 1 :(得分:4)

添加@ Tor的回复,将$redis = Redis.new更改为Rails.cache.reconnect

在此github问题https://github.com/jodosha/redis-store/issues/21#issuecomment-948569

中找到的信息
相关问题