ほぼタイトルのままですが、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と