LoginSignup
19
13

More than 3 years have passed since last update.

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

Last updated at Posted at 2017-07-07

概要

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
  }
...
...
19
13
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
13