RailsデフォルトのCookieを使うセッションストアから、Redisに変更してみる。
ローカル開発環境(Mac)と、本番環境(EC2:AmazonLinux)の両方動くようにする。
なお、本番環境ではRedisサーバとしてElastiCacheを使った。
Redisとはなんぞや?
いわゆるひとつのDB。といってもPostgresqlやMySQLといったRDBとは毛色が違っていて、
- 一意のキーと、保存したい値のペアでデータを保存する(KVS:KeyValueStore)
- データを全てメモリ上に持つ(なので動作が高速)
という特徴がある。
でもメモリにあるってことは再起動するとデータ消えるんでしょ?と思いきや、定期的にメモリ上のデータのスナップショットを保存してくれる(データ永続化)。もちろんクラッシュ時には最後にスナップショットを保存してから先の分は消えてしまうけど、それを最小限に抑えるようにもできるとのこと。
また、レプリケーションにも対応している。
レプリケーションというのは、複数のDBを用意して、内容を常に同期させておくこと。負荷分散になるし、障害にも強くなる。
そしてこのレプリケーション、AWSのElastiCacheでサポートされている。(←レプリケーションまだやってないけど、今回はこれが決め手)
MacにRedisをインストール
Redisのインストール
homebrewを使ってインストール。
% brew install redis
一応バージョン確認してみる。
% redis-server --version
Redis server v=2.8.13 sha=00000000:0 malloc=libc bits=64 build=96319fcc2102d7fa
Redisサーバ起動。(Ctrl-C
で終了)
% redis-server /usr/local/etc/redis.conf
Redisが自動実行されるよう登録
これでも動くけど、ローカルでRailsアプリを動かすたびにRedisサーバを起動しないといけなくなる。
それは面倒なのでRedisサーバが自動実行されるよう登録する。
% ln -sfv /usr/local/opt/redis/*.plist ~/Library/LaunchAgents
% launchctl load -w ~/Library/LaunchAgents/homebrew.mxcl.redis.plist
念のためプロセスを確認してみる。
% ps ax | grep redis-server
13443 ?? S 0:00.44 /usr/local/opt/redis/bin/redis-server 127.0.0.1:6379
13836 s005 S+ 0:00.00 grep redis-server
これでMacを再起動しても自動でRedisサーバが起動してくれる。
自動起動をやめたいときはコチラ。
% launchctl unload -w ~/Library/LaunchAgents/homebrew.mxcl.redis.plist
RailsにRedisを導入
Gemをインストール
gem 'redis'
gem 'redis-rails'
セッションストアをRedisにする。
初期設定はコメントアウト。
#Rails.application.config.session_store :cookie_store, key: 'XXXXXX'
そしてdevelopmentとproductionで設定を分けたいので、セッションストアの設定をdevelopment.rb
に移動
Rails.application.configure do
# (中略)
# これを追加
config.session_store :redis_store, servers: 'redis://localhost:6379/0', expire_in: 1.day
end
redis://localhost:6379/0
の0
というのはRedisのDBのIDとのこと。0~15まであるらしい。
もし他の用途でもRedisを使うなら、そこでは別の数字を使うといいのかな。
expire_in
はセッションデータの生存期間。この場合1日経つと消える。
これでローカル開発環境(Mac)は動くはず。
Redisに保存されたデータを確認
せっかくなので、保存されたセッションデータを確認してみる。
Redisクライアントを起動。
% redis-cli
もしID0
以外のDBを指定していたら、DBを選択。
127.0.0.1:6379> select 1
DBに保存されているキーの数を取得
127.0.0.1:6379> dbsize
キーを取得
127.0.0.1:6379> keys *
1) "f1412e2bbe5df2091ebdf2e3025e2335"
キーが表示されるので、そのキーを使って値を見てみる。
127.0.0.1:6379> get "f1412e2bbe5df2091ebdf2e3025e2335"
読めない文字列が出てくるけど、何かしら保存されてる。
ちなみにflushdb
を実行すると、RedisのDBのデータが全削除される。
Railsアプリにログイン機能があったりすると、セッションデータが無くなってログインし直しに。
これで本当にRedisに保存されていることを実感。
127.0.0.1:6379> flushdb
終了する。
127.0.0.1:6379> exit
EC2:AmazonLinux - ElastiCacheでも動かす
ローカルでうまくいったら、本番環境でも動かしてみる。
本当はローカルからもElastiCacheを使いたかったけど、今のところElastiCacheはEC2ネットワーク外からはアクセス出来ないらしい。
ElastiCacheのエンドポイントを確認
ElastiCacheの作成手順は割愛。
ただ、CacheClusterの名前は、EC2等と違って後から名前の変更ができないので注意。
作成したらこんな感じ。
画像中の1node
となっているリンクから、ノードの詳細画面に移動
ここで、エンドポイントの文字列をコピーしておく
本番環境用のセッションストア設定
Rails.application.configure do
# (中略)
# これを追加
config.session_store :redis_store, servers: 'redis://XXXX.XXXX.XXXX.XXXX.cache.amazonaws.com:6379/0', expire_in: 1.day
end
XXXX.XXXX.XXXX.XXXX.cache.amazonaws.com
の部分がエンドポイント。
あとはデプロイすれば本番環境でも動くはず。