サーバー構成のスケール設計 — 垂直か水平か、最初に決めること

サーバー構成でスケールに行き詰まるプロジェクトの多くは、初期設計の段階で「どちらの方向に拡張するか」を決めていない。垂直スケールか水平スケールかという選択は、アプリケーションの状態管理・データ構造・デプロイ方式と密接に絡み合うため、後から方向転換するには大規模な手術が必要になる。本記事では、スケール設計の構造的な落とし穴を先に明らかにしたうえで、最初の構成で固定すべき判断軸と、過剰設計を避けるための基準を整理する。

後からスケールできない構成になる構造的な原因

「単一サーバー前提」の設計が埋め込まれる仕組み

初期構築では、要件が小さいほどシンプルな構成が選ばれる。Webサーバー・アプリケーションサーバー・データベースを1台に集約する構成は初期コストを抑えられる一方で、設計の前提が「単一サーバー上ですべてが動く」という暗黙のルールに縛られる。ファイルのアップロード先がローカルディスクになる、セッションがメモリに書き込まれる、設定値がファイルに直書きされる。こうした判断の一つひとつは合理的に見えるが、2台目を追加しようとすると、それぞれが構成の障壁として立ちはだかる。

現場では「1台で運用してきたが、アクセスが3倍になった段階で初めてスケールを考えた」という話をよく聞く。そのとき既に、アプリケーションコードはローカルパスに依存し、セッションはサーバー固有のメモリに紐付いていることが多い。スケールの失敗は技術的限界ではなく、最初の設計前提が変更コストを積み上げ続けた結果だ。

拡張のたびに手術が必要になる構成の特徴

スケール時に大きな改修が必要になる構成には共通した特徴がある。第一に、プロセス間の通信がIPアドレスやホスト名のハードコードに依存している。第二に、アプリケーションがセッションやキャッシュをプロセス内メモリに保持している。第三に、デプロイが「そのサーバーに直接接続して操作する」ことを前提にしている。これらが重なると、サーバーを追加するたびに設定ファイルの書き換え・データの移行・デプロイスクリプトの改修が同時に発生する。

10台規模になってから気づくと、移行のダウンタイムが数時間に及ぶケースも出てくる。最初から「どのサーバーが担当しても同じ結果になる」という無状態設計を意識するだけで、こうした積み上がりを防げる。

スケール失敗の原因は技術ではなく前提にある

構築担当者がスケールを設計するとき、多くの場合は「将来的にはクラスタ化したい」という意図を持っている。にもかかわらず失敗するのは、その意図が設計の前提として明文化されていないからだ。チーム内で「スケールアウトを前提に作る」という共通認識がなければ、個別の判断が積み重なってスケール不可能な構成が完成する。設計フェーズで「垂直か水平か」を明示的に決定し、その決定に基づいてアーキテクチャの制約を文書化しておく必要がある。

垂直スケール・水平スケールの向き不向き

垂直スケールが力を発揮するユースケース

垂直スケール(スケールアップ)は、サーバーのCPU・メモリ・ストレージを増強することで処理能力を高める方法だ。アプリケーションの変更が不要で、即効性が高い。状態の分離が難しいアプリケーション、大量のメモリを前提とした処理(インメモリデータベース・大規模バッチ処理など)、シングルスレッドで動作するレガシーシステムでは、垂直スケールが現実的な選択肢になる。

ピーク時のリクエスト数が予測可能で、最大リソースを見積もれる場合も垂直スケールのほうが管理コストを低く抑えられる。仮想マシンであればリソース変更がダウンタイム数分程度で完了するケースも多く、「スケールのために構成を変えたくない」という判断は一定の合理性を持つ。

水平スケールが本領を発揮する条件

水平スケール(スケールアウト)は、同等の役割を持つサーバーを複数台並べてロードバランサで分散する方式だ。単一サーバーのリソース上限を超えられる点、特定のサーバーに障害が起きても全体が止まらない点が強みだ。ただし前提条件がある。リクエストの処理がどのサーバーで行われても同じ結果になる無状態設計が実現していること、セッション・ファイル・キャッシュが外部に分離されていることだ。

ECサイトや外部公開APIのように、アクセス数が数倍〜数十倍に変動する可能性があるシステムでは、水平スケールの設計を初期から組み込むことでピーク対応コストを大幅に下げられる。日次100万リクエストを超えるような規模では、垂直スケールだけでは費用対効果が逆転する傾向がある。

混在させてよい場合とそうでない場合

実際の構成では、レイヤーごとに異なるスケール戦略を取ることが多い。Webサーバー・アプリケーションサーバーは水平スケール、データベースは垂直スケールという組み合わせは現場でよく見られ、設計として成立する。問題が生じるのは「一部のレイヤーだけ水平スケール対応にした」ことでボトルネックが移動し、データベースへの接続数が急増するケースだ。スケール設計は一つのレイヤーだけを考えるのではなく、全体のボトルネックがどこに移るかを先読みして判断する必要がある。

状態を持つ構成がスケールを妨げる仕組み

セッションとローカルストレージの罠

水平スケールを妨げる最大の障壁は「状態の局所化」だ。セッション情報をアプリケーションサーバーのメモリに保持していると、同じユーザーのリクエストを常に同じサーバーに送るスティッキーセッション(固定セッション)が必要になる。これはロードバランサの設定を複雑にし、特定サーバーへの負荷集中を生む。そのサーバーが障害を起こすと、紐付いていたユーザーは全員ログアウトになる。

同様に、ファイルアップロードの保存先がサーバーのローカルディスクの場合、別のサーバーからそのファイルにアクセスできない。2台目のサーバーを追加した瞬間、アップロードしたファイルが「どのサーバーに繋がるかで見えたり見えなかったり」という不整合が発生する。構築を担当したエンジニアが2台目追加の直後にこの問題に直面するケースは少なくない。

状態の分離が水平スケールの前提条件になる理由

セッションをRedisなどの外部キャッシュストアに移す、ファイルをオブジェクトストレージに保存する、設定をコンフィグサーバーや環境変数から読み込む。これらの「状態の外出し」は水平スケールの前提条件だ。アプリケーションが「どのサーバーで動いているかを意識しない」設計になっていれば、サーバーの追加と削除はインフラ側だけで完結する。

この分離を最初から設計しておくことと、後から移行することでは、工数の差が数倍に開く。後者の場合、アプリケーションコードのリファクタリング・データ移行・テスト工程が加わり、本番環境への適用には慎重なカットオーバー計画も必要になる。初期設計の段階で「状態はどこに置くか」を決定することが、スケール設計の核心だ。

データベース層のボトルネックを見落とす落とし穴

アプリケーション層を水平スケールに対応させたとしても、データベース層が単一サーバーのままでは、接続数の増加がボトルネックになる。アプリケーションサーバーを5台から10台に増やした途端、データベースへの同時接続数が倍増してクエリのレイテンシが急上昇するという現象は珍しくない。コネクションプールの設計と最大接続数の見積もりは、水平スケールの計画と同時に行う必要がある。

読み取りが多いシステムでは読み取り専用レプリカを分離する選択肢があるが、これも「どのクエリをどのエンドポイントに向けるか」という設計判断が先に必要だ。スケール設計はアプリケーション層だけでは完結しない。

スケールを見越して最初に固定すべき設計

ロードバランサの位置とDNS戦略

水平スケールを想定する場合、最初からロードバランサを構成の入口に置くことが合理的だ。最初はバックエンドが1台だけでも、ロードバランサ経由でアクセスさせる構成にしておけば、サーバーを追加するときにクライアント側のDNS設定を変更せずに済む。DNSがロードバランサのIPを指していれば、バックエンドの台数変更は透過的に完結する。

一方、最初からサーバーのIPを直接DNSに登録してしまうと、水平スケールへの移行時にDNS変更が伴い、TTLの問題で切り替えに時間がかかる。「将来的にはロードバランサを入れる」という計画があるなら、初日からロードバランサを挟む設計が正解だ。この判断は後からでは遅く、移行コストが一気に膨らむポイントの一つになる。

設定・秘密情報の外出しを最初に徹底する

データベースの接続文字列・APIキー・証明書パスといった環境依存の値がアプリケーションコードや設定ファイルにハードコードされていると、サーバーを複数台に増やすたびに同じ値を各サーバーへ配布する作業が発生する。これは管理コストの増大だけでなく、更新漏れによる障害リスクを生む。

環境変数やシークレット管理の仕組みを使って設定を外出しする設計を最初から採用しておけば、サーバー台数が5台から20台に増えても設定の配布は一元化できる。この設計は水平スケールを前提とするかどうかにかかわらず、本番環境の安全性と保守性を高める判断でもある。

ヘルスチェックとデプロイ自動化の設計

水平スケールの構成では、ロードバランサがバックエンドサーバーの死活監視を行うヘルスチェックが必須になる。ヘルスチェックのエンドポイントとその判定基準を最初に設計しておかないと、障害時にトラフィックが落ちているサーバーにも流れ続けるという問題が起きる。またデプロイは、全サーバーへの一括反映ではなく1台ずつ順番に更新するローリングアップデートを想定した自動化が必要だ。

手作業でのデプロイを前提にした構成では、サーバー台数が増えるにつれて作業時間と失敗リスクが比例して積み上がる。デプロイの自動化をどのレイヤーで担うかの設計はスケール設計と同時に決定すべき事項だ。手を動かす詳細な実装はセミナー・実地トレーニングの領域だが、「何をどこで自動化するか」という設計判断はここで固めておく。

「まだ要らない冗長化」を避ける判断

過剰設計のコストと複雑さ

スケールを意識しすぎると、実際の利用規模に対して過剰な複雑さを持った構成ができあがる。日次リクエスト数が数万件程度の内部システムに、マルチAZ構成のロードバランサ・コンテナオーケストレーション・複数リージョンのオブジェクトストレージを適用してしまうと、運用の複雑さが増して障害時の対応難度が上がる。過剰な冗長化は「安全」ではなく「複雑さによるリスク増」になることがある。

現場で多いのは「将来的に大きくなるかもしれないから」という理由で、現在の規模の10倍を見越した構成を入れてしまうケースだ。設計の複雑さは構築工数だけでなく、日々の運用コストと障害復旧のコストにも直結する。

どこまでを最初の構成と決めるか

スケール設計の判断軸は「今の規模で耐えられるか」ではなく「どのくらいの規模まで今の構成で耐えられ、どの時点で構成を変えるか」だ。3倍の負荷まで垂直スケールで対応し、それ以降は水平スケールに移行するという計画を最初に持っていれば、その移行コストを減らす設計上の選択だけを先行して行えばよい。全部を最初から作り込む必要はない。

具体的には、状態の外出し・ロードバランサの組み込み・デプロイ自動化は移行コストが高いため最初から実装する価値がある。一方、冗長化されたロードバランサ・複数台のデータベースレプリカ・マルチAZ構成は、実際に必要になる規模が見えてから追加すれば十分なことが多い。

段階的拡張の設計と判断軸

「段階的に拡張できる設計」と「最初から大規模構成を稼働させる」は別物だ。前者は、拡張の際に最小限の変更で対応できるよう設計上の制約を取り除いておくことを意味する。後者は、現在必要のない機能・構成を実際に動かし続けることを意味する。この違いを設計段階で意識することが、過剰投資を避けながら将来の拡張性を確保する鍵になる。

判断の目安として、拡張時に「アプリケーションコードの変更が必要かどうか」を基準にするとよい。コードを変えずにインフラ側の追加だけで対応できる設計なら、その拡張は段階的といえる。コードの変更が必要になるなら、それは初期設計で対処すべき問題が残っているサインだ。

比較表: コスト・複雑さ・限界点のトレードオフ

垂直スケールと水平スケールは、それぞれの構成が有利になる条件が明確に異なる。以下の比較表では、初期構成コスト・運用複雑さ・スケールの限界・向いているユースケースを軸に整理した。どちらが「正解」かではなく、システムの特性と成長予測に基づいてどちらを選ぶかが設計判断の核心だ。

比較軸 垂直スケール(スケールアップ) 水平スケール(スケールアウト)
初期構成コスト 低い(既存構成をそのまま拡張) 中〜高い(ロードバランサ・外部セッション管理等が必要)
アプリケーションへの影響 ほぼなし 無状態設計への移行が必要(コード変更を伴うことが多い)
運用の複雑さ 低い(サーバー台数が増えない) 中〜高い(複数台の監視・ログ集約・デプロイ自動化が必要)
スケールの上限 ハードウェアの最大スペックで頭打ち 理論上は台数分だけ拡張可能(ただし設計とボトルネック次第)
可用性・冗長性 単一障害点が残る 複数台構成により冗長性を確保できる
大規模時のコスト効率 低い(高スペック機は割高になりやすい) 高い(標準スペック機の組み合わせで対応可能)
向いているユースケース 状態管理が複雑・レガシー・アクセスが安定している系 無状態API・急成長が予測されるサービス・クラウドネイティブ構成

スケール設計チェックリスト

初期設計フェーズで以下の項目を確認することで、後からスケールできない構成になるリスクを大幅に低減できる。すべてに対応する必要はなく、選択したスケール戦略に応じて該当する項目を適用する。

  1. スケールの方向(垂直・水平・混在)を明示的に決定し、チーム内で合意しているか
  2. セッション情報をアプリケーションサーバーのメモリに保持していないか(水平スケール前提の場合は外部ストアへ分離)
  3. ファイル・メディアの保存先がローカルディスクに依存していないか
  4. データベース接続先・APIキー・設定値がハードコードされておらず、外部から注入できる設計になっているか
  5. ロードバランサをエントリポイントとして最初から組み込んでいるか(水平スケール前提の場合)
  6. ヘルスチェックエンドポイントの設計と判定基準が定義されているか
  7. デプロイが自動化されており、サーバー台数が増えても作業量が比例増加しない設計になっているか
  8. データベースへの同時接続数の上限と、アプリケーションサーバー増加時の接続数増加を試算しているか
  9. どの規模・指標(リクエスト数・CPU使用率・台数など)を超えたら構成を見直すかの閾値を定めているか
  10. 現在の規模で不要な冗長化・過剰構成が含まれていないかを確認したか

▶ 手を動かして本番まで到達する

その設計判断を、RHEL10の本番環境で手を動かして固めませんか

ここまでの設計判断は、読めば腹に落ちます。ですが「自分の手で本番まで通しきる自信」は、それとは別の話になります。

最大6名の少人数で、構築実務者の到達点まで引き上げます。座学で終わらせず、本番相当の環境で判断を検証する2日間です。

スケール設計を本番で検証する上級講座へ →

Linuxセミナー上級編(RHEL10)|最大6名の少人数ハンズオン