带有ruby on rails的$ redis全局变量

时间:2014-01-12 14:26:05

标签: ruby-on-rails ruby redis

我使用redis作为读缓存。我创建了一个初始化器

配置/初始化/ redis.rb

$redis = Redis.new(:host => ENV["REDIS_HOST"], :port => ENV["REDIS_PORT"])

我在unicorn.rb中使用this global来创建新工作组时创建新连接。

before_fork do |server, worker|
  # clear redis connection
  $redis.quit unless $redis.blank?
end

# Give each child process its own Redis connection
after_fork do |server, worker|
  $redis = Redis.new(:host => ENV["REDIS_HOST"], :port => ENV["REDIS_PORT"])
end

每当我需要访问我的redis服务器时,我也在使用这个全局变量。但我不习惯使用这个全局变量。有没有比使用全局变量更好的选择?

6 个答案:

答案 0 :(得分:65)

Redis.current,您可以使用它来存储您的唯一Redis个实例。

因此,您可以按如下方式分配实例,而不是使用$redis

Redis.current = Redis.new(:host => ENV["REDIS_HOST"], :port => ENV["REDIS_PORT"])

Redis.currentintroduced to redis-rb in 2010作为获取redis连接的标准方式,所以我很惊讶没有其他答案提及它。

答案 1 :(得分:27)

进一步扩展mestachs建议,在初始化程序中命名一个模块,如下所示

配置/初始化/ redis.rb

module ReadCache
  class << self
    def redis
      @redis ||= Redis.new(:url => (ENV["REDIS_URL"] || 'redis://127.0.0.1:6379'))
    end
  end
end

然后在unicorn.rb

 before_fork do |server, worker|
    ...
   if defined?(ReadCache.redis)
    ReadCache.redis.quit
   end
    ...
 end

 after_fork do |server, worker|
    ...
   if defined?(ReadCache.redis)
    ReadCache.redis.client.reconnect
   end
    ...
 end

答案 2 :(得分:0)

如果你还没有使用另一个Rails.cache,我建议你只使用redis的那个机制。

gem redis-store使这个变得简单(https://github.com/redis-store/redis-store

这样你就可以Rails.cache.reconnect,而且一切都很花哨

https://github.com/redis-store/redis-store/issues/21#issuecomment-948569

它还允许您使用令人敬畏的Rails.cache API,它具有一些简洁的功能:http://api.rubyonrails.org/classes/ActiveSupport/Cache/Store.html

答案 3 :(得分:0)

用于替换全局变量的命名空间选项,可以在模块中创建方法

module Caching
  def self.redis
    ... initialize/memoize/reconnect here...
  end
end

然后你打电话给:

Caching.redis

答案 4 :(得分:0)

根据this Heroku,你不需要为你的Unicorn添加$redis

  

将Redis Cloud与Unicorn服务器配合使用时无需特殊设置。在Unicorn上运行Rails应用程序的用户应遵循Configuring Redis from Rails部分和用户...

中的说明

以下是Rails 4之前的所有“Configuring Redis from Rails部分”(除了Gemfile和其他一些预Rails 3之外):

# config/initalizers/redis.rb

if ENV["REDISCLOUD_URL"]
  uri = URI.parse(ENV["REDISCLOUD_URL"])
  $redis = Redis.new(:host => uri.host, :port => uri.port, :password => uri.password)
end

它并没有真正解释为什么“不需要特殊设置”。

答案 5 :(得分:-1)

试试这个: -

您可以使用constant代替global variable     配置/初始化/ redis.rb

REDIS = Redis.new(:host => ENV["REDIS_HOST"], :port => ENV["REDIS_PORT"])

和unicorn.rb

before_fork do |server, worker|
  # clear redis connection
  REDIS.quit if defined?(REDIS)
end

#为每个子进程提供自己的Redis连接

after_fork do |server, worker|
  REDIS ||= Redis.new(:host => ENV["REDIS_HOST"], :port => ENV["REDIS_PORT"])
end