これは何?
以前RedisのOptionの説明を見ているときに出会ったDog Pile Effectというものを理解するのに苦戦したので、それについてまとめようと思いました。
一応キャッシュの説明もしていますが、Dog Pile Effectのみ見たい方はこちらから。
キャッシュとは
一度利用したデータなどを、その後また使う場合に高速にアクセスできるような形で保存しておくこと。
ちなみにキャッシュといってもブラウザキャッシュやメモリキャッシュなど色々な種類がありますが、今回焦点に当てるのはサーバキャッシュです。WEBサーバなどが利用しているキャッシュの種類です。
サーバーキャッシュの種類
サーバーキャッシュの種類は大きく分けて2つあります。
Cache-Aside Pattern
- クライアントからリクエストする。
- 該当するデータが存在するかをキャッシュに問い合わせる。
- ヒットすれば、キャッシュからデータを取得する。
- ヒットしなければ、データベースにアクセスして取得する。
- 取得したデータをキャッシュに保存する。
Redisやmemcacheなどに採用されています。今回はこちらのパターンのお話です。
Broker Pattern
- クライアントからリクエストする
- 該当するデータが存在するかをキャッシュに問い合わせる。
- ヒットすれば、そのまま返却する。
- ヒットしなければ、キャッシュがDBから値を取得し、キャッシュに保存する。
- キャッシュからクライアントに返却する。
Amazon DynamoDB Accelerator (DAX)に採用されています。
キャッシュが使われるまでの流れ
## キャッシュが作られるまで
## キャッシュが使われるまで
Dog Pile Effectとは
キャッシュの有効期限が切れた後に同じページに複数のリクエストがほぼ同時にきて、DBに負荷がかかってしまう現象。
一般にキャッシュには有効期限があり、有効期限が切れると削除されるようになっています。
複数のリクエストが一気に来ることを想定しましょう。
キャッシュがある場合
この場合は全てキャッシュが返され、データベースにアクセスされることはありません。
キャッシュが切れた直後
新しくキャッシュができる前にきたリクエストは全てデータベースにアクセスしてしまう。また、キャッシュもその分だけ作ってしまう。これがDog Pile Effectです。
解決法
具体的なRedisのoption
- race_condition_ttl: This option is used in conjunction with the :expires_in option. It will prevent race conditions when cache entries expire by preventing multiple processes from simultaneously regenerating the same entry (also known as the dog pile effect). This option sets the number of seconds that an expired entry can be reused while a new value is being regenerated. It’s a good practice to set this value if you use the :expires_in option. (新しいキャッシュを作ってる間だけ有効期限の切れたキャッシュを指定した時間だけ使えるようにするよ。)
参考にしたもの
- https://hiroki.jp/fix_dog_pile_effect_in_rails
- https://railsguides.jp/caching_with_rails.html
- https://github.com/rails/rails/blob/cf4fa5caf39f1271d3f8c4c9774e874430ea0f68/activesupport/lib/active_support/cache.rb#L261
- http://highscalability.com/blog/2014/7/30/preventing-the-dogpile-effect-problem-and-solution.html
- https://www.sobstel.org/blog/preventing-dogpile-effect/