キャッシュ戦略
1)キャッシュの理由とそれを行う場所
キャッシュは、高価なリソース(CPU/DB/外部 API)のレイテンシと負荷を低減する高速メモリ層です。重要な目標:- 速度(p95/p99より低い)、費用(より少ない出口/CPU)、安定性(ピークの下でより少ない依存性)。
- 「騒々しい隣人」からのピークの平滑化と分離。
1.クライアント(ブラウザ/モバイル)-HTTPキャッシュ、IndexedDB、ローカルストレージ。
2.Edge/CDN-POPノードはユーザー、キャッシュ静的、およびAPIの一部に近い。
3.L7-gateway/Reverse-proxy-Nginx/Envoy/Varnish (microcash、 SWR)。
4.サービスキャッシュ-クラスタ内でRedis/Memcached。
5.インプロセス-インメモリ(カフェイン/グアバ/LRUマップ)。
6.データベース内のキャッシュ-材料表現、セカンダリインデックス。
ルール:できるだけ消費者の近くにキャッシュしますが、一度真実を保ちます。
2)キャッシュパターン
2.1キャッシュアサイド(「遅延ロード」)
アプリケーションは最初にキャッシュから読み取ります。ミスの場合-ソースから、その後、キャッシュに書き込みます。
長所:シンプルさ、コントロール。短所:コールドスタート、不一致ウィンドウ。
2.2読み取りスルー
読み取りは常にキャッシュを介して行われます。読み取りが失敗したときにソースに移動します(library/proxy layer)。
TTL/シリアル化ポリシーを一元化するのに便利です。
2.3ライトスルー/ライトバック(ライトバック)
Write-through: write to cache and source synchronously→consistency higher、 latency higher。
書き込み:キャッシュに書き込み、非同期フラッシュをソース→高速に書き込みますが、損失と競合のリスクがあります。
2.4リフレッシュアヘッド(プロアクティブ)
「TTLはすぐに期限切れになります」と予測し、バックグラウンドでキーを更新し、スタンピードを防ぎます。
2.5負のキャッシュ
短いTTLに「no data/404/empty」をキャッシュすると、ソースへの負荷が軽減されます。
2.6マイクロキャッシング
非常に短いTTL (0。5-5 s)のL7の「ほぼダイナミクス」(リスト、メイン)-テールを大幅に削減します。
3) HTTPキャッシュ: ヘッダーとコントロール
3.1基本的な見出し
'Cache-Control': 'max-age'、 's-maxage'(共有кэшей)、 'public/private'、 'no-store'、 'stale-while-revalidate'、 'stale-if-error'。
バリデータ:'ETag'(コンテンツハッシュ)、'Last-Modified'。
条件を持つクエリ:'If-None-Match'、 'If-Modified-Since'→304 Not Modified。
3.2異なるとキー
'Vary: Accept-Encoding、 Authorization、 Cookie、 Accept-Language'-異なるキャッシュオプションを生成します。カーディナリティを「爆破」しないように「Vary」を最小化します。
3.3 HTTPレスポンスの例
Cache-Control: public, max-age=60, s-maxage=300, stale-while-revalidate=60
ETag: "a1b2c3"
Vary: Accept-Encoding
4)主設計およびTTL
4.1つのキー
構造:'tenant: user: {id}: profile: v3'(スキーマバージョンを含む)。
キーのPIIを避けます。
コレクションの場合-キー+クエリパラメータ(正規化とソート)。
4.2 TTLと一貫性
短いTTLはミスマッチを減少させますが、ミスマッチを増加させます。
重要なデータ-バリデータ('ETag')とSWR (stale-while-revalidate)。
ほとんど変わらない-長いTTL+障害の「爆弾」。
4.3バージョン管理/バスティング
互換性のない変更の場合は、プレフィックス/キーバージョン('v2→v3')を変更してください。
静的リソースの場合-ファイル名のコンテンツハッシュ。
5)障害: 戦略と実践
5.1直接削除
プロキシ上の'DELキー'/'PURGE'。危険:削除と複数の読者の間のレース。
5.2サロゲートキー
ドキュメントをタグ(category/author)のセットに関連付けます。障害-タグ別。
ニス/エッジ-'Surrogate-Key: article: 42 tag: author: 7'+'BAN tag: author: 7'。
5.3イベント主導の障害
Pub/Sub (Kafka/NATS):ソースが変更されると「、無効」イベントを公開します。
キャッシュの消費者は、キーの聴取と削除/更新を行います。
5.4つの二相
まず、キーの古い(ソフトTTL)をマークし、古いサービスを提供し、バックグラウンドで更新し、原子的に置き換えます。
6) stampede/dogpileおよび熱いキーを扱うこと
6.1リクエスト合体(シングルフライト)
あるプロデューサーはキーを更新し、残りは結果を待っています(mutex/label 「updates」)。
6.2 ジッターTTL
同期腫れを避けるために、TTLにランダム性(± 10-20%)を追加します。
6.3 ソフトTTL+ハードTTL
soft-TTLの前に、リフレッシュトリガーと並行してキャッシュからサービスを提供します。by hard-TTL-我々はミスを考慮します。
6.4ホットキー
共有(2層)上のローカルキャッシュ。
複数のシャードおよびランダムな選択へのホットキーのレプリケーション(読み取り専用)。
特定のキーを更新するためのレート制限。
6.5 Redis+Lua(シングルフライトスケッチ)の例)
lua
-- SETNX lock with TTL to avoid deadlocks local ok = redis. call("SET", KEYS[1], "1", "NX", "EX", ARGV[1])
if ok then return "LOCKED"
else return "WAIT"
end
7)プリエンプションポリシーとキャッシュレセプション
7.1立ち退き
LRU:シンプルで局所性に優れています。
LFU:「長生き」ホットキーの方が良いです。
ARC/TinyLFU: recency/frequency balance。
7.2入場料
巨大なレアオブジェクト(TinyLFU/Bloomフィルタ)を入れないでください。
サイズ/レイテンシー境界での大きな値(LZ4/Zstd)の圧縮。
8)チャーディングとトポロジー
8.1一貫したハッシュ
ノードにキーを安定して分配し、クラスタの成長/圧縮時の移動を低減します。
8.2 Redis/Memcachedトポロジ
Redisクラスタ(スロット/シャード)、Sentinel (feilover)、読み取り専用レプリケーション。
Memcachedは、サーバーレベルのレプリケーションを行わないクライアントサイドのシャーディング(ケタマハッシュ)です。
8.3ローカル+分散
カスケード:in-proc (micro-TTL/LRU)→Redis (TTLより長い)→source。
TTLコロンとキャッシュバリデータには注意してください。
9)エッジ、CDN、 L7キャッシュ
9.1マイクロキャッシュNginx
nginx proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=api:100m inactive=10m;
map $request_method $skip_cache { default 0; POST 1; PUT 1; DELETE 1; }
server {
location /api/list {
if ($skip_cache) { add_header Cache-Control "no-store"; }
proxy_cache api;
proxy_cache_valid 200 2s; # micro-cache proxy_cache_use_stale error timeout updating;
proxy_cache_background_update on; # SWR add_header X-Cache $upstream_cache_status;
proxy_pass http://upstream;
}
}
9.2特使(SWRと条件)
yaml http_filters:
- name: envoy. filters. http. cache typed_config:
"@type": type. googleapis. com/envoy. extensions. filters. http. cache. v3. CacheConfig typed_config:
"@type": type. googleapis. com/envoy. extensions. http. cache. file_system_http_cache. v3. FileSystemHttpCacheConfig cache_path: "/var/cache/envoy"
9.3ニス(サロゲートキー)
バッチ障害のタグに「サロゲートキー」と「禁止」を使用します。
10)キャッシュとデータの整合性
10.1あなたの読み書き
ユーザープロファイル/ごみ箱の場合、短いTTL、書き込みスルー、またはクライアントマーキング(書き込み後N秒間バイパス)を提供します。
10.2 イベントvs強い
推奨/分析-最終的な+長いTTL。
マネー/オーダーのステータス-短いTTL、検証、時にはクリティカルパスのキャッシュなし。
10.3不変量
厳密なTTLと再検証なしでセキュリティ/ACLに影響を与えるフィールドをキャッシュしないでください。
11)観察可能性、SLOおよび管理
11.1メトリクス
hit_ratio(ルートごとのобщий)、 byte_hit_ratio、 miss_rate。
、 、 、 。
レイテンシー:p50/p95/p99のキャッシュとソースのキャッシュ。
hot_keys_topNとそのQPS/バイト。
11.2ログとトレース
「X-Cache: HIT/MISS/STALE/UPDATING」と記録します。
トレースでは、応答のソース('cache=true'、 'tier=edge' service 'local')をマークします。
11.3 SLOアプローチ
例: "API/カタログ p99 ≤ 250msの場合、キャッシュのヒット率≥ 85%、スタンピード≤ 0。リクエストの1%"
11.4つのRunbooks
「成長ミス」→TTL、ウォームアップ/障害、ホットキー、キャッシュサイズ、受け入れポリシーをチェックします。
12)安全および複数のテナント
キーにテナントIDを埋め込む(およびHTTPの'Vary'に)。
プライベートレスポンスを「公開」としてキャッシュしないでください。
機密データでキャッシュを暗号化するか、非PII/IDのみを保存します。
13)典型的なレシピ
13.1カタログ/テープ(ほぼ動的)
Edge-microcash 1-3 s+SWR、内側-15-60 sのRedis、更新イベントによる障害。
13.2ユーザープロフィール
TTL 30-120 sとキャッシュアサイド、プロファイル更新後5-10 sをバイパス(クッキー/ヘッダー)、または書き込みスルー。
13.3通貨コース/参考書
新しいデータが公開されたときの長いTTL(分時間)+目標障害;条件付きGETの'ETag'。
13.4検索結果
Edge-microcash 1-2 s、 inside-リフレッシュアヘッドと結合、キー内のクエリパラメータの正規化。
14)アンチパターン
障害のない現金:TTLのためにのみ希望→無関係の長いウィンドウ。
巨人'Vary':オプションの「爆発」→低ヒットレート。
prod/experiments→contaminationのための単一キャッシュ。
TTLの有効期限が切れるとstampede→sourceスパイクに対する保護はありません。
厳密な保証のない現金/権利/ACLキャッシュ。
「行のすべて」の圧縮-余分なCPU、小さなオブジェクトのp99の劣化。
15)実装チェックリスト
- キャッシュレベルとターゲット(edge/service/local)を定義します。
- 設計キー(バージョン管理、テナント、パラメータ正規化)。
- パターンを選択します(cache-aside/read-through/refresh-ahead)。
- TTL/soft-TTL/jitterを設定し、SWRを有効にします。
- 合体/シングルフライト、スタンピード保護を実装します。
- 障害の整理(イベント、タグ、パージ/禁止)。
- ヒット比/レイテンシーメトリックと「X-Cache」ダッシュボードを入力します。
- ホットキー負荷テストを実行します。
- SLOとrunbooksを書く。
- セキュリティ/テナントの分離を確認し、'Vary'。
16) FAQ
Q:キャッシュアサイドまたはリードスルーを選択するには?
A:簡単なサービスのために-キャッシュ脇。一元化と単一のポリシー-読み取り。
Q:最適なTTLを理解するには?
A:許可された陳腐化、更新の頻度および目標のヒットレートから始めて下さい;ジッタを追加し、p95/p99/costを観察します。
Q: write-backはいつ適切ですか?
A:高負荷ストリームの場合、最終的な一貫性が許容され「、追加」のための信頼できるキュー/ログがあります。
Q:承認されたレスポンスはキャッシュできますか?
A:はい、しかし'private'および/または/'Vary'スイッチのテナント/ユーザーを含んで下さい。真にプライベートなクライアントキャッシュの場合。
Q:キャッシュをウォームアップするには?
A:人気のあるキーのリスト、背景の悪化、ログからの再生、リリース/ピーク前のウォームアップ(ブラックフライデーなど)。
17)合計
効果的なキャッシュは、イベント障害、SWR/リフレッシュアヘッド、およびスタンピード保護によって強化された、キー設計+合理的なTTL+よく選択されたパターンです。キャッシュ(クライアント/エッジ/サービス)を階層化し、観測性とSLOを追加し、安定したレイテンシテイル、予測可能なコスト、ピークレジリエンスを取得します。