Help us understand the problem. What is going on with this article?

redis_storeを使っているときRails.cache.clearはDBをまるまる吹っ飛ばすから注意

概要

Railsのキャッシュストアにredis_storeを用いている場合、Rails.cache.clearを呼び出すとキャッシュストアが使っているDBのデータが全部消えます。なのでキャッシュ用DBとそれ以外の用途のDBは分けておきましょう。

実験

設定ファイルはこんな感じ

config/initializers/redis.rb
require 'redis'
Redis.current = Redis.new(
  host: 'redis://localhost',
  port: 6379,
  db: 0
)
config/application.rb
...
...
  config.cache_store = :redis_store, {
    url: 'redis://localhost',
    port: 6379,
    db: 0
  }
...
...

では、試してみましょう。

# 書き込み
> Rails.cache.write('aaa', 'aaa')
=> "OK"
> Redis.current.with { |redis| redis.set('bbb', 'bbb') }
=> "OK"

# 読み込み
> Rails.cache.read('aaa')
=> 'aaa'
> Redis.current.with { |redis| redis.get('bbb') }
=> 'bbb'

# キャッシュクリア後読み込み
> Rails.cache.clear
=> nil
> Rails.cache.read('aaa')
=> nil
> Redis.current.with { |redis| redis.get('bbb') }
=> nil

Rails.cache.write で書き込んだ分以外もまとめて消えてしまっているのがわかります。

redis_store の実装を見てみるとわかるように、 Rails.cache.clear はRailsのキャッシュが使っているRedis DBに対して flushdb を行っています。そりゃ全部消えちゃうわけですね。
https://github.com/redis-store/redis-activesupport/blob/master/lib/active_support/cache/redis_store.rb#L247-L253

対処

キャッシュストアとそれ以外で、Redis DBを分けておきましょう。

config/initializers/redis.rb
require 'redis'
Redis.current = Redis.new(
  host: 'redis://localhost',
  port: 6379,
  db: 0
)
config/application.rb
...
...
  config.cache_store = :redis_store, {
    url: 'redis://localhost',
    port: 6379,
    db: 1
  }
...
...
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away