6

我想使用 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'

我做了一些阅读并了解到每个乘客工作实例必须创建自己的 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

4

2 回答 2

6

看看redis store的reconnect方法: https ://github.com/jodosha/redis-store/blob/master/redis-activesupport/lib/active_support/cache/redis_store.rb

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

if defined?(PhusionPassenger)
  PhusionPassenger.on_event(:starting_worker_process) do |forked|
    if forked
      Rails.cache.reconnect
    end
  end
end
于 2012-07-11T06:19:24.907 回答
4

添加到@Tor 的响应中,更改$redis = Redis.newRails.cache.reconnect.

在这个 github 问题中找到的信息,https://github.com/jodosha/redis-store/issues/21#issuecomment-948569

于 2012-08-21T18:54:35.690 回答