Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Redis::在heroku上使用Redis rails时出错_Ruby On Rails_Heroku_Redis_Resque_Redistogo - Fatal编程技术网

Ruby on rails Redis::在heroku上使用Redis rails时出错

Ruby on rails Redis::在heroku上使用Redis rails时出错,ruby-on-rails,heroku,redis,resque,redistogo,Ruby On Rails,Heroku,Redis,Resque,Redistogo,已更新以包括Redis/Resque版本和堆栈跟踪(如下所示): 我在heroku上看到间歇性的Redis::TimeoutError:连接超时,同时使用Rails.cache.fetch命令将中等大小的数组(~200个Fixnums)写入Redis存储 我也在使用Resque 我看到Redis::Client可以接收一个超时选项,但我不知道在哪里向Redis传递初始化选项 我正在使用标准的herokuresque.rb: rails_root = ENV['RAILS_ROOT

已更新以包括Redis/Resque版本和堆栈跟踪(如下所示):


我在heroku上看到间歇性的Redis::TimeoutError:连接超时,同时使用
Rails.cache.fetch
命令将中等大小的数组(~200个Fixnums)写入Redis存储

我也在使用Resque

我看到Redis::Client可以接收一个超时选项,但我不知道在哪里向Redis传递初始化选项

我正在使用标准的heroku
resque.rb

rails_root        = ENV['RAILS_ROOT'] || File.dirname(__FILE__) + '/../..'
rails_env         = ENV['RAILS_ENV'] || 'development'

resque_config     = YAML.load_file(rails_root + '/config/resque.yml')
ENV['REDIS_URI']  = resque_config[rails_env]
Resque.redis      = resque_config[rails_env]
Resque.inline     = rails_env == 'test'

require 'resque_scheduler'
require 'resque/scheduler'
require 'resque_scheduler/server'

Resque.schedule   = YAML.load_file(rails_root + '/config/resque-schedule.yml')

Resque.before_fork do
  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.connection.disconnect!
end

Resque.after_fork do
  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.establish_connection
end
rails_root          = ENV['RAILS_ROOT'] || File.dirname(__FILE__) + '/../..'
rails_env           = ENV['RAILS_ENV'] || 'development'
resque_config = YAML.load_file(rails_root + '/config/resque.yml')
config.cache_store = :redis_store, resque_config[rails_env], { expires_in: 14.days }
我假设这里实例化了一个Redis客户机。这与
production.rb中实例化的客户端不同吗:

rails_root        = ENV['RAILS_ROOT'] || File.dirname(__FILE__) + '/../..'
rails_env         = ENV['RAILS_ENV'] || 'development'

resque_config     = YAML.load_file(rails_root + '/config/resque.yml')
ENV['REDIS_URI']  = resque_config[rails_env]
Resque.redis      = resque_config[rails_env]
Resque.inline     = rails_env == 'test'

require 'resque_scheduler'
require 'resque/scheduler'
require 'resque_scheduler/server'

Resque.schedule   = YAML.load_file(rails_root + '/config/resque-schedule.yml')

Resque.before_fork do
  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.connection.disconnect!
end

Resque.after_fork do
  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.establish_connection
end
rails_root          = ENV['RAILS_ROOT'] || File.dirname(__FILE__) + '/../..'
rails_env           = ENV['RAILS_ENV'] || 'development'
resque_config = YAML.load_file(rails_root + '/config/resque.yml')
config.cache_store = :redis_store, resque_config[rails_env], { expires_in: 14.days }
据我所知,
Rails.cache
options的选项散列。这里是否实例化了新客户机?如何将选项传递给此选项


已更新,以在heroku控制台中包含此实验,这意味着它们是不同的客户端实例:

irb(main):002:0> Rails.cache
=> #<ActiveSupport::Cache::RedisStore:0x00000003860e18 @data=#<Redis client v3.0.4 for redis://spinyfin.redistogo.com:9485/0>, @options={:expires_in=>14 days}>
irb(main):003:0> Resque.redis.redis
=> #<Redis client v3.0.4 for redis://spinyfin.redistogo.com:9485/0>
irb(main):004:0> Rails.cache.instance_variable_get(:@data).object_id == Resque.redis.redis.object_id
=> false
irb(main):002:0>Rails.cache
=>#14天}>
irb(主):003:0>Resque.redis.redis
=> #
irb(main):004:0>Rails.cache.instance_variable_get(:@data).object_id==Resque.redis.redis.object_id
=>错误

堆栈跟踪:

Redis::TimeoutError: Connection timed out
    from /app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis/client.rb:208:in `rescue in io'
    from /app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis/client.rb:206:in `io'
    from /app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis/client.rb:214:in `read'
    from /app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis/client.rb:84:in `block in call'
    from /app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis/client.rb:187:in `block (2 levels) in process'
    from /app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis/client.rb:295:in `ensure_connected'
    from /app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis/client.rb:177:in `block in process'
    from /app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis/client.rb:256:in `logging'
    from /app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis/client.rb:176:in `process'
    from /app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis/client.rb:84:in `call'
    from /app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis.rb:644:in `block in setex'
    from /app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis.rb:36:in `block in synchronize'
    from /app/vendor/ruby-1.9.3/lib/ruby/1.9.1/monitor.rb:211:in `mon_synchronize'
    from /app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis.rb:36:in `synchronize'
    from /app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis.rb:643:in `setex'
    from /app/vendor/bundle/ruby/1.9.1/gems/redis-store-1.1.2/lib/redis/store/interface.rb:17:in `setex'
... 11 levels...
    from /app/vendor/bundle/ruby/1.9.1/gems/activesupport-3.2.13/lib/active_support/cache.rb:299:in `fetch'
    ...SNIP...
    ...my code...
    ...SNIP...
    from /app/vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.13/lib/active_record/relation/delegation.rb:6:in `each'
    from /app/vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.13/lib/active_record/relation/delegation.rb:6:in `each'
    ...SNIP...
    ...my code...
    ...SNIP...
    from (irb):5
    from /app/vendor/bundle/ruby/1.9.1/gems/railties-3.2.13/lib/rails/commands/console.rb:47:in `start'
    from /app/vendor/bundle/ruby/1.9.1/gems/railties-3.2.13/lib/rails/commands/console.rb:8:in `start'
    from /app/vendor/bundle/ruby/1.9.1/gems/railties-3.2.13/lib/rails/commands.rb:41:in `<top (required)>'
    from script/rails:6:in `require'
    from script/rails:6:in `<main>'irb(main):006:0>  !    Heroku client internal error.
 !    Search for help at: https://help.heroku.com
 !    Or report a bug at: https://github.com/heroku/heroku/issues/new

    Error:       Operation timed out (Errno::ETIMEDOUT)
    Backtrace:   /usr/local/heroku/ruby/lib/ruby/1.9.1/openssl/buffering.rb:121:in `sysread'
                 /usr/local/heroku/ruby/lib/ruby/1.9.1/openssl/buffering.rb:121:in `readpartial'
                 /Users/me/.heroku/client/lib/heroku/client/rendezvous.rb:69:in `block in start'
                 /Users/me/.heroku/client/lib/heroku/client/rendezvous.rb:53:in `loop'
                 /Users/me/.heroku/client/lib/heroku/client/rendezvous.rb:53:in `start'
                 /Users/me/.heroku/client/lib/heroku/command/run.rb:132:in `rendezvous_session'
                 /Users/me/.heroku/client/lib/heroku/command/run.rb:119:in `run_attached'
                 /Users/me/.heroku/client/lib/heroku/command/run.rb:24:in `index'
                 /Users/me/.heroku/client/lib/heroku/command.rb:206:in `run'
                 /Users/me/.heroku/client/lib/heroku/cli.rb:28:in `start'
                 /usr/local/heroku/bin/heroku:24:in `<main>'

    Command:     heroku run rails c
    Plugins:     heroku-redis-cli
    Version:     heroku-toolbelt/2.39.4 (x86_64-darwin10.8.0) ruby/1.9.3
Redis::TimeoutError:连接超时
from/app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis/client.rb:208:“io中的救援”
from/app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis/client.rb:206:in'io'
from/app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis/client.rb:214:in'read'
from/app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis/client.rb:84:in'block-in-call'
from/app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis/client.rb:187:在“进程中的块(2个级别)”中
from/app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis/client.rb:295:“确保连接”
from/app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis/client.rb:177:“进程中的块”中
from/app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis/client.rb:256:in'logging'
from/app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis/client.rb:176:在“进程”中
from/app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis/client.rb:84:in'call'
from/app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis.rb:644:in'block in setex'
from/app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis.rb:36:在“同步中的块”中
from/app/vendor/ruby-1.9.3/lib/ruby/1.9.1/monitor.rb:211:in'mon_synchronize'
from/app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis.rb:36:在“同步”中
from/app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis.rb:643:in'setex'
from/app/vendor/bundle/ruby/1.9.1/gems/redis-store-1.1.2/lib/redis/store/interface.rb:17:in`setex'
... 11级。。。
来自/app/vendor/bundle/ruby/1.9.1/gems/activesupport-3.2.13/lib/active\u support/cache.rb:299:in'fetch'
剪
…我的代码。。。
剪
from/app/vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.13/lib/active\u record/relation/delegation.rb:6:in'each'
from/app/vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.13/lib/active\u record/relation/delegation.rb:6:in'each'
剪
…我的代码。。。
剪
来自(irb):5
来自/app/vendor/bundle/ruby/1.9.1/gems/railties-3.2.13/lib/rails/commands/console.rb:47:in'start'
来自/app/vendor/bundle/ruby/1.9.1/gems/railties-3.2.13/lib/rails/commands/console.rb:8:in'start'
来自/app/vendor/bundle/ruby/1.9.1/gems/railties-3.2.13/lib/rails/commands.rb:41:in`'
来自脚本/rails:6:in'require'
来自脚本/rails:6:in`'irb(main):006:0>!Heroku客户端内部错误。
!    在以下位置搜索帮助:https://help.heroku.com
!    或在以下位置报告错误:https://github.com/heroku/heroku/issues/new
错误:操作超时(Errno::ETIMEDOUT)
回溯:/usr/local/heroku/ruby/lib/ruby/1.9.1/openssl/buffering.rb:121:in'sysread'
/usr/local/heroku/ruby/lib/ruby/1.9.1/openssl/buffering.rb:121:in'readpartial'
/Users/me/.heroku/client/lib/heroku/client/rendezvous.rb:69:in'block in start'
/Users/me/.heroku/client/lib/heroku/client/rendezvous.rb:53:in'loop'
/Users/me/.heroku/client/lib/heroku/client/rendezvous.rb:53:in'start'
/Users/me/.heroku/client/lib/heroku/command/run.rb:132:在“会合会话”中
/Users/me/.heroku/client/lib/heroku/command/run.rb:119:in'run_attached'
/Users/me/.heroku/client/lib/heroku/command/run.rb:24:in'index'
/Users/me/.heroku/client/lib/heroku/command.rb:206:在'run'中
/Users/me/.heroku/client/lib/heroku/cli.rb:28:in'start'
/usr/local/heroku/bin/heroku:24:in`'
命令:heroku运行rails c
插件:heroku redis cli
版本:heroku toolbelt/2.39.4(x86_64-darwin10.8.0)ruby/1.9.3
消息“连接超时”表示
redis rb
在启动与redis服务器的连接时遇到问题。通常,在应用程序启动时,您只需初始化一次Redis连接。然而,由于Resque是分叉的(而不是使用像Sidekiq这样的线程),它必须为每个作业初始化一个新的Redis连接


通常情况下,这不是问题,但Heroku在创建新的Redis连接时有间歇性问题。我在各种语言/客户端库/Redis主机中都看到过这个问题,除了减少您创建的Redis连接数量之外,缓解这个问题的唯一方法是在Resque.after fork块中自动重试连接到Redis几次。(例如,捕获超时错误,重试或重新引发异常,如果您尝试了3次)

这不是一个很好的答案,但在一位同事的建议下,我从RedisToGo切换到openredis,这些问题立即消失。

您不能将URL和选项哈希同时传递到
c
redis_uri = URI.parse(ENV["REDISTOGO_URL"])
config.cache_store = :redis_store, {
  host: redis_uri.host,
  port: redis_uri.port,
  password: redis_uri.password,
  namespace: "cache",
  expires_in: 7.days
}