高可用性と災害復旧
はじめに
システムが1分間ダウンすると、数十万の損失につながる可能性があります。 高可用性(High Availability)とは、ハードウェア障害、ソフトウェアのバグ、ネットワーク問題などの異常事態に直面しても、システムが継続的にサービスを提供できる能力のことです。災害復旧(Disaster Recovery)は、より大規模な災害発生時にシステムがサービスを復旧できる能力を指します。
この記事で何を学べるのか?
この章を読み終えると、以下のことが身につきます:
- 可用性の指標:「いくつ9」の意味と対応するダウンタイムを理解する
- フェイルオーバー:アクティブ・スタンバイ、アクティブ・アクティブ、マルチアクティブなどの高可用アーキテクチャを習得する
- 災害復旧戦略:RPOとRTOの概念と設計手法を理解する
- 障害検知:ハートビート、プローブ、サーキットブレーカーなどの障害発見メカニズムを理解する
- カオスエンジニアリング:能動的に障害を注入してシステムのレジリエンスを検証する方法を知る
| 章 | 内容 | 核心概念 |
|---|---|---|
| 第1章 | 可用性の指標 | SLA、いくつ9、ダウンタイム |
| 第2章 | フェイルオーバーアーキテクチャ | アクティブ・スタンバイ、アクティブ・アクティブ、マルチAZ、マルチリージョン・アクティブ・アクティブ |
| 第3章 | 災害復旧設計 | RPO、RTO、バックアップ戦略 |
| 第4章 | 障害検知と復旧 | ハートビート、サーキットブレーカー、オートスケーリング |
| 第5章 | カオスエンジニアリング | 障害注入、レジリエンス検証 |
1. 可用性の指標:「いくつ9」が意味するもの
可用性は通常「いくつ9」で表されます。計算式は以下の通りです:
可用性 = 稼働時間 / 総時間 × 100%
例えば、1ヶ月(30日 = 43200分)の間に43分間ダウンした場合、可用性は (43200 - 43) / 43200 ≒ 99.9% になります。9が1つ増えるごとに許容されるダウンタイムが1桁減り、実現の難易度とコストも指数関数的に増加します。
| 可用性レベル | パーセンテージ | 月間許容ダウンタイム | 年間許容ダウンタイム | 典型的な要件 |
|---|---|---|---|---|
| 2つの9 | 99% | 7.3時間 | 3.65日 | 社内ツール |
| 3つの9 | 99.9% | 43分 | 8.76時間 | 一般的な業務システム |
| 4つの9 | 99.99% | 4.3分 | 52.6分 | EC、SaaS |
| 5つの9 | 99.999% | 26秒 | 5.26分 | 金融、決済 |
SLAとは?
SLA(Service Level Agreement、サービス水準合意) は、サービス提供者と顧客の間の正式な約束です。例えばAWS S3は99.99%の可用性を約束しており、達成できなかった場合は比例して返金します。SLAは単なる技術指標ではなく、ビジネス契約です。SLA違反は金銭的損失を意味します。
3つの9から4つの9への壁
3つの9(99.9%)は月に43分間のダウンタイムを許容します。デプロイで問題が起き、ロールバックすればそれで使い切ってしまいます。 4つの9(99.99%)は月に4分間しかダウンタイムを許容しません。これには自動フェイルオーバー、ローリングデプロイ、ヘルスチェックなど、完全な高可用基盤が必要です。
2. フェイルオーバーアーキテクチャ
フェイルオーバー(Failover)は高可用性の中核メカニズムです。プライマリノードが障害を起こした際、自動的にバックアップノードに切り替えてサービスを継続します。
アクティブ・スタンバイ方式(Active-Standby)
最も一般的な高可用アーキテクチャです。プライマリノードがすべてのリクエストを処理し、セカンダリノードはリアルタイムでデータを同期しますが、リクエストは処理しません。プライマリノードが障害を起こした際、セカンダリノードが自動的に引き継ぎます。
正常状態:
クライアント → プライマリノード(リクエストを処理)
セカンダリノード(データを同期、待機中)
フェイルオーバー:
クライアント → セカンダリノード(新しいプライマリとして引き継ぎ)
元プライマリノード(障害、復旧待ち)重要な問題はスプリットブレイン(Split Brain)です。ネットワーク分断が発生すると、プライマリとセカンダリの両方が相手が落ちたと判断し、同時にサービスを提供してデータの不整合を引き起こします。解決策はクォーラム(Quorum)の導入です。少なくとも3つのノードで投票し、どちらがプライマリかを決定します。
マルチAZ(Multi-AZ)
同じリージョンの複数のデータセンター(アベイラビリティゾーン)にサービスをデプロイします。単一データセンターの停電やネットワーク断が全体のサービスに影響しません。クラウドプロバイダーのAZ間は通常、低遅延の専用線で接続されています(< 2ms)。
マルチリージョン・アクティブ・アクティブ(Multi-Region Active-Active)
異なる都市、さらには異なる国に完全なサービスレプリカをデプロイし、各拠点が独立してリクエストを処理できます。これは最高レベルの高可用アーキテクチャですが、最も複雑でもあります。中核的な課題はリージョン間のデータ同期の遅延と一貫性の問題です。
| アーキテクチャ | 可用性レベル | コスト | 複雑さ | 適用シナリオ |
|---|---|---|---|---|
| 単一マシン | 99%~99.9% | 低い | 低い | 開発テスト、社内ツール |
| アクティブ・スタンバイ | 99.9%~99.99% | 中程度 | 中程度 | 中小規模の業務システム |
| マルチAZ | 99.99% | 高い | 高い | EC、SaaSプラットフォーム |
| マルチリージョン・アクティブ・アクティブ | 99.999% | 極めて高い | 極めて高い | 金融、大手インターネット企業 |
3. 災害復旧設計:RPOとRTO
災害復旧設計は2つのコア指標を軸に展開されます:
| 指標 | フルネーム | 意味 | 例 |
|---|---|---|---|
| RPO | Recovery Point Objective | どれくらいのデータ損失を許容できるか | RPO=0はいかなるデータ損失も許容しない |
| RTO | Recovery Time Objective | どれくらいのダウンタイムを許容できるか | RTO=5分は5分以内の復旧が必要 |
バックアップ戦略とRPOの関係
| バックアップ方式 | RPO | コスト | 説明 |
|---|---|---|---|
| 毎日のフルバックアップ | 24時間 | 低い | 最大1日分のデータ損失の可能性 |
| リアルタイム増分バックアップ | 分単位 | 中程度 | binlog/WALによる継続同期 |
| 同期レプリケーション | 0 | 高い | 書き込み時にレプリカの確認を待つ必要がある |
すべてのデータにRPO=0が必要なわけではない
ユーザーのアバターが失われても再アップロードできます(RPO=24時間で十分)。しかし、支払い記録は1件も失ってはいけません(RPO=0が必要)。データのビジネス価値に応じてバックアップ戦略を決定し、一律に同じ基準を適用しないようにしましょう。
4. 障害検知と復旧
4.1 障害検知メカニズム
| メカニズム | 原理 | 検知速度 | 適用シナリオ |
|---|---|---|---|
| ハートビート検知 | 定期的にハートビートパケットを送信し、タイムアウトで障害と判定 | 秒単位 | ノードの生存確認 |
| ヘルスチェック | HTTP/TCPプローブでサービスの状態を確認 | 秒単位 | ロードバランサーのバックエンド検知 |
| ビジネスプローブ | 実際のリクエストをシミュレートしてビジネスロジックを確認 | 秒〜分単位 | エンドツーエンドの可用性監視 |
ハートビート検知の仕組み:ノードAが一定間隔(例:5秒)で監視側に「私は生きています」というシグナルを送信します。連続N回(例:3回)ハートビートが受信されない場合、ノードAが障害を起こしたと判定されます。重要なパラメータはハートビート間隔とタイムアウト閾値です。間隔が短すぎるとネットワークオーバーヘッドが増え、長すぎると障害検知が遅れます。
ヘルスチェックの3つのレベル:
- Liveness Probe(生存プローブ):プロセスは動いているか?動いていなければ再起動
- Readiness Probe(準備プローブ):サービスはリクエストを受けられるか?受けられなければロードバランサーから除外
- Startup Probe(起動プローブ):サービスの起動は完了したか?未完了なら待機し、障害と誤判定しない
4.2 自動復旧メカニズム
| メカニズム | 説明 | 代表的なツール |
|---|---|---|
| 自動再起動 | プロセスクラッシュ後に自動的に再起動 | systemd、PM2、K8s |
| オートスケーリング | 負荷増加時に自動的にインスタンスを追加 | K8s HPA、クラウドプロバイダーのAuto Scaling |
| サーキットブレーカー・フォールバック | 下流の障害時に高速に失敗させ、カスケード障害を防止 | Hystrix、Sentinel、Resilience4j |
| レートリミット | 容量を超えたリクエストを直接拒否 | Nginx limit_req、APIゲートウェイのレートリミット |
サーキットブレーカーパターン(Circuit Breaker)の詳細:
サーキットブレーカーの発想は電子回路のヒューズから来ています。電流が大きすぎると自動的に回路を切断し、回路全体が焼損するのを防ぎます。マイクロサービスでは、下流サービスが障害を起こした際、サーキットブレーカーが「開」になり、リクエストをタイムアウトまで待つのではなく、高速に失敗させます。
サーキットブレーカーの3つの状態:
閉(正常)──→ 失敗率が閾値を超える ──→ 開(遮断)
↑ │
│ クールダウン時間の経過
│ ↓
└── プローブリクエスト成功 ←── 半開(試探)- 閉状態:通常通りリクエストを転送しつつ、失敗率を統計
- 開状態:すべてのリクエストが即座にエラーを返す(高速失敗)、下流への呼び出しを行わない
- 半開状態:クールダウン時間が経過した後、少量のプローブリクエストを通す。成功すれば閉状態に復帰、失敗すれば開状態を継続
フォールバック(Fallback) はサーキットブレーカーに付随する戦略です。サーキットブレーカーが発動した後、エラーを直接返すのではなく、「代替」の結果を返します。例えば、レコメンドサービスが落ちたら人気商品リストを返す、ユーザーのアバターの読み込みに失敗したらデフォルトアバターを表示する、といった対応です。
5. カオスエンジニアリング:能動的に問題を見つける
カオスエンジニアリングの核心理念は、障害が発生するのを待つより、能動的に障害を発生させることです。制御可能な環境でシステムのレジリエンスを検証します。
| ツール | 提唱者 | コア機能 |
|---|---|---|
| Chaos Monkey | Netflix | 本番環境のインスタンスをランダムに終了 |
| Chaos Mesh | PingCAP | K8s環境での障害注入 |
| Litmus | CNCF | クラウドネイティブのカオスエンジニアリングフレームワーク |
| ChaosBlade | アリババ | マルチシナリオの障害注入ツール |
カオスエンジニアリングの実施ステップ
- 定常状態の定義:システムが正常に動作している指標を明確にする(例:P99レイテンシ < 200ms)
- 仮説の立案:あるノードが落ちた場合、システムは30秒以内に自動復旧するはず
- 障害の注入:制御可能な範囲で障害を発生させる(まずテスト環境で、その後本番環境で)
- 結果の観察:システムは期待通りに復旧したか?カスケード障害は発生していないか?
- 弱点の修正:発見された問題に基づいてアーキテクチャとプロセスを改善する
まとめ
高可用性は機能ではなく、アーキテクチャの能力です。設計、開発、デプロイ、運用のすべての段階で保証する必要があります。
本章の主要なポイントを振り返りましょう:
- いくつ9:9が1つ増えるごとにダウンタイムが1桁減り、コストと複雑さは指数関数的に増加する
- フェイルオーバー:アクティブ・スタンバイからマルチリージョン・アクティブ・アクティブまで、業務要件に応じて適切なアーキテクチャを選択する
- RPOとRTO:データの価値とビジネスの許容度に基づいてバックアップと復旧戦略を設計する
- 自動化:障害検知、自動再起動、サーキットブレーカー・フォールバックは高可用性のインフラストラクチャ
- カオスエンジニアリング:能動的に障害を発生させ、制御可能な環境でシステムのレジリエンスを検証する
関連資料
- Site Reliability Engineering - Google SREの古典
- Chaos Monkey - Netflixのカオスエンジニアリングツール
- Release It! - 本番環境設計パターン
- Chaos Mesh - K8sカオスエンジニアリングプラットフォーム