10日で覚えるSystem DesignDay 2: スケーラビリティとパフォーマンス

Day 2: スケーラビリティとパフォーマンス

今日学ぶこと

  • 垂直スケーリングと水平スケーリングの違い
  • ロードバランシングのアルゴリズム
  • ステートレスとステートフルなサービス設計
  • CAP定理の理解と適用
  • レイテンシとスループットの関係
  • 可用性とSLAの設計

垂直スケーリング vs 水平スケーリング

システムの処理能力を向上させる方法は2つあります。

flowchart TB
    subgraph Vertical["垂直スケーリング(Scale Up)"]
        V1["小さなサーバー\n4 CPU, 16GB RAM"]
        V2["大きなサーバー\n64 CPU, 256GB RAM"]
    end
    subgraph Horizontal["水平スケーリング(Scale Out)"]
        H1["サーバー 1"]
        H2["サーバー 2"]
        H3["サーバー 3"]
        H4["サーバー N"]
    end
    V1 -->|"CPU・メモリ増強"| V2
    style Vertical fill:#8b5cf6,color:#fff
    style Horizontal fill:#22c55e,color:#fff
比較項目 垂直スケーリング 水平スケーリング
方法 サーバーのスペックを上げる サーバーの台数を増やす
上限 ハードウェアの限界がある 理論上は無限に拡張可能
コスト 高スペックほど指数的に高額 比較的線形にコスト増加
ダウンタイム スペック変更時に必要な場合がある ローリングアップデート可能
複雑さ シンプル データ整合性など課題が多い
障害耐性 SPOF(単一障害点)になる 冗長性が高い
適するケース 初期段階・小規模システム 大規模・高可用性が必要な場合

面接でのポイント: 「まず垂直スケーリングで始め、必要に応じて水平スケーリングに移行する」という段階的アプローチを説明できると良い評価を得られます。


ロードバランシング

ロードバランサーは、複数のサーバーにリクエストを分散する仕組みです。

flowchart LR
    Client["クライアント"] --> LB["ロードバランサー"]
    LB --> S1["サーバー 1"]
    LB --> S2["サーバー 2"]
    LB --> S3["サーバー 3"]
    style LB fill:#3b82f6,color:#fff
    style S1 fill:#22c55e,color:#fff
    style S2 fill:#22c55e,color:#fff
    style S3 fill:#22c55e,color:#fff

ロードバランシングアルゴリズム

アルゴリズム 仕組み メリット デメリット
Round Robin 順番にリクエストを分配 シンプル サーバー性能の差を考慮しない
Weighted Round Robin 重み付きで順番に分配 性能差に対応可能 重みの設定が必要
Least Connections 接続数が最少のサーバーに送る 負荷を均等化 接続数の追跡が必要
IP Hash クライアントIPでサーバーを決定 同一クライアントは同一サーバー 分散が偏る可能性
Consistent Hashing ハッシュリング上で最近接ノードへ サーバー追加/削除の影響が小さい 実装が複雑

Consistent Hashing

Consistent Hashingは、サーバーの追加・削除時にデータの再配置を最小限にする手法です。

flowchart TB
    subgraph Ring["ハッシュリング"]
        direction TB
        N1["ノード A\n(位置: 0°)"]
        N2["ノード B\n(位置: 120°)"]
        N3["ノード C\n(位置: 240°)"]
    end
    K1["Key 1 → ノード B"] --> N2
    K2["Key 2 → ノード C"] --> N3
    K3["Key 3 → ノード A"] --> N1
    style Ring fill:#3b82f6,color:#fff
    style N1 fill:#8b5cf6,color:#fff
    style N2 fill:#22c55e,color:#fff
    style N3 fill:#f59e0b,color:#fff

ノードの追加時、影響を受けるのはリング上の隣接区間のデータのみです。全体の 1/N 程度のデータだけが移動します。


ステートレス vs ステートフル

flowchart TB
    subgraph Stateful["ステートフル"]
        C1["クライアント A"] -->|"常に同じサーバー"| SF1["サーバー 1\nセッション保持"]
        C2["クライアント B"] -->|"常に同じサーバー"| SF2["サーバー 2\nセッション保持"]
    end
    subgraph Stateless["ステートレス"]
        C3["クライアント"] --> LB2["ロードバランサー"]
        LB2 --> SL1["サーバー 1"]
        LB2 --> SL2["サーバー 2"]
        SL1 --> Store["共有ストア\n(Redis等)"]
        SL2 --> Store
    end
    style Stateful fill:#ef4444,color:#fff
    style Stateless fill:#22c55e,color:#fff
比較項目 ステートレス ステートフル
セッション管理 外部ストア(Redis等) サーバー内メモリ
スケーリング 容易 困難(Sticky Session必要)
障害耐性 サーバー障害の影響小 セッション消失のリスク
レイテンシ 外部ストア参照のオーバーヘッド ローカル参照で高速

面接での鉄則: 大規模システムでは常にステートレス設計を推奨しましょう。セッション情報は外部の分散キャッシュ(Redis)に保存します。


CAP定理

分散システムでは、以下の3つの特性のうち同時に2つまでしか保証できません。

flowchart TB
    subgraph CAP["CAP定理"]
        C["Consistency\n一貫性\nすべてのノードが同じデータを返す"]
        A["Availability\n可用性\nすべてのリクエストにレスポンスを返す"]
        P["Partition Tolerance\n分断耐性\nネットワーク分断時も動作する"]
    end
    C --- A
    A --- P
    P --- C
    style CAP fill:#3b82f6,color:#fff
    style C fill:#8b5cf6,color:#fff
    style A fill:#22c55e,color:#fff
    style P fill:#f59e0b,color:#fff

分散システムではネットワーク分断(P)は必ず起きるため、実質的には CPAP の選択になります。

選択 特性 ユースケース
CP 一貫性 + 分断耐性 ZooKeeper, HBase, MongoDB 金融取引、在庫管理
AP 可用性 + 分断耐性 Cassandra, DynamoDB, CouchDB SNS、ショッピングカート

CAP定理の実践的な理解

CAP定理は二者択一ではなく、スペクトラムとして理解するのが正確です。

強い一貫性 ←――――――――――――→ 結果整合性
(CP寄り)                    (AP寄り)

銀行口座 → ショッピングカート → SNSのいいね数 → DNS

レイテンシとスループット

概念 定義 単位
レイテンシ 1リクエストの処理にかかる時間 ms(ミリ秒)
スループット 単位時間あたりの処理量 QPS、RPS、TPS

よく使うレイテンシの目安

操作 レイテンシ
L1キャッシュ参照 0.5 ns
L2キャッシュ参照 7 ns
メインメモリ参照 100 ns
SSD読み取り 150 μs
HDD読み取り 10 ms
同一データセンター内通信 0.5 ms
カリフォルニア→東京 150 ms

面接での使い方: 「ディスクアクセスはメモリの10万倍遅いため、頻繁にアクセスするデータはキャッシュに載せるべきです」のように、設計判断の根拠として使いましょう。

パーセンタイル

レイテンシは平均値ではなくパーセンタイルで測定します。

パーセンタイル 意味 目安
P50(中央値) 50%のリクエストがこの時間以内 通常の体験
P95 95%のリクエストがこの時間以内 ほぼ全てのユーザー体験
P99 99%のリクエストがこの時間以内 SLA目標に使う
P99.9 99.9%のリクエストがこの時間以内 最悪ケースの監視

可用性とSLA

可用性は「ナイン」で表現されます。

可用性 ダウンタイム/年 ダウンタイム/月 用途
99%(2ナイン) 3.65日 7.31時間 開発環境
99.9%(3ナイン) 8.77時間 43.8分 一般的なWebサービス
99.99%(4ナイン) 52.6分 4.38分 ECサイト、SaaS
99.999%(5ナイン) 5.26分 26.3秒 金融、医療

可用性の計算

直列構成:全体の可用性 = 各コンポーネントの可用性の積

Web Server (99.9%) → App Server (99.9%) → DB (99.9%)
全体 = 0.999 × 0.999 × 0.999 = 99.7%

並列構成(冗長化):可用性の向上

1台の可用性: 99.9%
2台並列: 1 - (1 - 0.999)^2 = 99.9999%

まとめ

今日のポイント

トピック キーポイント
スケーリング 垂直は簡単だが限界あり、水平はスケーラブルだが複雑
ロードバランシング 用途に応じてアルゴリズムを選択(面接ではConsistent Hashingが頻出)
ステートレス 大規模システムではステートレス設計が必須
CAP定理 ネットワーク分断は不可避、CPかAPかはユースケース次第
レイテンシ パーセンタイル(P99等)で測定、メモリとディスクの差を意識
可用性 ナインの数が1つ増えると10倍の努力が必要

設計判断のフレームワーク

1. まず垂直スケーリングで対応可能か検討
2. 限界に達したら水平スケーリングへ移行
3. ステートレス設計でスケールアウトを容易に
4. ロードバランサーで負荷を分散
5. CAP定理を意識してデータストアを選択
6. SLA要件に基づいて冗長化レベルを決定

練習問題

基礎レベル

問題: 以下のシナリオで垂直スケーリングと水平スケーリングのどちらが適切か、理由と共に答えてください。

  1. 個人ブログで月間1万PV
  2. ECサイトで年末セール時にトラフィックが10倍
  3. リアルタイム株価表示システム

中級レベル

問題: 可用性99.99%のシステムを設計するために、以下の構成の全体可用性を計算し、目標を達成するためにどのコンポーネントを冗長化すべきか提案してください。

  • Webサーバー: 99.9%(2台構成の場合を計算)
  • アプリケーションサーバー: 99.95%
  • データベース: 99.99%
  • キャッシュ: 99.95%

チャレンジレベル

問題: 「Twitterのようなソーシャルメディアプラットフォームを設計してください」という問題が出されました。以下の点について設計を説明してください。

  • 読み取りと書き込みの比率は100:1
  • DAUは1億人
  • ロードバランシング戦略
  • ステートレス設計のアプローチ
  • CAP定理の観点からの設計判断

参考リンク


次回予告

Day 3: データベース設計とスケーリング では、SQLとNoSQLの使い分け、インデックス設計、レプリケーション、シャーディングなど、データ層の設計について深く学びます。多くのシステム設計問題で核心となるトピックです。