Redisとは
RedisはWebサービスなどのシステムにキャッシュ機能を簡単に実装出来るツールです。キャッシュを利用していない場合のシステムは毎回クエリを発行するので、DBが大きければ大きいほどパフォーマンスが落ちてしまいます。少しでもシステムを高速化したい時にキャッシュは一番手っ取り早く効果を出せる方法です。
今回はDocker上で動かしている既存のRailsプロジェクトにRedisコンテナを追加してキャッシュ機能を実装したいと思います。
Docker修正
まずはdocker-compose.ymlにRedisコンテナを追記します。必要な場合は各自6379/tcpポートの開放を行っておいて下さい。
〜 中略 〜
web:
depends_on:
- db
- redis
environment:
REDIS_HOST: redis
REDIS_PORT: 6379
〜 中略 〜
redis:
image: redis:5.0.5
ports:
- 6379:6379
volumes:
- ./redis:/data
command: redis-server --appendonly yes
Railsコンテナの環境変数にホスト名とポート番号を記述し、Redisコンテナを起動するためのイメージをプルする設定を記述しています。
ファイルを編集したら次のコマンドでコンテナ起動と再作成を行って下さい。
$ docker-compose up -d
Rails側の設定
次にRailsからRedisを使用するための設定を行っていきます。まずGemfileに下記を記述して下さい。
gem 'redis-rails'
次に下記コマンドを実行して下さい。
$ bundle install
インストール出来たらconfig/initializers/redis.rb
とconfig/environments/development.rb
それぞれに下記の設定を追加します。
Redis.current = Redis.new
#if Rails.root.join('tmp', 'caching-dev.txt').exist?
# config.action_controller.perform_caching = true
# config.action_controller.enable_fragment_cache_logging = true
# config.cache_store = :memory_store
# config.public_file_server.headers = {
# 'Cache-Control' => "public, max-age=#{2.days.to_i}"
# }
#else
# config.action_controller.perform_caching = false
# config.cache_store = :null_store
#end
config.cache_store = :redis_store, "redis://redis:6379/0/cache"
config.active_record.cache_versioning = false
config/environments/development.rb
に関しては2行追加していて既存の不要な設定にはコメントアウトをしています。
Redisキャッシュを利用する
実際にRedisキャッシュへの書き出し処理をコントローラへ記述していきます。
class CategoriesController < ApplicationController
def index
@categories = cache_categories
end
private
def cache_categories
Rails.cache.fetch("cache_categories", expires_in: 60.minutes) do
Category.order(name: :asc).to_a
end
end
end
9行目ではcache_categories
というキー名で1h格納する処理を設定しています。また.to_a
としているのはこれがないとキャッシュされないからです。実はCategory.order(name: :asc)
だけだとクエリはまだ発行されず、View側のループ処理時点などで発行されるらしいです。
これで設定は完了なのでページにアクセスしてみて速度が改善されるか試してみて下さい。実際にキャッシュされているかどうかはRedisコンテナに入りredis-cli
でも確認が出来ます。
$ keys *
1) "cache:cache_categories" ← 設定したキー名で保存されています。
$ get cache:cache_categories
※キャッシュ内容が出力される
あとはRedisがキャッシュの一時ファイルを作成するみたいなので.gitignoreに下記を記述してコミットから除外してしまいましょう。
appendonly.aof
終わりに
個人的な備忘録のために書いた記事なので不足や読み苦しい箇所があったかと思います。大変申し訳ございません。理解不足な部分は他のサイトをご参考にしてみて下さい。分かりやすい解説をしているところが沢山出てくるかと思います。
また今回は昔作成した個人的なプロジェクトをそのまま利用したのですがコントローラが見事に肥大化していてモデルに処理を書き出すリファクタリングをしなければと思いました。