System Design Primer
donnemartin/system-design-primer の日本語READMEを、面接と実務の両方で使える「設計判断の地図」として再構成。
System Design Primer は、大規模システム設計の学習素材、設計トピック、面接課題、補助的な暗算メモを体系化したオープンソースの索引。単なる用語集ではなく、「何を聞くか」「どこを深掘るか」「どのトレードオフを説明するか」を組み立てるための教材になっている。
README-ja.md の学習指針は「全部やれ」ではなく、持ち時間と経験に応じて幅・深さ・演習量を調整する考え方。まず全体を広く把握し、面接課題と実世界アーキテクチャで具体化していく。
| 期間 | 学習範囲 | 演習量 | 狙い |
|---|---|---|---|
| 短期 | システム設計トピックを広く読む | いくつかの課題 | 会話で詰まらない最低限の地図を作る |
| 中期 | 広く読み、重要領域をそれなりに深掘る | 多くの課題 | 自分の回答と模範解答を比較できる状態にする |
| 長期 | トピック、企業ブログ、実世界アーキを深く追う | ほぼ全ての課題 | 設計選択の理由と失敗条件まで説明する |
使用例・制約・推計を聞く
誰が使うか、機能、入力と出力、データ量、RPS、読み書き比率を質問で固める。
高レベル設計を描く
主要コンポーネントと接続をスケッチし、なぜその構成なのかを説明する。
核となる部品を深掘る
URL短縮ならハッシュ、衝突、SQL/NoSQL、スキーマ、APIなどを具体化する。
ボトルネックとスケールを議論する
ロードバランサー、水平スケール、キャッシュ、シャーディングとその副作用を扱う。
パフォーマンス問題は一人のユーザーにとって遅い状態。スケーラビリティ問題は一人では速いが、多数のリクエストで遅くなる状態。
レイテンシーは結果が返るまでの時間。スループットは単位時間あたりの処理数。通常は許容レイテンシー内で最大スループットを狙う。
CAPでは、一貫性・可用性・分断耐性のうち同時保証できるのは二つまで。ネットワークは信頼できないため、実務ではCPかAPかを選ぶ。
アトミックな読み書きが重要ならCP。結果整合性や停止しないことが重要ならAP。ここでの選択が、データベース、キャッシュ、キュー、API設計の細部に波及する。
SQL/RDBMSは構造化データ、厳格なスキーマ、リレーショナルデータ、複雑なJOIN、トランザクションに向く。スケール手段は読み書きの性質によって選ぶ。
NoSQLは正規化を弱め、アプリケーション側でJOINすることが多い。BASEは一貫性より可用性を優先する説明として使われる。
| 選択 | 向く条件 | 注意点 |
|---|---|---|
| SQL | 構造化データ、厳格なスキーマ、複雑なJOIN、トランザクション、成熟したエコシステム | 水平分割や分散JOINでアプリケーションロジックが複雑になる |
| NoSQL | 準構造化データ、柔軟なスキーマ、TB/PB級データ、高いIOPS、ログやクリックストリーム | ACIDより結果整合性を選ぶ場面が多く、整合性モデルを説明する必要がある |
キャッシュは読み込み時間とDB負荷を下げるが、真のデータとの整合性と更新タイミングが難所になる。
| パターン | 要点 |
|---|---|
| Cache aside | アプリがDBを読み、ミス時だけキャッシュへ追加 |
| Write through | キャッシュが同期的にデータストアへ書く |
| Write behind | 書き込みを非同期化して性能を上げるが、損失リスクあり |
| Refresh ahead | 期限切れ前にホットな項目を更新する |
非同期ワークフローは、インラインで処理するとリクエスト時間を圧迫する重い処理を分離する。キューが膨らみすぎる場合はバックプレッシャーで制限し、必要ならHTTP 503と再試行を返す。
def get_user(self, user_id):
user = cache.get("user.{0}", user_id)
if user is None:
user = db.query("SELECT * FROM users WHERE user_id = {0}", user_id)
if user is not None:
key = "user.{0}".format(user_id)
cache.set(key, json.dumps(user))
return user
自己完結したリクエスト・レスポンスのアプリケーション層プロトコル。中間にLB、キャッシュ、暗号化、圧縮を置きやすい。
順序と欠損なしを保証する接続型プロトコル。信頼性が必要で、時間制約が厳しくない処理に向く。
保証を減らして低レイテンシーを狙う。VoIP、ビデオチャット、ストリーミング、リアルタイムゲーム向き。
| 操作 | RPCスタイル | RESTスタイル |
|---|---|---|
| サインアップ | POST /signup | POST /persons |
| Person読み込み | GET /readPerson?personid=1234 | GET /persons/1234 |
| アイテム更新 | POST /modifyItem | PUT /items/456 |
| アイテム削除 | POST /removeItem | DELETE /items/456 |
| 乗数 | 厳密値 | 目安 |
|---|---|---|
| 2^10 | 1,024 | 1 KB |
| 2^20 | 1,048,576 | 1 MB |
| 2^30 | 1,073,741,824 | 1 GB |
| 2^40 | 1,099,511,627,776 | 1 TB |