サービス別の構成例 — 同じ部品の組み合わせ方

概要 — まず全体をつかむ

初級では「同じ部品の組み合わせ方が違うだけ」と捉えました。中級では、サービスの性質が要求する設計パターンを見ます。

詳細 — 1段階ずつ追う

読み中心か、書き中心か

  • 読みが多い(SNSのタイムライン・記事) — キャッシュ、CDN、DBのリードレプリカで読みを分散
  • 書きの正しさが重要(決済・在庫) — トランザクションで整合性を守る。安易にキャッシュしない
  • リアルタイム(チャット・通知) — WebSocket/SSE でつなぎっぱなしに

通常のHTTPは「お願い→返す」の都度接続なので、更新が起きても聞くまで届きません。サーバから更新を押し出すには、つなぎっぱなしのWebSocket(双方向)やSSE(サーバ→クライアントの一方向push)を使います。

アニメーション『リアルタイム通信(WebSocket/SSE)』を開く
リアルタイム通信の3方式① 通常のHTTP(ポーリング)クライアントサーバ① お願い(リクエスト)② 返す(レスポンス)③ また最初から…(都度接続)更新が起きても、こちらが「聞く」まで届かない(毎回つなぎ直す)② WebSocket(双方向・開きっぱなし)クライアントサーバ送る →← 送る一度つなげば、どちらからでも即プッシュできる(双方向)③ SSE(サーバ→クライアントの一方向push)クライアントサーバ更新① を push更新② を push更新③ を pushサーバが更新を一方的に押し出す(クライアント→サーバの送信はできない)更新をサーバから届けたいときは WebSocket / SSE

SNSのタイムラインは「いつ配るか」で設計が分かれます。投稿時に各フォロワーへ配る(読みが速い)か、読むときに集める(書き込みが軽い)かのトレードオフです。

アニメーション『タイムラインの配り方(fan-out)』を開く
fan-out on write(書く時に配る)投稿時に配っておく投稿者1回投稿受信箱フォロワー毎受信箱フォロワー毎受信箱フォロワー毎読むとき速い ⇔ 書き込みが重い(配る先が多い)fan-out on read(読む時に集める)読むとき集めて作る投稿フォロー相手投稿フォロー相手投稿フォロー相手閲覧者読む時に要求書き込みが軽い ⇔ 読むときが重い(毎回集める)大量フォロワーの有名人は「読み時に集約」が定石(配る先が多すぎるため)

登場人物メモ:

  • ※1 リードレプリカ — 読み取り専用のDB複製。読みを逃がす
  • ※2 WebSocket — つなぎっぱなしの双方向通信
この部分をもっと深く(上級
  • 配信方式fan-out on write(投稿時に各受信箱へ)/on read(表示時に集約)。有名人問題ではハイブリッド
  • 読みの分散 — タイムラインは強くキャッシュ、DBはリードレプリカ
  • イベント駆動 — 通知・集計・検索インデックス更新は非同期
  • 整合の見せ方 — 自分の投稿は即見える(楽観的UI)、他人分は少し遅れてよい
やさしく言うと(初級
  1. 投稿する → フロントAPIバックDBに保存
  2. 添付の画像は → ストレージに保存(DBにはURLだけ)
  3. タイムラインは何度も見られる → キャッシュに載せてDB往復を減らす
  4. 「いいね通知」など → すぐ返さなくていいのでキューで後処理
  5. アイコン・CSS・JS → CDNで近くから配信

具体例で見る

  • チャット — WebSocketで双方向、メッセージはDB+キャッシュ、既読/通知はキュー
  • 動画配信 — アップロードは署名付きURLでストレージへ、変換はキュー、配信はCDN、視聴履歴はDB
  • ネットショップ — 商品はCDN/キャッシュ、在庫・注文はDBのトランザクション、決済は外部API、確定処理はキュー
この部分をもっと深く(上級
  • 在庫の同時実行 — 楽観/悲観ロック、原子的減算で超過販売を防ぐ
  • 決済 — 外部APIに委任+冪等キーで二重課金防止+サーキットブレーカ
  • 注文フロー — 複数サービスをまたぐのでSagaで整える
  • 検索 — DBの外に全文検索/検索エンジンを置く(DBのLIKEは重い)
やさしく言うと(初級
  1. 商品ページ(みんな同じ)→ CDN・キャッシュで高速化
  2. 在庫・注文・会員 → DBで正しく管理
  3. 支払い → 自前で持たず、外部の決済APIに委ねる
  4. 注文確定後のメール送信・集計 → キューで後回し

パターンの見取り図

  • スケール — ステートレス+ロードバランサで水平に。状態はDB/キャッシュへ
  • 整合性 vs 速さ — 強整合が要る所(在庫・残高)と、多少古くてよい所(タイムライン)を分ける
  • 障害設計 — 単一障害点を避け、リトライ・タイムアウト・フォールバックを用意
  • 外部依存 — 決済・地図・通知などは外部APIに委ね、失敗時の扱いを決めておく
この部分をもっと深く(上級
  • イベントソーシング/CQRS — 変更を events として蓄え、読み取り専用のリードモデルを作る
  • リードモデル — 表示に最適化した非正規化ビュー(結果整合で更新)
  • 外部依存の隔離 — 決済・地図・通知の障害を、タイムアウト/フォールバックで閉じ込める
  • マルチリージョン — 近さと可用性のため、データの分散と整合を設計
やさしく言うと(初級
  • 読み(見る)が多い → キャッシュ・CDN で軽くする
  • 書き(変える)の正しさが大事 → DB とトランザクション
  • 重い処理・急な増加 → キューで後回し、サーバを増やす

サービスの性質で「どの部品を厚くするか」が変わるだけ、と分かると、初めて見る構成図も読めるようになります。

⚠️ つまずきどころ

  • 何でもキャッシュ — 在庫や残高をキャッシュして二重販売・不整合
  • 同時実行の見落とし — レースコンディション(在庫・ポイント)
  • 外部API頼み — 決済APIが落ちたときの設計が無い
  • リアルタイムの過負荷 — 接続数の増加に耐える設計(水平分割)が要る
この部分をもっと深く(上級
  • 有名人問題 — fan-outの偏り、ホットキー
  • 二重課金 — 決済の冪等性・整合
  • 超過販売 — 在庫の競合制御漏れ
  • 結果整合の体験 — 「反映が遅い」をUIでどう見せるか(楽観的更新と巻き戻し)
やさしく言うと(初級
  • 動画配信 — ストレージと配信(CDN)、変換処理(キュー)が主役で重い
  • SNS — 大量のタイムライン生成が重い(キャッシュ設計が肝)
  • ネットショップ — 在庫の同時購入など、正しさ(整合性)が難所

理解度チェック

そのまま解けます(成績は保存されません)。無料アカウントを作ると、学習の記録と進捗の山登りが始まります。

1. ネットショップで「在庫1個を2人が同時に買う」を正しくさばくのに必要なのは?

2. チャットの「相手の発言がリアルタイムに届く」を実現する代表的な仕組みは?

3. 複数の処理が同時に走り、実行の巡り合わせで結果が変わってしまう問題を何と呼ぶ?

4. サーバからクライアントへの一方向のリアルタイムpush(通知の配信など)に向く仕組みはどれ?

5. 動画配信サービスで、大きな動画ファイルをブラウザからストレージへ直接アップロードさせるのに使うのはどれ?

6. 在庫や残高を安易にキャッシュすると起きやすい問題はどれ?

7. サーバを並べて負荷を分散する「水平スケール」の前提となる設計はどれ?

8. 読み取り専用のDBの複製を用意して読みの負荷を逃がす仕組みを、カタカナで何と呼ぶ?