在中国语言中,以一种方式解释以下内容:REDIS_URL环境变量最好包含模式(redis://),例如’redis:// hostname:6379′

几乎与标题相同,但是我们得出结论,如果使用REDIS_URL环境变量来设置redis的URL,最好包含完整的redis://部分。

过去我做了完全权限访问,或者连接到localhost:6379这样的操作。

经过一系列的原因和发展,最终得出了结论。

    アプリケーションのキャッシュはRedisを使っていました
# config/application.rb

config.cache_store = :redis_store, 'redis://localhost:6379/1/redis_try/cache', { expires_in: 90.minutes }

redisのURLを環境変数に切り出したいので、REDIS_URL環境を変数を定義してrails cを実行したら、下記のエラーになって、起動失敗しました

➜  redis_cache_try git:(master) REDIS_URL=localhost:6379/1/ttt rails c
/Users/blueplanet/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/redis-3.3.0/lib/redis/client.rb:416:in `_parse_options': invalid uri scheme 'localhost' (ArgumentError)
        from /Users/blueplanet/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/redis-3.3.0/lib/redis/client.rb:81:in `initialize'
        from /Users/blueplanet/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/redis-3.3.0/lib/redis.rb:51:in `new'
        from /Users/blueplanet/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/redis-3.3.0/lib/redis.rb:51:in `initialize'
        from /Users/blueplanet/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/redis-store-1.1.7/lib/redis/store.rb:10:in `initialize'
        from /Users/blueplanet/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/redis-store-1.1.7/lib/redis/store/factory.rb:27:in `new'
        from /Users/blueplanet/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/redis-store-1.1.7/lib/redis/store/factory.rb:27:in `create'
        from /Users/blueplanet/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/redis-store-1.1.7/lib/redis/store/factory.rb:10:in `create'
        from /Users/blueplanet/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/redis-activesupport-4.1.5/lib/active_support/cache/redis_store.rb:50:in `initialize'
        from /Users/blueplanet/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/activesupport-4.2.5/lib/active_support/cache.rb:60:in `new'
        from /Users/blueplanet/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/activesupport-4.2.5/lib/active_support/cache.rb:60:in `lookup_store'
        from /Users/blueplanet/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/railties-4.2.5/lib/rails/application/bootstrap.rb:76:in `block in <module:Bootstrap>'
        from /Users/blueplanet/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/railties-4.2.5/lib/rails/initializable.rb:30:in `instance_exec'
        from /Users/blueplanet/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/railties-4.2.5/lib/rails/initializable.rb:30:in `run'
        from /Users/blueplanet/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/railties-4.2.5/lib/rails/initializable.rb:55:in `block in run_initializers'
        from /Users/blueplanet/.rbenv/versions/2.3.0/lib/ruby/2.3.0/tsort.rb:228:in `block in tsort_each'
        from /Users/blueplanet/.rbenv/versions/2.3.0/lib/ruby/2.3.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component'
        from /Users/blueplanet/.rbenv/versions/2.3.0/lib/ruby/2.3.0/tsort.rb:431:in `each_strongly_connected_component_from'
        from /Users/blueplanet/.rbenv/versions/2.3.0/lib/ruby/2.3.0/tsort.rb:349:in `block in each_strongly_connected_component'
        from /Users/blueplanet/.rbenv/versions/2.3.0/lib/ruby/2.3.0/tsort.rb:347:in `each'
        from /Users/blueplanet/.rbenv/versions/2.3.0/lib/ruby/2.3.0/tsort.rb:347:in `call'
        from /Users/blueplanet/.rbenv/versions/2.3.0/lib/ruby/2.3.0/tsort.rb:347:in `each_strongly_connected_component'
        from /Users/blueplanet/.rbenv/versions/2.3.0/lib/ruby/2.3.0/tsort.rb:226:in `tsort_each'
        from /Users/blueplanet/.rbenv/versions/2.3.0/lib/ruby/2.3.0/tsort.rb:205:in `tsort_each'
        from /Users/blueplanet/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/railties-4.2.5/lib/rails/initializable.rb:54:in `run_initializers'
        from /Users/blueplanet/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/railties-4.2.5/lib/rails/application.rb:352:in `initialize!'
        from /Users/blueplanet/sandbox/redis_cache_try/config/environment.rb:5:in `<top (required)>'
        from /Users/blueplanet/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/spring-1.7.1/lib/spring/application.rb:92:in `require'
        from /Users/blueplanet/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/spring-1.7.1/lib/spring/application.rb:92:in `preload'
        from /Users/blueplanet/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/spring-1.7.1/lib/spring/application.rb:143:in `serve'
        from /Users/blueplanet/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/spring-1.7.1/lib/spring/application.rb:131:in `block in run'
        from /Users/blueplanet/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/spring-1.7.1/lib/spring/application.rb:125:in `loop'
        from /Users/blueplanet/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/spring-1.7.1/lib/spring/application.rb:125:in `run'
        from /Users/blueplanet/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/spring-1.7.1/lib/spring/application/boot.rb:19:in `<top (required)>'
        from /Users/blueplanet/.rbenv/versions/2.3.0/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
        from /Users/blueplanet/.rbenv/versions/2.3.0/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
        from -e:1:in `<main>'
    • なぜ?と思って調べてみたら、どうやら redis gem の中で、redisのデフォルト値を取得するの処理がREDIS_URL環境変数の値を使っているせいです。

まずはソース

# https://github.com/redis/redis-rb/blob/master/lib/redis/client.rb#L398-L417
url = options[:url] || defaults[:url]

# Override defaults from URL if given
if url
  require "uri"

  uri = URI(url)

  if uri.scheme == "unix"
    defaults[:path]   = uri.path
  elsif uri.scheme == "redis" || uri.scheme == "rediss"
    defaults[:scheme]   = uri.scheme
    defaults[:host]     = uri.host if uri.host
    defaults[:port]     = uri.port if uri.port
    defaults[:password] = CGI.unescape(uri.password) if uri.password
    defaults[:db]       = uri.path[1..-1].to_i if uri.path
    defaults[:role] = :master
  else
    raise ArgumentError, "invalid uri scheme '#{uri.scheme}'"
  end
  ...

optionshashはconfig.cache_store = :redis_store, ‘redis://localhost:6379/1/redis_try/cache’, { expires_in: 90.minutes }で設定した値のURLから後ろの部分になる

defaultsはデフォルト値で、その中、defaults[:url]の値は環境変数REDIS_URLの値を取得しています

optionsの値にはurlの値が設定されてないので、defaults[:url]の値になってしまいます
そして、もしredis://の部分が含めてない場合は、raise ArgumentError, “invalid uri scheme ‘#{uri.scheme}'”になってしまうわけです

よって、アプリケーション側のconfig.cache_store設定値と関係なく、REDIS_URL環境変数のURLにredis://のスキマー部分を含めないと上記エラーになってしまう

概括

    • 最初エラーが出た時、アプリ側設定しておけば、REDIS_URL環境変数を見に行かないでしょ!と勝手に思って、エラーはどうしても理解出来なかった。

思い込みをしないこと
エラー内容をじっくり読むこと

当たり前かもしれませんが、REDIS_URL環境変数(だけではなく)でredisのURLを設定するときは、redis://の部分も含めましょう。

まあ、そもそもURLと言う概念にはプロトコルまたはスキマーを含めるでしょうけど

请参考下面的链接。

    • 再現コード blueplanet/redis_cache_try

ローカルにcloneしてbundle installした後、REDIS_URL=localhost:6379/1/ttt rails cを実行すればエラーがでるはずです。

redis-rails RailsのセッションをRedisで管理 – 酒と泪とRubyとRailsと

广告
将在 10 秒后关闭
bannerAds