おはようございます、YASUです。
DVAの勉強で、ElastiCacheの「Lazy Loading」と「Write-Through」の違いを整理しました。名前が似ていて混同しやすかったので、シンプルにまとめておきます。
結論
違いは「キャッシュにいつデータを入れるか」だけでした。Lazy Loadingは「読み取りの時」、Write-Throughは「書き込みの時」にキャッシュへ入れます。
ElastiCacheとは
ElastiCacheは、アプリケーションとデータベースの間に置く、メモリ上のキャッシュです。アプリは、まずキャッシュにデータを聞きに行きます。キャッシュにあれば、すぐに返してもらえるので、データベースへの負担が減り、応答も速くなります。
Lazy Loading:読まれた時に入れる
自分なりのイメージでは、「聞かれた時に調べて、メモしておく」方式です。流れはこうです。
1. アプリがキャッシュにデータを聞く
2. あれば、そのまま返す(キャッシュヒット)
3. なければ、データベースから取ってくる(キャッシュミス)
4. 取ってきたデータを、キャッシュに入れておく
- 良い点:実際に読まれたデータだけがキャッシュに入るので、無駄が少ない
- 悪い点:最初の1回(キャッシュミスの時)は、キャッシュへの確認、データベースへの問い合わせ、キャッシュへの書き込みと、3回のやり取りが必要で、少し遅い
- 悪い点:データベースの中身が変わっても、キャッシュは自動で更新されないので、古いデータが残ることがある
Write-Through:書いた時に入れる
こちらは、「情報が更新されるたびに、メモも書き換える」方式です。データベースに書き込むたびに、同時にキャッシュも更新します。
- 良い点:キャッシュが常に最新の状態になる
- 悪い点:書き込みのたびにキャッシュも更新するので、書き込み処理が少し遅くなる
- 悪い点:一度も読まれないデータまでキャッシュに入り、無駄が増えることがある
TTLで、古いデータを防ぐ
どちらの方式の弱点も、TTL(Time to Live)で和らげられます。TTLは、データをキャッシュに残しておく秒数のことです。期限が切れたデータは、キャッシュにないものとして扱われるので、Lazy Loadingでは、次に読まれた時にデータベースから取り直して、新しいTTLで保存し直します。ただし、データの更新頻度によっては、古いデータを完全になくせるわけではなく、減らす手段、という位置づけです。
どう使い分けるか
- 古いデータが多少残ってもよい、無駄なく使いたい → Lazy Loading(必要に応じてTTLも併用)
- 常に最新のデータを返したい → Write-Through
実際には、この2つを組み合わせて使うことも多いと紹介されていました。
RedisとMemcached
ElastiCacheには、RedisとMemcachedという2つのエンジンがあります。Memcachedは、シンプルなキャッシュ用途向けです。Redisは、ランキングのようなデータの扱い、永続化、マルチAZでの自動フェイルオーバー、Pub/Subなど、より多くの機能を持っています。
前に整理したDAXは、DynamoDB専用のキャッシュでした。ElastiCacheは、RDSなど、他のデータベースの前にも置ける汎用のキャッシュ、という違いです。
まとめ
- ElastiCacheは、アプリとデータベースの間に置く、メモリ上のキャッシュ
- Lazy Loadingは、読まれた時にキャッシュへ入れる。無駄は少ないが、最初の1回は遅く、古いデータが残ることがある
- Write-Throughは、書き込んだ時にキャッシュも更新する。常に最新だが、書き込みが少し遅くなる
- TTLで、古いデータが残る問題を和らげられる
- Redisは多機能、Memcachedはシンプルなキャッシュ向け
「いつキャッシュに入れるか」という1つの軸で見ると、2つの違いがすっきり整理できました。それでは、また明日!

コメント