キャッシュヒット率

生田 陸人
LuaGate エンジニア / 現役エンジニア
編集 LuaGate編集部

キャッシュヒット率

このレッスンで分かること

  • Web サーバ、DB、CPU の L1 キャッシュ、ブラウザのリソースキャッシュ
  • キャッシュ にデータがあって読み込みに成功すれば hit、無くて元データを取りに行くのが miss です
  • 100 を掛けてパーセント表記にするのが慣例です

キャッシュヒット率 とは

ヒット数と総アクセス数からキャッシュヒット率をパーセントで返す。本レッスンでは、キャッシュヒット率 の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。

Web サーバ、DB、CPU の L1 キャッシュ、ブラウザのリソースキャッシュ。キャッシュ はどの階層にも存在し、その効きを測る最重要指標が ヒット率 (hit rate) です。アプリの体感速度を左右し、コスト最適化 の主戦場でもあります。

ヒット率は ヒット数 / 総アクセス数 * 100 でパーセント表記する単純な割合計算です。単純ですが、システム性能を語る共通言語 です。

ヒットとミスの定義

キャッシュ にデータがあって読み込みに成功すれば hit、無くて元データを取りに行くのが miss です。総アクセス数 total = hit + miss であり、ヒット率は次の式で求めます。

プレーンテキスト

hit_rate = hits / total * 100

100 を掛けてパーセント表記にするのが慣例です。0.85 のような 比率 を返す API もありますが、人間に見せる指標としては 85.0% の方が直感的です。DatadogCloudWatch のグラフを見るときも、% 表示の方が 閾値 を設定しやすいという実用的な理由があります。

0 除算の落とし穴

total = 0、つまり一度もアクセスがない状態でこの式を計算すると Python では ZeroDivisionError 例外が発生し、JavaScript では NaN が返ります。本番システムで NaN が表示されて事故になる典型パターンです。本問題では、total が 0 の場合は 0.0 を返す という仕様にします。

Python

def cacheHitRate(hits, misses): total = hits + misses if total == 0: return 0.0 return hits / total * 100

JavaScript

function cacheHitRate(hits, misses) { const total = hits + misses; if (total === 0) return 0.0; return (hits / total) * 100; }

0 除算は 防御的プログラミング の入口。if total == 0 の一行を書く習慣をつけましょう。

浮動小数点の比較

テストでは expected: 85.0 のように整数値や 0.5 刻み を使い、誤差 を生まないように設計します。実務では Math.abs(actual - expected) < 1e-9 のような近似比較を入れるのが安全です。pytest.approxJesttoBeCloseTo のように、ライブラリが用意している 近似一致 の API を活用しましょう。

diagram (will load when visible)

実システムでの解釈

L1 キャッシュ のヒット率は 95% 以上 が普通、CDN の静的ファイルは 90% 以上 を目指します。Web アプリの DB クエリキャッシュは 60〜80% でも十分効果があり、低い場合は クエリパターン の見直しが課題になります。RedisINFO stats で出る keyspace_hitskeyspace_misses から、この式そのままで実運用のヒット率が計算できます。

ヒット率は数字そのものではなく、それを どう改善するか の議論を始めるための指標です。

ヒット率を上げる打ち手

  • キャッシュサイズを増やす (maxmemory を上げる)
  • TTL (生存時間) を長くする
  • LRU のような追い出しポリシーを最適化する
  • そもそも キャッシュキー の設計を見直す (正規化 する、不要なパラメータを削る)
  • アクセスパターンに合わせて ウォームアップ を実施する

ヒット率はあくまで指標であり、LatencyBackend QPS と合わせて見ないと判断を誤ります。80% ヒット率でも遅い ケースは、miss 時の処理 が重すぎる、つまり 元データ取得のコスト が問題かもしれません。

関数の戻り値の精度

本問題では 85.0 のような数値を返します。return Math.round(hits / total * 100 * 10) / 10 のように 小数第 1 位 で丸める設計もありますが、精度 を捨てる責任を関数に押し付けると、テストやログ集計で困ることがあります。生の比率 を返し、表示時に整形するのが安全です。

よくある間違い

  • hits / misses で計算してしまう (分母が total ではなく miss)
  • total = 0 のケースを忘れて InfinityNaN を返す
  • パーセント化の * 100 を忘れる

やってみよう

  • miss rate も同時に返す版を書いてみる
  • 引数を アクセスログの配列 ["hit", "miss", "hit"] にして集計する版を書く
  • 直近 N 回 の移動平均でヒット率を返す関数を書く
  • 階層キャッシュ (L1 → L2 → 元データ) のヒット率を集計する関数を書く

よくある質問

Q. このトピックを覚える意味は何ですか?

A. Redis や CDN、DB クエリキャッシュのモニタリングでヒット率は最重要指標です。ヒット率が低下したときに原因を特定し、TTL 調整やキャッシュキー設計の見直しといった改善策を判断できるようになります。実務での問題解決スピードが格段に上がります。

Q. 実務でこの知識を使う場面は?

A. API の Content-Length 計算、ファイルアップロードのサイズ制限、画像処理での色深度計算など、低レベルな数値を扱う場面で頻出します。OS・ネットワーク・暗号の理解にも繋がるため、CS の共通言語と思って習得しておくと一生使える知識です。

Q. 他の章とどう繋がりますか?

A. 後続の章で扱うデータ構造(スタック・キュー)、アルゴリズム(探索・ソート)の基礎になります。「データを 32 bit でどう表現するか」「メモリにどう載せるか」が分かると、後続トピックの実装が腹落ちしやすくなります。

次のレッスン

次は LRU 簡易シミュレーション に進みましょう。

事前確認 — 進む前に次の 3 つができることを確認しましょう。

  1. ヒット率 の要点を自分の言葉で説明できる
  2. このレッスンの最小コード (または操作手順) を見ずに書ける
  3. 練習問題やクイズで間違えた箇所を読み直して理解した

理解度チェック (30 秒)

Q. ヒット率 とは何か、1 文で説明してください。

この章のポイント

A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。

関連レッスン

要件

  1. cacheHitRate という名前の関数を実装すること
  2. ヒット率をパーセントで返すこと (100 倍する)
  3. hits + misses が 0 の場合は 0 を返すこと

入出力例

test-cases.txt

cacheHitRate(85, 15)85 cacheHitRate(1, 1)50 cacheHitRate(0, 10)0 cacheHitRate(10, 0)100 cacheHitRate(0, 0)0

ヒント

main.py
main.py
学習モード

メモ

キャッシュヒット率

⌘S で保存