RailsのセッションストアにRedisを使う
レプリケーションとかが簡単そうなセッションストアということでRedisを使ってみることにした。
Redisのインストール
まずはRedisのセットアップから。
Chefで。ひとまずVagrantの環境に対して。
RedisのCookbook
ふたつ見つけた。
READMEの設定例などが親切だったので、とりあえずredisioの方を使ってみることにした。
Berksfileの編集
いつものごとくBerkshelfを使う。
cookbook 'redisio'
Vagrantfileの編集
chef.add_recipe "redisio::install" chef.add_recipe "redisio::enable"
Vagrantのバージョンは1.3.5。
Vagrantへの反映
vagrant provision
こんなかんじでRedisのインストールはあっさりと完了すた。
redis-rails
次はセッションストアにRedisを使うためのRails側の設定。
redis-railsを使う。
Gemfileの編集
gem 'redis-rails'
bundle installしたらredis-railsのREADMEの通りに設定ファイルを編集。
一見あっさりとうまくいった。でもなんだかexpires_inとかがうまく働かないのでドキュメントを参考にしつつもいろいろ試して、結果として次のようにした。なんだかREADMEが更新されてないような気がする。
config/environments/initializers/session_store.rb
RedisRailsExample::Application.config.session_store :redis_store, expire_after: 60.minutes, servers: { host: "localhost", port: 6379, namespace: "sessions" }
development.rbやproduction.rbなどに書いてもいい。
Redisの認証
開発環境はこれでいいとして、本番では認証入れないとまずいよな、ということでやり方を模索。
Redisにパスワードを設定してこれをRailsから使うのに試行錯誤したが、実はRedisの設定で接続を許可するホストを限定するか、iptablesでアクセス制御するのが一般的なようだ。(そうだよね?)
なのでここから下はすごくいらないっぽいけど、せっかくやったので書いておく。
(そもそも無理にinitializers以下でやらなくてもdevelopment.rbやproduction.rbとかに書いてしまえばいいよね)
Vagrantfileの編集
Redisの設定を変更してパスワードを設定する。
chef.json = { :redisio=> { :default_settings => {:requirepass => ["hujiko"]} }, }
これでvagrant provisionするとパスワードが設定される。
ただし手動でRedisを再起動する必要があった。redisioが不親切なのか、こっちが何か悪いのか分からない。
config/environments/initializers/session.rb
RedisRailsExample::Application.config.session_store :redis_store, servers: { host: "localhost", port: 6379, namespace: "cache", password: "hujiko", expires_in: 90.minutes }
しかしこれだと環境ごとに設定できないという問題が。
このあたりを参考にdevelopment.rbで色々と試したがだめだった。
だめだったリスト。
# 1. config.cache_store = :redis_store, 'redis://localhost:6379/0/cache', { password: 'hujiko', expires_in: 90.minutes } # 2. config.cache_store = :redis_store, { :host => "localhost", :port => 6379, :db => 0, :password => "hujiko", :namespace => "cache", :expires_in => 90.minutes } # 3. config.cache_store = :redis_store, { servers: { host: "localhost", port: 6379, db: 0, password: "hujiko", namespace: "sessions", expires_in: 90.minutes } }
環境ごとの認証設定
このあたりを参考に環境ごとにRedisの設定をできるようにする。
config/environments/initializers/session.rb
redis_store_config_file = File.join(Rails.root,'config','redis_store.yml') raise "#{redis_store_config_file} is missing!" unless File.exists? redis_store_config_file redis_store_config = YAML.load_file(redis_store_config_file)[Rails.env].symbolize_keys RedisRailsExample::Application.configure do config.session_store :redis_store, servers: { host: redis_store_config[:host], port: redis_store_config[:port], namespace: redis_store_config[:namespace], password: redis_store_config[:password], expires_in: redis_store_config[:expires_in] } end
config/redis_store.yml
# Redis session store settings development: host: localhost port: 6379 namespace: sessions password: hujiko expires_in: 86400 test: host: localhost port: 6379 namespace: sessions password: hujiko expires_in: 86400 staging: host: localhost port: 6379 namespace: sessions password: hujiko expires_in: 86400 production: host: localhost port: 6379 namespace: sessions password: hujiko expires_in: 86400
これで環境ごとにRedisサーバーを設定できるようになった。
なお繰り返し言うけど、パスワード不要ならこんなことせずに普通にdevelopment.rbとかproduction.rbとかに書けばいい。
TODO
* レプリケーション
* フェイルオーバー