← ログ・モニタリング バージョニング・パッケージ管理 →

📑 この章の目次

title: キャッシュ・非同期処理 icon: ⚡ card_desc: 処理を速くする・後回しにする技術の使い分け — キャッシュ/無効化/TTL・非同期/キュー・同期との違い slug: 09-cache-async

09 キャッシュ・非同期処理 — 処理を速くする・後回しにする技術の使い分け

「ページの表示が遅い」「重い処理でユーザーを待たせている」——この2つの問題に、開発現場は決まって2つの技術で立ち向かいます。キャッシュ(結果を使い回して速くする)と非同期処理(重い処理を後回しにする)です。この章では、この2つの本質と使い分けを根本から理解します。


一言でいうと

キャッシュは、一度取得・計算した結果を使い回して速くする技術。非同期処理は、時間のかかる処理を後回しにしてユーザーを待たせない技術。この2つは「速くする」という目的で語られますが、根本的に別の仕組みです。キャッシュは「同じ計算を何度もしない」・非同期は「重い処理を待たせない」と、それぞれの得意な問題に使い分けます。


1. なぜキャッシュ・非同期処理が必要なのか

Webサービスにおいて、速さは機能と同じくらい重要です。

ここで問題になるのは、2種類の「遅さ」です:

遅さの種類 向く技術
同じ問い合わせを何度も繰り返す 人気商品ページを毎回DBから組み立てる キャッシュ(結果を使い回す)
1回の処理そのものが重い メール送信・画像変換・大量集計 非同期処理(後回しにする)

キャッシュと非同期処理は、この**別々の「遅さ」**にそれぞれ効く技術です。


2. キャッシュとは —— 結果を使い回す

キャッシュcache/「隠し場所」由来)は、一度取得・計算した結果を一時保存しておき、次はそれを使い回す仕組みです。「同じ問いには同じ答え」を、毎回やり直さずに返せます。

どこに置くか

キャッシュは、本来のデータ源(データベース等)の手前に置きます:

ユーザー → [キャッシュ] → データベース
            (あれば即返す)  (なければ取りに行く・キャッシュにも保存)

💡 キャッシュの保管場所としては、Redis(→ 第7章)のようなキー・バリュー型 NoSQL や、アプリのメモリがよく使われます。静的ファイル(画像・CSS等)なら CDN(シーディーエヌ/Content Delivery Network)—— 世界中のサーバーにファイルを配置し、ユーザーに地理的に近い所から配信する仕組み —— が代表例です。

例えていうと: 冷蔵庫

毎回スーパー(データベース)に行かず、**冷蔵庫(キャッシュ)**に食材を保存しておいて使い回す。冷蔵庫にあれば早いが、在庫が古くなる問題(後述)もある。


3. 🔑 キャッシュの核心 —— 速さと新しさのトレードオフ

ここが本章の核心の1つ目です。キャッシュの最大の難しさは**「古くなる」**ことです。

古さ(一貫性)の問題

キャッシュは**「副本(コピー)」です。本体(データベース)が変わっても、キャッシュが古いままなら「更新したのに画面が変わらない」**事故が起きます。

これを防ぐのが無効化invalidation/「キャッシュを捨てる」)です。本体が変わった時にキャッシュも消し、次回は新しく取り直させます。

TTL —— 寿命を決める

毎回無効化を管理するのは複雑なので、TTL(ティーティーエル/Time To Live/「寿命」)を設定する方法がよく使われます。「このキャッシュは5分間有効」のように期限を決め、過ぎたら自動で捨てられます。新しさの保証は「TTLの時間分だけ遅れる」ことで緩和されます。

重要 キャッシュは「速さ」と「新しさ」のトレードオフです。速くすればするほど古いデータを見せるリスクが増え、新しさを厳密に保てばキャッシュの効果が薄れます。**「どのデータを・どの程度古くても許すか」**をデータごとに判断するのが設計の核心です。

💡 業界有名な格言: 「計算機科学の難問題は2つしかない。命名とキャッシュ無効化だ」。キャッシュ無効化の設計がいかに難しいかを示す冗談で、現場でも共感されて広く使われます。


4. 非同期処理とは —— 重い処理を後回しにする

非同期処理asynchronous/通称 async/エイシンク)は、時間のかかる処理の完了を待たず、先へ進む方式です。「後でやる」仕組みで、ユーザーを待たせません。

同期 vs 非同期

例: ユーザー登録で「確認メールを送る」処理。

キューとワーカー

非同期処理は**「依頼を並べておいて、別の係が順に処理する」**仕組みで実現します:

アプリ → [キュー(依頼の列)] → ワーカー(処理係)→ 実行
   (即座に依頼だけ置いて戻る)  (順に取り出して実行)

例えていうと: レストラン

注文をとったら伝票を厨房に回して、すぐ客席に戻る(非同期)。料理ができるまで客をカウンターで立たせ続けない(同期ならそうなる)。料理は厨房(ワーカー)が順に作る。


5. 🔑 キャッシュと非同期の使い分け

ここが本章の核心の2つ目です。この2つは「速くする」で語られますが、目的が違います。混同しないことが大切です:

キャッシュ 非同期処理
目的 同じ計算を何度もしない 重い処理を待たせない
効く問題 同じ問い合わせが頻発する 1回の処理そのものが重い
人気商品ページの組み立て メール送信・画像変換・集計
速さの正体 結果の使い回し 処理の後回し
主な落とし穴 古いデータ(一貫性) エラーの握り潰し・順序

重要 「速くする=キャッシュ」ではありません。「同じ結果を何度も計算している」ならキャッシュ、「1回の処理がそもそも重い」なら非同期、と原因で選びます。両方組み合わせる(重い処理の結果をキャッシュする等)こともあります。


6. なぜ「キャッシュ・非同期」が開発の作法なのか

ここまでを読むと、パフォーマンス改善が「道具を知っているか」でなく**「遅さの原因を見極めて適切な技術を選べるか」**の問題だと分かります。

作法として位置づけられる理由

  1. パフォーマンスは機能要件: 「遅い」はバグと同じ。速さを設計に組み込むのがプロの態度
  2. 原因別の引き出し: 遅さの原因(N+1・インデックス不足・キャッシュ不足・重い同期処理)ごとに、適切な手段を持つ
  3. トレードオフの理解: キャッシュは新しさ・非同期は即時性と、それぞれ代償を伴うことを知って使う

面接・実務での意味

「サービスが遅いと聞きました。どう調査し、どう改善しますか?」

この質問は、「パフォーマンス問題を論理的に切り分けられるか」を聞いています。「まず原因を特定する(DBは速いか・ネットワークは・計算量は)→ それに応じてインデックス・キャッシュ・非同期のいずれかを選ぶ」と原因から手段を逆算できる人が、現場で信頼されます。


7. よくある落とし穴と対処

落とし穴 何が起きるか 正しい対応
キャッシュの無効化忘れ 古いデータが表示され続ける(一貫性崩壊) 本体変更時に確実に無効化・TTLで寿命を設定
キャッシュ雪崩(stampede) TTL一斉切れで全キャッシュミス→DBに殺到 期限にばらつきを持たせる・再生成を1件に絞る
キャッシュしすぎ メモリ枯渇・無駄な保存 本当に繰り返すものだけキャッシュする
非同期のエラー握り潰し 失敗に気づかず、依頼が「消えた」ように見える 失敗をログ・リトライで確実に扱う(→ 第8章
非同期の順序依存を見落とす 「Aの後にB」が必要なのに順不同で壊れる 順序が重要なら同期にする・キューで順を保証
非同期=魔法と思い込む 結局処理は遅いまま(後回しにしただけ) 非同期は待たせないだけで、処理自体の重さは解決しない

💡 キャッシュ雪崩(スタンピード/cache stampede): 多くのキャッシュが同時にTTL切れすると、一気に全リクエストがキャッシュミスになり、本来のデータ源(DB等)に殺到してダウンさせる事故。TTLに多少のランダムさを持たせる等で防ぎます。


まとめ

💡 次のステップ: 処理を「速くする・後回しにする」技術が見えました。次は、ソフトウェアの**「バージョン」**の話です。第10章では、「1.2.3」のような番号の意味と、依存ライブラリの管理(パッケージ管理)の作法を扱います。