システムデザイン レッスン1

スケーラビリティの基本

アクセス増加に耐えるためのスケールアップとスケールアウトの違いと、システム設計における考慮点を学ぶ

スケーラビリティとは何か

スケーラビリティとは、 利用者数やデータ量、リクエスト数が増加しても、性能を維持したままシステムを拡張できる性質のことです。

拡張の方向には大きく分けて2つのアプローチがあります。それぞれ得意なことと限界が異なるため、 両者の違いを理解することがシステムデザインの出発点になります。

スケールアップとスケールアウト

Scale Up (垂直スケーリング)
+-------------------+       +-----------------------+
|   Server (small)  |  -->  |   Server (bigger CPU,  |
|   CPU 2 / RAM 4GB |       |   more RAM, more disk) |
+-------------------+       +-----------------------+

Scale Out (水平スケーリング)
+-------------------+       +--------+  +--------+  +--------+
|   Server (1台)     |  -->  | Server |  | Server |  | Server |
+-------------------+       +--------+  +--------+  +--------+
                              (同じ性能のサーバーを複数台並べる)

スケールアップ(垂直)

  • • 既存の1台の性能(CPU/メモリ)を増強する
  • • アプリケーションの変更なしに対応できることが多い
  • • ハードウェアの上限・コストの急増でいずれ頭打ちになる
  • • 単一障害点(SPOF)が残る

スケールアウト(水平)

  • • 同じ役割のサーバーを複数台に増やして負荷を分散する
  • • 理論上、台数を増やす限りスケールし続けられる
  • • ロードバランサーやステートレス設計など前提となる工夫が必要
  • • 1台が落ちても他が処理を継続でき、可用性も高めやすい

ボトルネックの見つけ方

スケーリングを検討する前に、まず「何が限界を迎えているのか」を計測することが重要です。 CPU・メモリ・ディスクI/O・ネットワーク帯域・データベースの接続数など、限界の現れ方はシステムごとに異なります。

例えば、アプリケーションサーバーをいくら水平にスケールしても、背後のデータベースが1台のままでは データベースが先に限界を迎え、全体の性能は頭打ちになります。ボトルネックはシステム全体を通して 最も弱い箇所に現れるため、部分的な増強だけでは解決しないことがあります。

ステートレス設計の重要性

水平スケーリングを機能させるには、アプリケーションサーバーが「状態を持たない(ステートレス)」ことが前提になります。

// NG: サーバーのメモリにセッション情報を保持(ステートフル)
function login(request):
    inMemorySessionStore[request.userId] = sessionData
    // このサーバー以外にリクエストが振られると情報が失われる

// OK: セッション情報を外部の共有ストアに保持(ステートレス)
function login(request):
    sharedSessionStore.save(request.userId, sessionData)
    // どのサーバーインスタンスがリクエストを受けても同じ結果になる

セッションのような状態は、Redisなどの共有ストアやクライアント側のトークンに持たせることで、 ロードバランサーが自由にどのインスタンスにでもリクエストを振り分けられるようになります。

ポイント

  • スケールアップは1台の性能増強、スケールアウトは台数を増やす方式で、性質もコストも異なる
  • ボトルネックはシステムごとに現れる場所が違うため、推測ではなく計測して特定する
  • 水平スケーリングを機能させるには、サーバーをステートレスに保つ設計が前提になる

確認クイズ

1 / 3

スケールアップ(垂直スケーリング)の限界として適切なものはどれか?