【仕組み解説】キャッシュはどうやってアクセスを高速化しているのか — CPU・ブラウザ・CDNのキャッシュ戦略を図解


キャッシュの階層構造(速度 vs 容量) 速い・小さい 遅い・大きい L1 キャッシュ ~1ns / ~64KB L2 キャッシュ ~10ns / ~256KB L3 キャッシュ ~30ns / ~32MB メインメモリ(RAM) ~100ns / ~16GB SSD / HDD ~100µs / ~1TB CPU内部 Hit vs Miss Cache Hit キャッシュから即返却 ✔ 高速 Cache Miss 元のソースに問い合わせ ✘ 低速 → 結果をキャッシュに保存 上に行くほど高速だが容量が小さい = キャッシュの基本原則
キャッシュの階層構造
ひよこ ひよこ

ウェブサイトを2回目に開くと明らかに速くなるんだけど、あれってなんでなの?

ペンギン先生 ペンギン先生

それが「キャッシュ」の力だよ。キャッシュっていうのは、よく使うデータを取り出しやすい近い場所にコピーしておいて、次にアクセスしたときにわざわざ遠くまで取りに行かなくて済むようにする仕組みなんだ。図書館で言えば、よく借りる本を自分の机の上に置いておくようなイメージだね。

ひよこ ひよこ

なるほど!でもキャッシュってブラウザだけの話なの?

ペンギン先生 ペンギン先生

いい質問だね。キャッシュはコンピュータのあらゆる場所に存在するよ。まずCPUの中にはL1・L2・L3という3段階のキャッシュがあって、メインメモリからデータを取るより数十倍〜数百倍速くアクセスできるんだ。L1が一番速くて小さい(数十KB)、L3が一番遅いけど大きい(数十MB)という階層構造になっているよ。

ひよこ ひよこ

CPUの中にもキャッシュがあるんだね!速さってどのくらい違うの?

ペンギン先生 ペンギン先生

ざっくり言うと、L1キャッシュへのアクセスは約1ナノ秒、メインメモリは約100ナノ秒、SSDは約100マイクロ秒(10万ナノ秒)、HDDは約10ミリ秒(1000万ナノ秒)。つまりL1キャッシュHDDでは1000万倍の速度差があるんだ。だからこそ、できるだけ近い場所にデータを置いておくことが重要なんだよ。

ひよこ ひよこ

1000万倍!?それはすごい差だね…。じゃあブラウザキャッシュはどういう仕組みなの?

ペンギン先生 ペンギン先生

ブラウザキャッシュは、一度ダウンロードしたCSSJavaScript・画像ファイルなどをパソコンのローカルディスクに保存しておく仕組みだよ。サーバーがレスポンスに「Cache-Control」というHTTPヘッダーを付けて、「このファイルは1時間キャッシュしていいよ」とブラウザに伝えるんだ。次にアクセスしたとき、ブラウザサーバーに問い合わせずにローカルのコピーを使うから速くなるんだよ。

ひよこ ひよこ

CDNキャッシュっていうのも聞いたことがあるんだけど、あれはブラウザキャッシュとは違うの?

ペンギン先生 ペンギン先生

CDNキャッシュサーバー側の仕組みだね。CDNは世界中にエッジサーバーを配置していて、オリジンサーバー(大元のサーバー)のコンテンツをコピーして持っておくんだ。東京のユーザーは東京のエッジサーバーから、ニューヨークのユーザーはニューヨークのエッジサーバーからデータを受け取れるから、物理的な距離が縮まって高速になるよ。

ひよこ ひよこ

データベースキャッシュもあるって聞いたことがあるんだけど、どういうものなの?

ペンギン先生 ペンギン先生

データベースキャッシュはRedisMemcachedが代表的だね。データベースへのクエリ結果をメモリ上に保存しておいて、同じクエリが来たらデータベースに問い合わせずにメモリから返す仕組みだよ。データベースはディスクI/Oが発生するから遅いんだけど、メモリ上のキャッシュなら数百マイクロ秒で返せる。大規模なWebサービスではこれが必須なんだ。

ひよこ ひよこ

でもキャッシュしたデータが古くなったらどうするの?更新されたのに古い内容が表示されたら困るよね?

ペンギン先生 ペンギン先生

まさにキャッシュ最大の課題だね。これを解決するためにいくつかの戦略があるよ。まずTTL(Time To Live)で「このデータは何秒間有効」と決めておく方法。次にETagというハッシュ値サーバーが返して、ブラウザが次回アクセス時に「このETagのデータまだ有効?」と確認する方法。変更がなければ304 Not Modifiedが返ってきて、データ本体を転送しなくて済むんだ。

ひよこ ひよこ

他にもキャッシュを新しくする方法ってあるの?

ペンギン先生 ペンギン先生

「キャッシュバスティング」という手法もあるよ。CSSJSのファイル名にハッシュ値を付けて、内容が変わったらファイル名も変わるようにするんだ。例えば style.a1b2c3.css みたいにね。ファイル名が変わればブラウザは新しいファイルだと認識するから、古いキャッシュを使ってしまう問題が起きない。多くのフロントエンドのビルドツールがこの仕組みを自動でやってくれるよ。

ひよこ ひよこ

キャッシュヒット率っていう言葉も聞くんだけど、あれは何なの?

ペンギン先生 ペンギン先生

キャッシュヒット率は「キャッシュにデータがあった割合」のことだよ。100回アクセスして90回キャッシュから返せたらヒット率90%。一般的に80%以上あればいいとされるけど、CDNなら95%以上を目指すことも多いね。ただし、キャッシュは万能ではないよ。ユーザーごとに違うデータ(マイページなど)はキャッシュしにくいし、リアルタイム性が求められるデータ(株価や在庫数)もキャッシュすると不整合が起きる。

ひよこ ひよこ

キャッシュできないものもあるんだね。他に気をつけることはあるの?

ペンギン先生 ペンギン先生

キャッシュ銀の弾丸ではない」というのは覚えておくといいよ。キャッシュを導入するとデータの整合性管理が複雑になるし、キャッシュサーバー自体がダウンすると突然オリジンに全トラフィックが集中する「キャッシュスタンピード」という問題も起きる。あと面白いのは、Phil Karltonという人の「コンピュータサイエンスで難しいことは2つだけ。キャッシュの無効化と、名前付けだ」という名言があるくらい、キャッシュの適切な管理は難しいんだ。設計段階から「何をキャッシュして、いつ無効化するか」をしっかり考えることが大切だよ。