既存のRailsプロジェクトにRedisコンテナを追加した

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.rbconfig/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

終わりに

個人的な備忘録のために書いた記事なので不足や読み苦しい箇所があったかと思います。大変申し訳ございません。理解不足な部分は他のサイトをご参考にしてみて下さい。分かりやすい解説をしているところが沢山出てくるかと思います。

また今回は昔作成した個人的なプロジェクトをそのまま利用したのですがコントローラが見事に肥大化していてモデルに処理を書き出すリファクタリングをしなければと思いました。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA