株式会社ジオデータ開発 ロゴ
株式会社ジオデータ開発GEO DATA DEVELOPMENT Inc.
高可用性クラスタフェールオーバーセッショントランザクションロードバランサーNext.jsSupabase

SYSTEM ARCHITECTURE / AVAILABILITY / FAILOVER

Webサーバーの冗長化とは? セッション共有・フェールオーバー・DBトランザクションを図解で理解する

公開日:2026-10-14

Next.jsとSupabaseを使って予約アプリを作ったとします。予約確定の直前にWebサーバーが止まったら、別のサーバーへ切り替えるだけで元どおりになるでしょうか。答えは「どの状態をどこに保存しているか」によって変わります。今回は、一つの予約操作を追いながら、可用性とデータの整合性を丁寧に整理します。

この記事の学習ルート

身近な予約アプリ → Webの構成 → セッションとは → 冗長化 → フェールオーバー → セッション共有 → DBトランザクション → Supabaseでの設計 → 可用性指標 → 操作ラボ

01|予約ボタンを押した瞬間にサーバーが止まったら

例えば、予約サイトで日時と人数を選び、「予約する」を押す場面を考えてください。画面はNext.js、認証はSupabase Auth、予約データはPostgresという構成が一例です。押した直後に処理担当のサーバーが停止すると、通信が失敗したり、結果が分からなくなったりします。

身近な予約アプリを例にした処理の流れ

ブラウザ

予約日と人数を入力

Webの処理

ユーザーと在庫を確認

データベース

予約レコードを確定

完了画面

予約番号を表示

Webサーバーが停止しても、すでにDBで確定した予約まで自動的に取り消されるわけではありません。どの時点で失敗したかが重要です。

02|まずWebサーバーとデータベースの役割を分けます

Webアプリは一つの箱に見えますが、画面を提供する部分、リクエストを処理する部分、状態を保存する部分に分かれています。これらを分けておくと、障害時に何が残り、何が失われるかを考えやすくなります。

共有状態を持つWebクラスタの概念図
ブラウザ予約ボタンを押しますロードバランサー利用可能なサーバーへ振り分けますWebサーバー A障害で停止する場合がありますWebサーバー B次の要求を引き受けます共有セッションログイン・操作の状態Postgres予約・在庫などの確定データ図は理解用の例です。Supabaseがこの構成をそのまま提供するという意味ではありません。
技術・状態何を守るか障害時のポイント
ブラウザ入力フォームやCookieを持ちます再読み込みで消える入力がある一方、Cookieは残る場合があります。
アプリケーションサーバー処理を実行し、一時的な状態を保持しますプロセス内メモリにしかない情報は停止すると失われます。
セッションストア複数リクエスト間の利用者状態を保持しますサーバー外へ共有すれば別インスタンスから参照できます。
データベース予約などの確定情報を永続化しますDBトランザクションの境界が確定・取消しを決めます。

03|「ログイン中」はどこに保存されていますか

HTTP(Hypertext Transfer Protocol)は、基本的に個々のリクエストを独立して扱います。ユーザーがログインしているか、買い物カゴに何を入れたかを扱うために、Cookieやトークン、サーバー側セッションなどの仕組みを使います。

ログイン情報と予約情報は同じものではありません

Cookie/トークン

ユーザーを識別・認証

セッション状態

入力途中の手順やカート

DBレコード

確定した予約・決済情報

JWTのような署名付きトークンで状態を検証できる方式もあります。すべての構成で共有セッションストアが必要なわけではありません。

サーバーAだけのメモリに「予約の第2画面まで進んだ」という情報を持っていると、次のリクエストがサーバーBへ届いても、Bはその情報を知りません。これがセッションを共有しない構成の問題です。

04|可用性と信頼性は何を意味しますか

可用性(Availability)は必要なときにサービスを使える度合いです。信頼性(Reliability)は一定条件のもとで正しく動作し続ける性質を指します。Webサービスでは、故障しても別の装置へ切り替えられるように設計することが重要です。

技術・状態何を守るか障害時のポイント
冗長化(Redundancy)同じ機能を担う複数の資源を用意します1台停止しても別の系が対応できます。
フェールオーバー(Failover)障害を検知し、予備系へ切り替えます切替えには検知・再接続の時間がかかる場合があります。
フェールバック(Failback)復旧した元の系へ戻す処理です戻し方も運用設計の対象です。
単一障害点(SPOF)ここが壊れると全体が止まる箇所ですロードバランサーやDB自身にも注意が必要です。

05|コールド・ウォーム・ホットスタンバイの違い

「予備がある」だけでは切替え速度を判断できません。コールドスタンバイは予備機の起動や初期化が必要になりやすく、ウォームスタンバイは一部準備済み、ホットスタンバイはすぐ引き継げる状態を維持する設計です。ただし用語の厳密な運用は製品ごとに異なります。

障害発生後の流れを時間軸で比較します
通常運転
Aで障害
切替え中
復旧後
コールド
提供中
停止
停止
提供中
ホット/クラスタ
提供中
瞬断の可能性
提供中
提供中

時間の長さを定量化した図ではありません。ホット構成でも無停止が必ず保証されるわけではありません。

技術・状態何を守るか障害時のポイント
コールドスタンバイ予備を起動・設定してからサービスを引き継ぎます障害後に待ち時間が発生します。
ウォームスタンバイ一部を起動・同期して待機しますホットより準備が少なく切替え時間が長い場合があります。
ホットスタンバイすぐに処理を受けられるよう準備します同期状態や通信切替えにより瞬断する場合があります。
アクティブ・アクティブ複数系が平常時から要求を処理します状態共有と負荷分散が重要です。

06|ロードバランサーは何をするのですか

LB(Load Balancer、ロードバランサー)は、正常なサーバーへリクエストを振り分けます。ヘルスチェックで故障を検出し、送信先から外す仕組みを組み合わせます。ただし、すでに実行中の処理をそのまま移動させるわけではありません。

Aが停止したあと、次のリクエストをBへ送ります

利用者

予約画面を操作

LB

Aの障害を検知

WebサーバーB

新しい要求を処理

Aで実行中だった要求は失敗した可能性があります。新しい要求をBで受け付けられることと、途中処理の継続は別問題です。

07|セッションを共有すると何が変わりますか

AとBの両方が共通のセッションストアへアクセスできれば、「入力を何段階進めたか」「一時的な選択内容」などをBが参照できます。セッション共有は、利用者が別サーバーへ移った後の操作の継続を助けます。

共有ストアを介して状態を引き継ぎます

WebサーバーA

途中状態を保存

共有ストア

session_id → 選択内容

WebサーバーB

同じ状態を読み出す

08|セッション維持とDBトランザクションは別物です

DBトランザクション(Transaction)は、予約レコードの書込みなど複数のDB操作を、一つの整合した処理単位にまとめます。原子性(Atomicity)により、COMMIT前に異常終了した場合は変更がロールバックされるのが基本です。

予約を確定する処理の例

BEGIN

処理単位を開始

在庫を確認

空き枠をロック等で保護

予約を登録

必要なDB更新

COMMIT

まとめて確定

技術・状態何を守るか障害時のポイント
ログインセッション利用者が誰か、操作の文脈サーバー外で保持すれば別のWebサーバーから利用できます。
DBトランザクションDB更新を整合的に確定する単位途中で接続が失われれば、通常はロールバックされます。
HTTPリクエスト利用者が送った1回の通信接続切断後の再送と重複処理に注意が必要です。

09|Supabaseを使った予約アプリならどう設計しますか

Supabase Authでは認証状態を扱い、Postgresに予約データを保存できます。画面表示を担当するWebサーバーが入れ替わっても予約情報を参照できるよう、確定情報を特定サーバーのメモリだけに置かないのが大切です。

学習用の責務分離イメージ(擬似コード)
// ブラウザ: 認証済みのユーザーとして予約要求を送信します
POST /api/reservations
{
  "timeSlot": "2026-10-20T18:00:00+09:00",
  "requestId": "reservation-attempt-001"
}

// Web API側の責務(設計イメージ)
// 1. Supabase Authでユーザーを検証します。
// 2. DBで requestId の重複を確認・制約で保護します。
// 3. 在庫確認と予約登録をDBの単一トランザクションで扱います。
// 4. 既に成功済みの requestId なら同じ結果を返します。

複数のDB操作を一つのトランザクションにまとめたい場合は、Postgresの関数などDB側で処理を完結させる設計が考えられます。上記は設計方針を示した擬似コードで、そのまま動くSupabase API実装ではありません。

10|二重予約を防ぐには冪等性が重要です

処理完了後、応答だけが届かないことがあります。利用者がもう一度「予約」を押すと、同じ処理が二重に実行されるおそれがあります。そこで冪等性(Idempotency、べきとうせい)を使います。同じリクエストIDの再送で結果が二重に増えないようにする設計です。

応答だけが失われた場合

予約がDBで確定

1件作成されました

HTTP応答が途切れる

画面では結果が不明

同じIDで再送

重複登録せず既存の結果を返します

実装では一意制約、原子的なINSERT、適切なトランザクション境界、要求IDの保存などを組み合わせます。「同じデータのSELECT結果になる」だけでは二重登録の防止にはなりません。

11|フェールオーバーとフェールソフト・フォールトトレランス

関連する用語も整理しておきます。フェールオーバーは系の切替えです。フォールトトレランス(Fault Tolerance、耐障害性)は障害下でも処理を続けられる性質を表します。フェールソフト(Fail-soft)は機能や性能を落としてもサービスの一部を提供し続ける考え方です。

技術・状態何を守るか障害時のポイント
フェールオーバー障害時に別の系へ切り替えます切替えの瞬間に通信が失敗する場合があります。
フェールソフト機能を縮小しても稼働を続けます予約は止めても一覧閲覧だけ維持する例があります。
フェールセーフ故障時に安全側へ制御します決済の確定を保留するなど、不整合を避ける設計です。
フォールトトレランス障害の発生を見越した継続能力です多重化・検出・復旧の仕組みを組み合わせます。

12|可用性・MTBF・MTTR・RTO・RPOを区別します

可用性を数値で考える場合は、稼働時間と修復時間が重要です。MTBF(Mean Time Between Failures、平均故障間隔)、MTTR(Mean Time To Repair、平均修復時間)を使う単純なモデルでは、稼働率 A は次の式で表せます。

単純な修復可能システムの稼働率モデル
A = MTBF / (MTBF + MTTR)
例:MTBF = 990時間、MTTR = 10時間
A = 990 / 1000 = 0.99(99%)

RTO(Recovery Time Objective、目標復旧時間)は停止から復旧するまでの目標、RPO(Recovery Point Objective、目標復旧時点)は障害前のどこまでデータを復元できればよいかの目標です。可用性が高いことと、失われるデータ量が少ないことは別々に考えます。

技術・状態何を守るか障害時のポイント
MTBF平均故障間隔長いほど障害間隔が長い傾向です。
MTTR平均修復時間短いほど復旧が速い傾向です。
RTO復旧に許される目標時間例:15分以内に業務を再開します。
RPO許容できるデータ損失の目標時点例:直前5分までのデータを復元します。

13|アプリの冗長化だけでは不十分な理由

Webサーバーを2台にしても、両方が同じ単一DBへ依存し、そのDBが停止すれば予約処理は止まります。LB、セッションストア、DB、ネットワーク、認証基盤など、複数の依存先を考えなければなりません。

システム全体としての単一障害点を探します

ロードバランサー

入口が止まると到達できません

Webサーバー群

複数台でも共有状態が必要です

データベース

永続データと整合性を守ります

14|ラボ:サーバーAを停止して違いを確かめましょう

次のシミュレーターでは「コールドスタンバイ」「クラスタ・セッション非共有」「クラスタ・セッション共有」を切り替えられます。ログイン・入力・予約要求・障害を順番に試し、状態がどこに残るのか観察してください。DB側はWebサーバーと独立した学習モデルです。

INTERACTIVE LAB

予約サーバーの障害と状態の引継ぎ

ステップを進めると、サーバー停止・セッション共有・DBの確定状態がそれぞれどう変化するか確認できます。データベースと共有ストアが正常な単純化モデルです。

AとBが共通のセッションストアを参照します。Aが止まっても入力途中の状態を読み直せます。

サーバーA

稼働中

サーバーB

待機中

入力した予約日時

未入力

共有ストア:保存なし

データベースの予約

確定 0 件

処理中:なし

二重予約防止の動きを確認します

ここではIDの重複をDB側で原子的に防止できるものと仮定します。実際には一意制約などが必要です。

イベントログ

  1. 初期状態です。サーバーAで入力を始め、次に障害を発生させてください。

現在のステップ:0。障害検知やDBの整合性を学ぶためのモデルであり、実サービスの可用性やSupabaseの内部動作をシミュレートするものではありません。

15|まとめ:守りたい状態を分けて設計します

複数サーバーを用意することは、可用性向上の出発点です。しかし、セッションがAのメモリにしかなければ、Bへ切り替えたあとに操作状態を失います。さらに、共有セッションがあってもDBトランザクションの自動継続まで保証されるわけではありません。

Webの構成、利用者状態、DBでの確定処理、再送時の冪等性を別々に設計することが、実際のシステムを堅牢にする近道です。