Ruby on RailsにてRedisにマスタデータのModelをキャッシュ
とあるシュミレータをruby on rails
上で作成することになり、ある処理を何万回、
何百万回と動作させなければいけなくなった。例えば以下の処理が本番環境で動作している。
def cards (1..1000).each do |index| index.to_s + ": " + Card.all[Random.rand(Card.all.size)].name end end
1000回ほど、カードというマスタデータのnameカラムをランダムに1件ずつ取得している処理だが、
Completed 200 OK in 17243ms (Views: 29.3ms | ActiveRecord: 2451.8ms)
ぐらいの処理時間になってしまう。特にActiveRecord: 2451.8ms
は1回の処理でmysqlに
アクセスしてしまうためにモデルデータをなんとかキャッシュできないかと考えなければいけない....!
というわけでruby on rails
にredis
を導入し、モデルデータをキャッシュしてしまおうと対応にでた。
def cards (1..1000).each do |index| cache = Rails.cache.fetch("card_data", expires_in: 1.hour) do Card.all.to_a end index.to_s + ": " + cache[Random.rand(cache.size)].name end end
card_data
というkeyのvalueにCardモデルの内容を全てキャッシュするように記述してみました。
(expires_in
に関してはTTL
時間で1時間だけキャッシングするという記述)
これで処理してみると
Completed 200 OK in 16713ms (Views: 94.6ms | ActiveRecord: 0.4ms)
という結果を得ることができました。なんとActiveRecord: 0.4ms
という速度になり、log
を確認すると
mysqlログ
もなくなりキャッシュからデータを取得できていることも確認できました。
(Views: 94.6msになってるのはなぜ・・)
ちなみに実際、どのようにデータがキャッシュされているかは以下コマンドで確認することができます。
$ redis-cli // redisコンソールの起動 127.0.0.1:6379> keys * // キャッシュされているkey一覧 1) "card_data" 127.0.0.1:6379> get card_data // valueの取得
コマンドは大変!クライアントソフトないの!?っという人もいると思います。(自分のことです...)
そういう方はRedis Desktop Manager
を使用してみてはいかがでしょうか。
以下のような感じでredis
を確認することができます。これは便利!