System Design入門 設計判断を数字とコードで確かめる
つくる 設計書1枚
この回でやること
設計書の他の節は見本として使い、一意制約・トランザクション・冪等キーの役割を踏まえた保存方針だけを4行で書きます。
- 読む 約 7 分
予約サービスで解いてみる
8章の判断を束ねた、席の予約サービスの設計書1枚の完成見本です。今回は第4節の保存方針だけを4行で書きます。他の節は見本として使い、数字と名前をそのまま引き継ぎます。
1 要件
利用者は空席を見て、予約と自分の予約の取り消しができます。在庫の変更は運営に限り、席の二重確定を防ぎます。
応答時間の仮目標は p95 で300ミリ秒以内です。予算は月5万円で、決済と多言語対応は次の版に回します。
2 規模
DAU 3万、1人6回なら1日18万件です。件数を86400秒で割ると約2.08で、第2章の規模シートでは平均2 QPSに丸めています。
ピーク係数50で100 QPS、1台40件毎秒なら100÷40=2.5を切り上げて3台です。丸めた値なので、発売開始の実測で確認します。
3 構成
lb が要求を3台の app に振り分け、app は共有の database に予約を保存します。通知は app から queue へ渡し、worker が処理します。
app は共有のキーバリュー保存先からセッションを読みます。名前は流れ図と監視でも揃え、台数は規模シートに置きます。
繋がりだけでは故障の影響が分かりません。続く節に、データと運用の判断を残します。
4 保存
公演の席、利用者、予約をリレーショナルな保存先で管理します。同じ席の確定は一意制約とトランザクションで守り、冪等キーにも重複を許しません。
一意制約は、指定した値の組を重複して保存させない規則です。この予約サービスでは確定中の予約について「公演IDと席番号」の組を1件に限ります。別の公演なら同じ席番号を使えます。取り消した予約は履歴として残しても、確定中の席を占める対象から外します。
別の題材で考えると、会員証の番号を一意にする規則があれば、2人を同じ会員証番号で登録しようとしても片方しか保存できません。名前が違っていても番号が同じなら重複です。
予約で二人が異なる鍵を使って同じ公演の同じ席を同時に選ぶと、どちらも空席を見られることがあります。一意制約は両方の確定保存を許さず、片方の予約だけを成功させます。トランザクションは在庫変更と予約保存をまとめ、保存に失敗した側の在庫変更も取り消します。単にトランザクションで囲むだけで、同じ席の重複を防げるとは限りません。
冪等キーは同じ要求の再送を識別し、成功済みの結果を返すためのものです。二人の異なる鍵が同じ席を選ぶ競合は、席の一意制約で防ぎます。鍵にも一意制約を置き、同じ鍵が同時に届いた場合は保存済みの結果を確認して返します。
予約は1日3000件、1件512バイト、1年保持を前提にします。操作ログ、索引、複製の容量は本体と分けて加算し、空席の表示は短いキャッシュを許します。
5 非同期と失敗
予約では冪等キーを先に確認し、既存の結果があれば返します。初回だけ在庫の確認と予約の保存を同じトランザクションで行い、保存の成功後に確定を返します。
通知用の仕事も予約と一緒に記録し、別の処理がキューへ送ります。再送で通知を重複させない鍵を持ち、再試行の上限を超えた仕事は別の置き場で確認します。
6 制限
利用者ごとの短い集中はトークンバケットで許し、継続的な連打を抑えます。受け付ける総量も制限し、保存先の上限に届く前に断ります。
制限した件数から、正当な利用者を断っていないか見直します。再試行でも予約の冪等キーは変えません。
7 運用
アプリは生存確認と応答時間、保存先は接続数、キューは滞留と待ち時間を測ります。保存先は単一障害点として明記し、復旧手順と担当者を決めます。
費用と失敗率も測ります。ログへ秘密を残さず、利用者の予約と運営の在庫操作の権限を分けます。
8 決定記録
記録008、2026年10月5日、題は「セッションの共有」。3台を入れ替える背景から共有のセッション保存先を選び、台への振り分けを固定する案を捨てました。
入れ替えが容易になる一方、保存先の費用と監視が増えます。前提が変わったら、古い記録を残し、新しい決定を足します。
今回は第4節の保存方針だけを書き換えます。他の節を作り直す必要はありません。全体を書くときはこの並びを使い、節ごとの数字と名前を照合します。
演習
次の4つの空欄を、それぞれ1文で埋めてください。コードの提出はありません。第4節の容量の見積もりと、第1〜3節・第5〜8節は上の見本を使います。
1 保存するデータと、確定中の席で重複を禁止する組を[ここに書く]。
2 二人が同じ席を同時に選んだとき、保存先が許す確定を[ここに書く]。
3 在庫変更と予約保存の途中で失敗したとき、残さない変更を[ここに書く]。
4 同じ要求の再送では何を返し、異なる鍵の席の競合は何で守るかを[ここに書く]。書けたら、別の公演の同じ席を禁止していないか、失敗した予約だけが在庫を減らさないか、冪等キーだけで二人の競合を防ごうとしていないかを確認します。