+ 作るログイン
1 / 19
AWS でサービスを作る ― 知識ゼロから、構成を自分で考えられるまで / 全32章

AWS 25:キャッシュ ― ElastiCache で DB を休ませる

発行
アニメモ公式
版
第2版
改訂
コマ
全19

フォトログが人気になり、DB が同じ問い合わせに毎回答えて重くなった。よく使う答えを手元に写しておくキャッシュの考え方、ヒットとミス、置き場所(ブラウザ・CloudFront・アプリ・ElastiCache)の違い、Valkey とサーバーレス、期限(TTL)と古いデータ、書いたら消す無効化、セッションや順位表への応用、料金と落とし穴、いつ足すべきかを説明します。

人気が出たら、DB が同じ質問に答え続けていた

フォトログが少しずつ知られてきました。第16章で組んだ3層の構成は、台数を増やせる Web サーバーと、RDS のデータベース(DB)でできています。第17章で付けた CloudWatch のアラームが、ある晩こう知らせてきました。「RDS の CPU 使用率が 90% を超えています」。

調べてみると、原因は意外に単純でした。

観察したことわかったこと
いちばん多い問い合わせトップ画面の「新着の写真 30件」
その答え誰が開いても同じ。数秒おきにしか変わらない
DB がしていたこと開かれるたびに、写真の表を並べ替えて30件を選び直す

Web サーバーは Auto Scaling(第12章)で増やせますが、DB は簡単には増やせません。Web サーバーを増やすほど、DB に届く問い合わせも増えます。つまり、利用者が増えるほど、DB が真っ先に苦しくなるのです。

でも、よく考えると無駄があります。1秒間に何百回も来る「新着30件」の答えは、その1秒の間ほとんど変わりません。1回計算した答えを、しばらく手元に取っておいて使い回せば、DB は1回だけ働けば済みます。

この「答えを手元に取っておく」仕組みをキャッシュと呼びます。この章では、キャッシュの考え方と、AWS でキャッシュの置き場を借りる Amazon ElastiCache を学びます。

※2026年9月時点の情報です。画面・料金・細部は変わることがあります。

  • AWS でサービスを作る 25 ― キャッシュ:ElastiCache
  • 1 / 19
  • 人気が出たら、DB が同じ質問に答え続けていた
  • サーバー
  • SELECT … 新着の写真 30件
  • SELECT … 新着の写真 30件
  • 人々
  • アプリ 1
  • SELECT … 新着の写真 30件
  • データベース
  • DB(RDS)
  • SELECT … 新着の写真 30件
  • たくさんの利用者
  • CPU 90%・遅い
  • (毎秒、何百回も同じ)
  • サーバー
  • アプリ 2
  • 第17章のアラームが鳴った。原因は、全員に同じ「新着30件」を毎回 DB で計算していること
  • → 1回計算した答えを、しばらく手元に取っておけばいい
  • ひらめき
  • DB は同じ問い合わせを毎回、最初から計算している。混む原因は同じ仕事の繰り返し。

キャッシュ=よく使う答えを、手の届く所に置いておく

キャッシュを、図書館で調べものをする場面にたとえてみます。

必要な本はすべて奥の書庫にあります。書庫には何でもそろっていますが、取りに行くのに時間がかかります。そこで、よく調べることは机の上のメモに書き写しておきます。次に同じことを調べたくなったら、まずメモを見ます。メモにあれば書庫へ行かずに済みます。

机の上のメモ(キャッシュ)奥の書庫(DB)
しまう場所メモリ(電気が切れると消える、とても速い記憶)ディスク(消えないが、メモリより遅い)
中身よく使う答えの写しだけすべてのデータの正本
速さとても速い計算の分だけ遅い
弱点写した後に書庫が変わると、古いまま同じ質問でも毎回計算する

ここで大事なのは、キャッシュは正本ではなく写しだということです。キャッシュが消えても、書庫(DB)から写し直せば元に戻ります。逆に言えば、キャッシュにしか無いデータを作ってはいけません。

そして、写しである以上、古くなる瞬間が必ずあります。キャッシュを使うことは、「速さ」を手に入れる代わりに「少し古いかもしれない」を引き受けることです。この章の後半は、ほとんどがこの「古さ」との付き合い方の話です。

  • AWS でサービスを作る 25 ― キャッシュ:ElastiCache
  • 2 / 19
  • キャッシュ=よく使う答えを、手の届く所に置いておく
  • 書類
  • 机の上のメモ(キャッシュ)
  • 本
  • 奥の書庫(DB)
  • すぐ読める・でも少ししか置けない
  • 全部そろっている・でも取りに行くのが遅い
  • OK
  • 速い(メモリから読む)
  • OK
  • いつも正しい(正本)
  • OK
  • DB の仕事が減る
  • OK
  • 消えない(ディスクに保存)
  • NG
  • 古いことがある(写した後で書庫が変わる)
  • NG
  • 同じ質問でも毎回計算する
  • ひらめき
  • 書庫(DB)まで毎回歩かず、机の上のメモ(キャッシュ)を先に見る。メモに無いときだけ書庫へ行く。

メモにあれば、DB には行かない(ヒット)

では、キャッシュを置いたフォトログの動きを見ていきます。図の舞台は、左から利用者、アプリ(Web サーバー)、右上がキャッシュ、右下が DB です。

利用者がトップ画面を開くと、アプリは DB に聞く前に、まずキャッシュに「timeline:new という名前で答えを持っていますか」と聞きます。この名前をキーと呼びます。キャッシュは、キーと値(答え)の組を覚えておく、単純な仕組みです。

結果呼び名アプリがすること
答えがあったヒットそれをそのまま利用者に返す
答えが無かったミスDB に聞く(次の説明)

ヒットした場合、DB は一度も働きません。キャッシュはメモリから読むので、DB で並べ替えるよりずっと速く返せます。

全体のうち、ヒットした割合をヒット率と呼びます。ヒット率が 95% なら、DB に届く問い合わせは元の 20分の1 になります。人気のある画面ほど同じ答えが何度も求められるので、ヒット率は上がりやすくなります。

ElastiCache のヒット数・ミス数は CloudWatch(第17章)のメトリクスで見られます。キャッシュを入れたら、ヒット率と、DB の CPU がどれだけ下がったかを必ず確かめましょう。

  • AWS でサービスを作る 25 ― キャッシュ:ElastiCache
  • 3 / 19
  • メモにあれば、DB には行かない(ヒット)
  • 電気
  • キャッシュ
  • ヒット
  • メモリ・とても速い
  • 人々
  • サーバー
  • ① 探す
  • キャッシュの中に 答えがあった
  • 答えあり
  • 利用者
  • アプリ
  • DB は休めたまま。 メモリから読むので とても速い
  • データベース
  • DB(RDS)
  • ディスク・重い仕事
  • 人気のある画面ほど、同じ答えを何度も求められる。ヒットの割合(ヒット率)が高いほど DB は楽になる
  • ひらめき
  • アプリはまずキャッシュを見る。答えがあれば(ヒット)そのまま返す。DB は一度も働かない。

メモに無ければ、DB で調べてメモに写す(ミス)

キャッシュに答えが無かった場合です。図の番号の順に動きます。

順番動き
① 探すキャッシュに timeline:new を聞く。無かった(ミス)
② 聞くDB に問い合わせて、新着30件を計算してもらう
③ 写すその答えをキャッシュに timeline:new として書き込む。このとき「30秒たったら消す」などの期限を付ける
返す利用者に答えを返す

次に同じ画面を開いた人は、①でヒットします。つまり、DB が働くのは「期限が切れた後の最初の1人」の分だけです。

このやり方をキャッシュアサイド(cache-aside、脇に置いたキャッシュ)と呼びます。アプリが「先にキャッシュ、無ければ DB、答えを写す」を自分で行う、いちばん基本の型です。

キャッシュアサイドのよいところは、キャッシュが止まっても、アプリは DB に直接聞けば動き続けられることです。遅くはなりますが、止まりはしません。キャッシュを「無くても動く部品」にしておくと、壊れたときに慌てずに済みます。

もう1つの型に、DB に書くたびにキャッシュにも同じ値を書くライトスルーもあります。常に新しい写しを持てますが、読まれないデータまで写すことになります。まずはキャッシュアサイドから始めるのが一般的です。

  • AWS でサービスを作る 25 ― キャッシュ:ElastiCache
  • 4 / 19
  • メモに無ければ、DB で調べてメモに写す(ミス)
  • 電気
  • キャッシュ
  • ミス
  • メモリ・とても速い
  • キャッシュに無い → DB で計算
  • 人々
  • サーバー
  • ① 探す
  • 利用者
  • アプリ
  • ③ 写す
  • ③で書くとき 「60秒で消す」など 期限を付ける
  • ② 聞く
  • データベース
  • DB(RDS)
  • DB の答え
  • ディスク・重い仕事
  • この「先にキャッシュ、無ければ DB、答えを写す」を「キャッシュアサイド」と呼ぶ。いちばん基本の型
  • ひらめき
  • 無ければ(ミス)DB に聞き、答えをキャッシュに書いてから返す。次の人からはヒットになる。

キャッシュの置き場所は1つではない

実は、キャッシュは ElastiCache だけではありません。利用者から DB までの道の途中、あちこちに置けます。

置き場所向いているもの消しやすさ
ブラウザ画像・CSS・JavaScript利用者の手元なので、こちらから消せない
CloudFront(第15章)写真、誰が見ても同じページ消す指示(無効化)は出せるが、世界中に行き渡るまで少しかかる
アプリのメモリ設定、めったに変わらない小さな表台ごとに消す必要がある
ElastiCacheDB の答え、セッション、順位表キーを指定してすぐ消せる
DB正本―

図の左ほど利用者に近く、速く返せます。そのかわり、一度配った写しを消しにくくなります。右ほど正本に近く、新しい答えを返せますが、遅くなります。

フォトログでは、写真そのものは一度上げたら変わらないので、CloudFront に任せます(第15章)。一方、タイムラインやいいね数のように、数秒ごとに変わったり、人ごとに違ったりするものは、CloudFront では扱いにくい。これを受け持つのが、アプリと DB の間に置く ElastiCache です。

「何を、どこに置くか」は、どれだけ古くてもよいかとどれだけ速くしたいかの釣り合いで決めます。1か所に全部を置くのではなく、ものごとに向いた場所を選びます。

  • AWS でサービスを作る 25 ― キャッシュ:ElastiCache
  • 5 / 19
  • キャッシュの置き場所は1つではない
  • 画面
  • インターネット
  • CPU
  • 電気
  • データベース
  • ブラウザ
  • CloudFront
  • アプリのメモリ
  • ElastiCache
  • DB
  • 画像・CSS
  • 写真・公開ページ
  • 設定・小さな表
  • DB の答え・セッション
  • 正本(元のデータ)
  • ← 利用者に近い:速い・消しにくい
  • 正本に近い:新しい・遅い →
  • 変わらない写真は CloudFront(第15章)。人ごと・秒ごとに変わる DB の答えは ElastiCache
  • ひらめき
  • 利用者に近いほど速いが、中身を消しにくい。何をどこに置くかで、速さと新しさの釣り合いが決まる。

アプリのメモリに置くと、台数ぶんの「違う答え」ができる

「キャッシュなら、アプリのメモリに置けば、別のサービスを借りなくて済むのでは」と思うかもしれません。サーバーが1台なら、それでも動きます。

しかし、フォトログは第11・12章で、ALB の後ろに複数台のサーバーを並べ、Auto Scaling で台数を増減する形にしました。ここでメモリにキャッシュを置くと、次のことが起きます。

起きること利用者から見た症状
台ごとに写した時刻が違う同じ写真のいいね数が、再読み込みするたびに 10 と 12 で入れ替わる
消すときは全台に伝える必要がある1台だけ消し忘れて、古い値が残り続ける
新しい台はメモが空台が増えた直後、その台からの問い合わせが全部 DB に行く
台が消えるとメモも消えるAuto Scaling が台を入れ替えるたびに、せっかくの写しが失われる

台数が増えるほど、同じ答えを台数ぶん写すことになり、DB の負担も思ったほど減りません。

アプリのメモリに置いてよいのは、全台で少しずれていても困らず、めったに変わらないもの(アプリの設定など)です。利用者が見るデータを置くなら、台の外に置く必要があります。

  • AWS でサービスを作る 25 ― キャッシュ:ElastiCache
  • 6 / 19
  • アプリのメモリに置くと、台数ぶんの「違う答え」ができる
  • サーバー
  • 手元のメモ:いいね 10
  • アプリ 1
  • 人々
  • ネットワーク
  • データベース
  • DB
  • 利用者
  • ALB
  • 本当は 12
  • サーバー
  • 手元のメモ:いいね 12
  • アプリ 2
  • 再読み込みするたびに 10 と 12 が入れ替わる。消すときも全台に「消して」と言って回る必要がある
  • ひらめき
  • 台数が増えると、メモが台ごとにずれる。同じ写真のいいね数が画面ごとに違ってしまう。

だから、全台が見る「共有のキャッシュ」を1つ置く

解決策は、キャッシュをサーバーの外に出し、全台が同じキャッシュを見ることです。

図では、アプリ 1 もアプリ 2 も、同じ ElastiCache に聞いています。どちらの台に振り分けられても、返ってくるいいね数は同じ 12 です。書き込みがあったときに消すのも、ElastiCache の1か所だけで済みます。

アプリのメモリ共有のキャッシュ(ElastiCache)
台ごとの答えバラバラどの台でも同じ
消すとき全台に伝える1か所で消す
台が入れ替わったらメモが消える残る
速さいちばん速い通信が1回入るが、それでもとても速い

これは、第12章で学んだステートレス(サーバーに状態を置かない)と同じ考え方です。第12章では「セッションや画像をサーバーに置かない」と言いました。画像は S3 へ出しました。セッションの置き場として、ここで ElastiCache が出てきます(後で説明します)。

サーバーの外に「速い共有の置き場」が1つあると、Web サーバーは本当に使い捨てにできます。台が壊れて入れ替わっても、利用者はログインし直す必要がなく、キャッシュもそのまま使えます。

  • AWS でサービスを作る 25 ― キャッシュ:ElastiCache
  • 7 / 19
  • だから、全台が見る「共有のキャッシュ」を1つ置く
  • サーバー
  • アプリ 1
  • 人々
  • ネットワーク
  • 電気
  • ElastiCache
  • データベース
  • 利用者
  • ALB
  • いいね 12
  • DB
  • サーバー
  • アプリ 2
  • これは第12章の「サーバーに状態を置かない(ステートレス)」と同じ考え方。セッションもここに置ける
  • ひらめき
  • キャッシュをサーバーの外に出せば、どの台から見ても同じ答え。台が入れ替わっても、メモは消えない。

ElastiCache:メモリの置き場を借りるサービス

Amazon ElastiCache は、メモリ上の置き場(インメモリのキー・値ストア)を、AWS が面倒を見る形で借りられるサービスです。RDS(第13章)が DB サーバーの世話を肩代わりしてくれたのと同じで、故障した機械の交換や、ソフトの更新を AWS が行います。

中で動く仕組みをエンジンと呼び、3つから選びます。

エンジンどんなものか選ぶ場面
ValkeyRedis から分かれてできたオープンソース。Linux Foundation が運営新しく作るなら、まずこれ。ElastiCache ではいちばん安い料金
Redis OSS長く使われてきた定番。Valkey と使い方はほぼ同じすでに Redis の特定の版に合わせて作ってある場合
Memcached文字の値を置くだけの、単純で軽い仕組み単純な置き場で十分で、複製が要らない場合

少し事情を説明します。Redis は長くキャッシュの定番でしたが、2024年にライセンス(使ってよい条件)が変わりました。それを受けて、元の自由な条件のまま開発を続けるために分かれたのが Valkey です。Valkey は Redis と同じ命令で話せるので、Redis 用のライブラリからそのまま使えます。

Valkey と Redis OSS は、複製(レプリカ)と自動切り替えに対応し、数・リスト・順位表のようないろいろな形のデータを扱えます。Memcached は複製ができないので、ノードが壊れるとその中身は消えます。フォトログでは Valkey を選びます。

  • AWS でサービスを作る 25 ― キャッシュ:ElastiCache
  • 8 / 19
  • ElastiCache:メモリの置き場を借りるサービス
  • 電気
  • 電気
  • 電気
  • Valkey
  • Redis OSS
  • Memcached
  • Redis から分かれたオープンソース。いちばん安い
  • Valkey と同じ使い方。既存の互換用
  • 単純な置き場だけ。複製なし
  • 複製と自動切り替え
  • Valkey・Redis OSS はできる。Memcached はできない
  • いろいろなデータの形
  • Valkey・Redis OSS は数・リスト・順位表など。Memcached は文字だけ
  • クライアント
  • Valkey は Redis 用のライブラリでそのまま話せる
  • ひらめき
  • 中身の仕組み(エンジン)は3つから選ぶ。新しく作るなら、まず Valkey を考えればよい。

サーバーレスか、ノードを選ぶか

ElastiCache には、作り方が2通りあります。

サーバーレスは、名前と置き場所(VPC とサブネット)を選ぶだけで作れる形です。量が増えれば自動で大きくなり、最初から複数の AZ(第2章)に写しが置かれます。接続先は1つだけで、裏で機械が増えても減っても、アプリは気にしなくて済みます。

ノード型は、ノード(キャッシュ用のサーバー)の種類と台数、置く AZ を自分で決める形です。細かい設定を変えたいときや、量が安定していて、ずっと同じ大きさで動かすほうが安くなるときに選びます。

サーバーレスノード型
決めること名前と置くサブネットノードの種類・台数・AZ・複製の数
大きさ使った分に合わせて自動自分で決める(自動増減も設定できる)
複数 AZ最初からレプリカを別の AZ に置いて自分で作る
料金しまった量+処理した量ノード1台ごとの動いた時間
通信必ず暗号化(TLS)暗号化するかを選べる

迷ったらサーバーレスから始めるのがおすすめです。容量の見積もりが要らず、複数 AZ の設計も自動で済みます。使い方が落ち着いて、量が読めるようになってから、ノード型のほうが安くならないかを見直せば十分です。

どちらも VPC(第5章)の中に置く部品です。インターネットから直接つなぐものではなく、同じ VPC の中のアプリから使います。

  • AWS でサービスを作る 25 ― キャッシュ:ElastiCache
  • 9 / 19
  • サーバーレスか、ノードを選ぶか
  • 電気
  • サーバーレス
  • サーバー
  • ノード型(自分で設計)
  • 決めること
  • 名前と置くサブネット
  • 決めること
  • ノードの種類・台数・AZ
  • 増減
  • 負荷に合わせて自動
  • 増減
  • 自分で(自動も設定可)
  • 複数 AZ
  • 最初から自動で複製
  • 複数 AZ
  • レプリカを別 AZ に置く
  • 料金
  • しまった量 + 処理の量
  • 料金
  • ノード1台ごとの時間
  • どちらも VPC の中に置く。インターネットから直接つなぐものではない
  • ひらめき
  • 迷ったらサーバーレス。量が読めて安定しているなら、ノード型で台数と大きさを自分で決める。

期限(TTL):どれくらい古くてもよいかを決める

ここからが、キャッシュでいちばん大事な話です。キャッシュは写しなので、DB が変わった後も、しばらく古い写しを返してしまいます。

図の時間の流れで見てみます。

時刻起きたことキャッシュDB
0秒ミスして DB から写した。期限は60秒いいね 10いいね 10
20秒誰かが2回いいねしたいいね 10(古い)いいね 12
20〜60秒この間の人には、古い 10 を返すいいね 10いいね 12
60秒期限が切れてキャッシュから消える。次の人はミスして 12 を写すいいね 12いいね 12

この期限を TTL(Time To Live、生きていてよい時間)と呼びます。TTL は、言い換えれば「最大でこれだけ古い答えを返してもよい」という約束です。

TTLよいところ困るところ
短い(数秒)新しいヒットが減り、DB が楽にならない
長い(数時間)ヒットが増え、とても速い古い答えが長く残る

TTL に正解はありません。画面ごとに「何秒古くても、利用者は困らないか」を考えて決めます。新着の写真が30秒遅れて出ても、誰も困りません。一方、自分がいいねしたのに数字が増えないと、利用者は「押せなかった」と思って何度も押すかもしれません。そういう画面には、次に説明する「書いたら消す」を組み合わせます。

  • AWS でサービスを作る 25 ― キャッシュ:ElastiCache
  • 10 / 19
  • 期限(TTL):どれくらい古くてもよいかを決める
  • ダウンロード
  • 0秒:写す
  • ハート
  • 20秒:いいね +2
  • 時計
  • 60秒:期限切れ
  • TTL 60秒・いいね 10
  • DB は 12。メモは 10
  • 次の人は DB から 12 を読む
  • 正しい
  • 古い値を返している(いいね 10 のまま)
  • 時間 →
  • TTL を短くすると新しいがヒットが減る。長くすると速いが古い。画面ごとに「何秒古くても困らないか」で決める
  • ひらめき
  • キャッシュは写しなので、必ず古くなる瞬間がある。TTL は「最大でこれだけ古くてもよい」という約束。

変わったら消す:書いたときにキャッシュを捨てる

TTL を待たずに、DB を書き換えたときに、関係するキャッシュを自分で消すこともできます。これを無効化(invalidation)と呼びます。

フォトログで、誰かがいいねした場合を図で見ます。

順番動き
① 書くDB のいいね数を 12 に更新する
② 消すキャッシュから photo:123 のキーを消す
次の人ミスして DB から 12 を読み、写し直す

キャッシュの値を「12 に書き換える」のではなく「消す」のがおすすめです。書き換えにすると、アプリが同時に2つ動いたときに、古いほうが後から書いてしまう、といった食い違いが起きやすいからです。消しておけば、次に読んだ人が必ず DB の最新を写します。

順番も大事です。先に DB に書き、それからキャッシュを消します。逆に「先に消して、後で DB に書く」と、消した直後から DB に書くまでの短い間に別の人が読みに来て、古い値を写し直してしまうことがあります。

それでも、消し忘れやエラーで消せないことはあります。だから、無効化をするときも TTL は必ず付けておきます。消し忘れても、TTL が来れば自然に直ります。「書いたら消す」と「期限で消える」の2段構えにしておくのが安全です。

  • AWS でサービスを作る 25 ― キャッシュ:ElastiCache
  • 11 / 19
  • 変わったら消す:書いたときにキャッシュを捨てる
  • いいね
  • 電気
  • キャッシュ
  • 消す(無効化)
  • メモリ・とても速い
  • 人々
  • サーバー
  • ② 消す
  • 書き換えではなく 「消す」がおすすめ
  • 利用者
  • アプリ
  • 消し忘れた場合も TTL が来れば直る。 両方を組み合わせる
  • ① 書く
  • データベース
  • DB(RDS)
  • ディスク・重い仕事
  • 順番は「DB に書く → キャッシュを消す」。逆だと、消した直後に別の人が古い値を写し直してしまうことがある
  • ひらめき
  • DB を書き換えたら、その答えのメモを消す。次に読んだ人がミスして、新しい答えが写される。

セッションや順位表の置き場にもなる

ElastiCache は、DB の答えの写しを置くだけの場所ではありません。「速く、何度も読み書きする、小さなデータ」の置き場としても使えます。

1つ目はセッションです。セッションとは、ログインした人に渡す「入場券の番号」と、「その番号は誰のものか」の対応のことです。これをサーバーのメモリに置くと、別の台に振り分けられた瞬間にログインが切れます。ElastiCache に置けば、どの台からでも同じ入場券を確かめられます。セッションはログインの有効期間が過ぎたら不要になるので、TTL をその期間に合わせます。

2つ目は順位表です。Valkey には、値に点数を付けて、点数順に並べたまま覚えておくソート済みセットという形があります。

ZINCRBY likes:today 1 photo:123   # photo:123 の点数を +1
ZREVRANGE likes:today 0 9          # 点数の高い順に10件

いいねのたびに点数を足しておけば、「今日の人気の写真」を DB で毎回並べ替えずに取り出せます。この場合、キャッシュというより、速さのために使う集計の置き場です。消えても DB から数え直せるようにしておけば安心です。

ほかにも、「1分間に何回投稿したか」を数えて連投を止める回数制限などにもよく使われます。

  • AWS でサービスを作る 25 ― キャッシュ:ElastiCache
  • 12 / 19
  • セッションや順位表の置き場にもなる
  • セッション置き場
  • 今日のいいね順位表
  • サーバー
  • # いいねされたら +1
  • ZINCRBY likes:today 1 photo:123
  • アプリ 1
  • 電気
  • ElastiCache
  • # 上位10枚を取り出す
  • 入場券の番号→誰か
  • ZREVRANGE likes:today 0 9
  • サーバー
  • 並べ替え済みの集合(ソート済みセット)。 DB で毎回 ORDER BY するより軽い
  • アプリ 2
  • ひらめき
  • ログイン中の印(セッション)や、いいねの順位表のように「速く・何度も書く」データにも向く。

作り方:VPC の中に置き、アプリの SG からだけ通す

コンソールでサーバーレスのキャッシュを作る流れは、次のとおりです。

手順画面での操作気をつけること
1ElastiCache の画面でキャッシュを作成し、エンジンに Valkey、形にサーバーレスを選ぶ名前は photolog-cache など用途がわかるものに
2VPC と、プライベートサブネット(第6章)を選ぶWeb サーバーと同じ VPC。複数の AZ のサブネットを選ぶ
3セキュリティグループ(第8章)を付ける受け付けるのは アプリの SG から、6379 番ポートだけ
4できあがったら表示される接続先(エンドポイント)をアプリの設定に書く接続先は秘密ではないが、パスワードを使う場合は Secrets Manager(第20章)へ

6379 番は、Valkey と Redis が使う標準のポート(第8章。サーバーの中の窓口の番号)です。SG で「0.0.0.0/0(どこからでも)」を許すのは絶対に避けます。SG から SG を許せば、Web サーバーが何台に増えても設定を変えずに済みます。

サーバーレスは通信が必ず TLS(暗号化)なので、アプリ側のライブラリでも TLS を有効にしてつなぎます。

アプリの中は、図の右のようなコードになります。cache.get で探し、無ければ DB から読み、cache.set で書いて返します。"EX", 30 の部分が TTL(30秒)です。IaC(第18章)で書く場合も、作るものは同じ「キャッシュ本体・サブネット・SG」の3つです。

  • AWS でサービスを作る 25 ― キャッシュ:ElastiCache
  • 13 / 19
  • 作り方:VPC の中に置き、アプリの SG からだけ通す
  • 設定
  • エンジンに Valkey、サーバーレスを選ぶ
  • // 先にキャッシュ、無ければ DB
  • const key = "timeline:new";
  • let v = await cache.get(key);
  • ネットワーク
  • VPC とプライベートサブネットを選ぶ
  • if (!v) {
  • v = JSON.stringify(await loadFromDb());
  • await cache.set(key, v, "EX", 30);
  • 盾
  • SG:アプリの SG から 6379 番だけ許可
  • }
  • return JSON.parse(v);
  • リンク
  • 表示された接続先をアプリに設定
  • "EX", 30 が TTL(30秒で消える)
  • ひらめき
  • サーバーレスなら4ステップ。大事なのは置き場所と扉(SG)。つなぐのは暗号化(TLS)の通信で。

フォトログでは、何をどこに、何秒置くか

ここまでをまとめて、フォトログで実際に何をキャッシュするかを決めます。

置くもの置き場所期限の目安理由
新着タイムラインElastiCache30秒全員に同じ。数十秒遅れても困らない
人気の写真ランキングElastiCache期限なし(順位表を直接更新)いいねのたびに点数を足す
プロフィールElastiCache5分+変更時に消すよく読まれ、めったに変わらない
ログイン中の印(セッション)ElastiCacheログインの有効期間どの台からでも確かめたい
写真そのものCloudFront長め一度上げたら変わらない(第15章)

判断の基準は3つです。全員に同じか(人ごとに違うなら、キーに利用者 ID を入れる)、よく読まれるか(たまにしか読まないならヒットしない)、少し古くても困らないか。

逆に、キャッシュに置かないものもあります。お金の残高、在庫、権限(この人がこの写真を消してよいか)のように、古い値を使うと事故になるものは、毎回 DB で確かめます。

また、投稿した本人が直後に自分のページを開いたとき、キャッシュのせいで自分の写真が出ないと「投稿に失敗した」と思われます。本人の画面は、投稿直後だけキャッシュを使わない、消してから表示する、といった工夫をします。

  • AWS でサービスを作る 25 ― キャッシュ:ElastiCache
  • 14 / 19
  • フォトログでは、何をどこに、何秒置くか
  • 置くもの
  • 置き場所
  • 期限の目安と理由
  • 新着タイムライン
  • ElastiCache
  • 30秒。数十秒遅れても誰も困らない
  • 人気の写真ランキング
  • ElastiCache
  • 順位表を直接更新(期限なし)
  • プロフィール
  • ElastiCache
  • 5分。変更したら消す
  • ログイン中の印
  • ElastiCache
  • ログインの有効期間と同じ
  • 写真そのもの
  • CloudFront
  • 長め。写真は上書きしない(第15章)
  • 置かないもの:残高・在庫・権限のように「古いと事故になる」もの。これは毎回 DB で確かめる
  • ひらめき
  • 「全員に同じ・よく読む・少し古くても困らない」ものから置く。自分の投稿直後の画面は置かない。

お金:何に払うのか

ElastiCache の料金は、作り方によって単位が違います。

作り方何に払うか
サーバーレスしまったデータの量(GB×時間)と、処理の量(ECPU という単位)
ノード型ノードの種類×台数×動いた時間。レプリカも1台として数える

ECPU(ElastiCache Processing Unit)は、サーバーレスの処理の量を数える単位です。簡単な読み書きなら、やり取りするデータ 1KB あたり 1 ECPU が目安で、重い命令ほど多く数えられます。

サーバーレスは、データが少なくても1つのキャッシュあたりの最低の計量があります。この最低ラインは Valkey のほうが小さく、単価も Valkey のほうが Redis OSS・Memcached より安く設定されています。新しく作るなら Valkey を選ぶ理由の1つです。単価そのものは変わることがあるので、料金ページと Pricing Calculator(第4章)で確かめてください。

ノード型は、使っていない夜中も、置いている台数分の料金がかかります。複数 AZ にするためにレプリカを足すと、その分も増えます。

お金の面では、キャッシュは「足すと費用が増えるもの」ですが、同時に「RDS を大きくしなくて済む」ものでもあります。DB の CPU が足りないとき、大きな DB に替えるより、キャッシュでよく読む画面を肩代わりするほうが安いことはよくあります。DB の費用と合わせて比べるのがコツです。

  • AWS でサービスを作る 25 ― キャッシュ:ElastiCache
  • 15 / 19
  • お金:何に払うのか
  • 電気
  • サーバーレス
  • サーバー
  • ノード型
  • しまったデータ量(GB×時間)+ 処理(ECPU)
  • ノードの種類 × 台数 × 動いた時間
  • OK
  • Valkey は他の2つより安い料金。最低限の計量も小さい
  • OK
  • よく読む画面を置けば、RDS を大きくするより安く済むことが多い
  • NG
  • ノード型は使っていない時間も台数分かかる。レプリカも1台分
  • ECPU:読み書き1回・1KB あたり 1 が目安の「処理の単位」
  • ひらめき
  • サーバーレスは「しまった量」と「処理の量」、ノード型は「台数×時間」。単価は料金ページで。

よくある落とし穴

キャッシュは、うまく働いているときは目立ちません。壊れ方を知っておきましょう。

事故何が起きるか防ぎ方
キャッシュが空で DB に殺到再起動直後や、たくさんのキーの期限が同時に切れた瞬間に、全員がミスして DB に押し寄せ、DB が倒れるTTL に少しばらつきを足す(30秒+0〜5秒など)。DB がキャッシュ無しでもしばらく耐えられるか確かめておく
他人の画面を見せてしまう「自分のお知らせ」を notice というキーで置き、利用者 ID を入れ忘れた。最初に開いた人のお知らせが全員に出るキーには「何の・誰の」を必ず入れる(notice:user:7)
メモリがいっぱいで追い出されるTTL なしで何でも置き続け、容量が尽きる。古いものから勝手に消されたり、書けなくなったりする必ず TTL を付ける。使用量を CloudWatch で見る
誰でもつなげる状態SG で 0.0.0.0/0 を許し、キャッシュの中身が読まれるSG は アプリの SG から 6379 番だけ

1つ目は特に危険です。キャッシュのおかげで DB が小さくても回っていると、キャッシュが空になった瞬間に、本来の負荷が一気に DB に戻ってきます。キャッシュは速さのための部品であって、DB の能力の代わりではありません。

2つ目は、情報流出の事故になります。個人ごとの情報をキャッシュするときは、キーの作り方をチームで決めておきましょう。

  • AWS でサービスを作る 25 ― キャッシュ:ElastiCache
  • 16 / 19
  • よくある落とし穴
  • 注意
  • キャッシュが空で DB に殺到
  • 見る
  • 他人の画面を見せてしまう
  • 再起動直後・期限が一斉に切れた瞬間
  • キーに利用者 ID を入れ忘れた
  • ディスク
  • メモリがいっぱいで追い出される
  • 開いた錠
  • 誰でもつなげる状態
  • TTL なしで何でも置き続けた
  • SG を 0.0.0.0/0 にした(第8章)
  • 対策:期限に少しばらつきを付ける/キーは「何の・誰の」を必ず含める/必ず TTL を付ける/SG は SG から許す
  • ひらめき
  • キャッシュは「無くても動く」ように作る。キャッシュが空になった瞬間に DB が倒れる作りは危ない。

いつ ElastiCache を足すか

キャッシュは便利ですが、最初から置く部品ではありません。「古さ」という新しい悩みを連れてくるからです。

足すかどうかは、監視(第17章)で原因を確かめてから決めます。

状況考える順番
DB が遅いまず遅いクエリ(問い合わせ)を探す。索引(本の索引のような、探しものを速くする仕組み)が無いだけなら、索引を足せば直る
読み取りが多いリードレプリカ(第13章)で読み取りを分ける。正確な値が要る読み取りにも使える
同じ読み取りが大半ここで初めてキャッシュ。少し古くてよい画面から置く
ElastiCache を足すときまだ足さないとき
同じ読み取りが問い合わせの大半を占めている遅い原因が、索引の無い1本のクエリ
少し古くても困らない画面が重い書き込みばかりで、同じ読み取りが少ない
セッションを台の外に出したい(第12章)いつも最新でないと事故になるデータ
順位表・回数制限など、速い数え上げが要る写真や動画を配りたい(それは CloudFront)

判断の問いは、「その遅さは、同じ仕事の繰り返しから来ているか」です。そうなら、キャッシュがよく効きます。そうでないなら、キャッシュは問題を隠すだけです。

  • AWS でサービスを作る 25 ― キャッシュ:ElastiCache
  • 17 / 19
  • いつ ElastiCache を足すか
  • 足すとき
  • まだ足さないとき
  • OK
  • 同じ読み取りが大半を占めている
  • NG
  • 遅い原因が索引の無いクエリ
  • OK
  • 少し古くても困らない画面
  • NG
  • 書き込みばかりで同じ読みが無い
  • OK
  • セッションを台の外に出したい
  • NG
  • いつも最新でないと事故になる
  • OK
  • 順位表・回数制限など速い数え上げ
  • NG
  • 画像を配りたい(→ CloudFront)
  • 先に疑う順は「遅いクエリの索引」「リードレプリカ(第13章)」「キャッシュ」
  • キャッシュは「古さ」という新しい悩みを連れてくるので、最後に足す
  • ひらめき
  • 最初から置かない。「同じ読み取りが DB を重くしている」と監視で確かめてから足す。

片付け:消す順番

ElastiCache は、何も読み書きしていなくても、置いているだけで課金されます(サーバーレスは最低の計量分、ノード型は台数分)。練習で作ったら、その日のうちに消しましょう。

順番やること補足
1必要ならバックアップを取る練習用なら不要。キャッシュは写しなので、ふつうは消えても困らない
2キャッシュを削除するコンソールでキャッシュを選び、削除する
3専用に作った SG を削除する他で使っていなければ

CLI(第1章の CloudShell など)なら、サーバーレスのキャッシュは次の1行で消せます。

bash
aws elasticache delete-serverless-cache --serverless-cache-name photolog-cache

ノード型の場合は、レプリケーショングループ(主とレプリカのまとまり)ごと削除します。

また、バックアップ(スナップショット)を取っていた場合、それも保存している間は課金されます。要らなければ一緒に削除します。

アプリの設定にキャッシュの接続先を書いたままにしておくと、キャッシュアサイドの作りなら DB に直接聞いて動き続けますが、毎回つなごうとして失敗する分だけ遅くなります。練習後は設定も戻しておきましょう。

  • AWS でサービスを作る 25 ― キャッシュ:ElastiCache
  • 18 / 19
  • 片付け:消す順番
  • ダウンロード
  • 必要ならバックアップ
  • バツ
  • キャッシュを削除
  • 盾
  • 専用の SG を削除
  • 本番の中身を残すときだけ
  • コンソールで削除を選ぶ
  • 他で使っていなければ
  • # サーバーレスの場合
  • aws elasticache delete-serverless-cache --serverless-cache-name photolog-cache
  • 手元のバックアップ(スナップショット)も残しておくと課金される。要らなければ一緒に消す
  • ひらめき
  • ElastiCache は置いているだけで課金される。練習で作ったら、その日のうちに消す。

まとめ:速くする代わりに、古さを引き受ける

この章で学んだことをまとめます。

項目内容
キャッシュよく使う答えを、手の届く所(メモリ)に写しておく。正本ではなく写し
ヒット/ミスあればそのまま返す/無ければ DB で調べて写す(キャッシュアサイド)
置き場所変わらない写真は CloudFront、DB の答えやセッションは ElastiCache。アプリのメモリは台ごとにずれる
ElastiCacheメモリの置き場を借りるサービス。新しく作るなら Valkey、迷ったらサーバーレス。VPC の中に置く
TTL と無効化何秒古くてよいかを決め、書いたら消す。両方を組み合わせる
いつ選ぶか同じ読み取りが DB を重くしていると、監視で確かめてから

フォトログは速くなりました。ところで、セッションの話をしたときに気づいたかもしれません。フォトログのログインは、ここまで自分で作ってきました。利用者のパスワードを DB に保存し、合っていればセッションを発行しています。

もしパスワードの保存のしかたを間違えていたら? DB が漏れたら、利用者が他のサービスでも使っているパスワードまで知られてしまいます。二段階認証や「Google でログイン」も欲しくなってきました。

次の第26章では、ログインという、自作すると危ない部品を借りるために、Amazon Cognito を学びます。

  • AWS でサービスを作る 25 ― キャッシュ:ElastiCache
  • 19 / 19
  • まとめ:速くする代わりに、古さを引き受ける
  • キャッシュ
  • よく使う答えを、手の届く所に写しておく
  • ヒット/ミス
  • あれば返す/無ければ DB で調べて写す(キャッシュアサイド)
  • 置き場所
  • 変わらないものは CloudFront、DB の答えは ElastiCache
  • ElastiCache
  • 新しく作るなら Valkey。迷ったらサーバーレス
  • TTL と消す
  • 何秒古くてよいかを決め、書いたら消す
  • 選ぶとき
  • 同じ読みが DB を重くしていると確かめてから
  • 鍵
  • 次の困りごと:パスワードを自分で保存していて、漏れたら終わり
  • ひらめき
  • 次の第26章:ログインを自作していて、パスワードの扱いが危ない。認証は借りる(Cognito)。

0 件のコメント

読み込み中…

権利侵害・不適切な内容の連絡: [email protected]