1. はじめに
システムを開発・運用していると、「障害は必ず起きるもの」という前提に立たざるを得ない瞬間があります。ハードウェアの故障、ネットワークの瞬断、想定外の負荷。こうした事象をゼロにすることはできません。
そこで重要になるのが「フォールトトレランス(Fault Tolerance:耐障害性)」という考え方です。この記事では、フォールトトレランスの基本概念から具体的な実現手法、そして「検証」の話まで整理します。
2. この記事はこんな方におすすめ
- システム設計や運用に関わっており、「可用性」「耐障害性」という言葉の意味を整理したい方
- 冗長化やフェイルオーバーといった用語を聞いたことはあるが、体系的に理解できていない方
- インフラ・バックエンドの設計を任され始めたエンジニアの方
前提知識として難しいものは不要です。サーバーやネットワークの基本的なイメージがあれば読み進められます。
3. フォールトトレランスの定義
フォールトトレランスとは、システムの一部に障害(フォールト)が発生しても、全体としては機能を維持し続ける性質を指します。
ポイントは「障害が起きないようにする」のではなく、「障害が起きることを前提に、それでも動き続ける」という発想の転換にあります。障害を防ぐこと自体は可用性設計の一部でしかなく、フォールトトレランスは一歩進んで「起きた後にどう振る舞うか」を設計する話です。この記事では、以降この一点を軸に話を進めます。
4. 主な実現手法
構成要素が多いシステムほど、どこかが壊れる確率は上がります。サーバーが1台落ちる、回線が切れる、外部APIがタイムアウトするといった事象のたびにサービス全体が止まっていてはユーザーの信頼もビジネスも持ちません。今回は、そうした障害に対抗するための具体的な実現手法をそれぞれ紹介します。
1. 冗長化(Redundancy)とフェイルオーバー(Failover)
同じ役割のコンポーネントを複数用意し、1つが故障したら自動的に待機系へ切り替える方式です。サーバーの多重化、データベースのプライマリ/レプリカ構成などが代表例です。
2. サーキットブレーカー
依存先のサービスが不調なとき、リクエストを送り続けるのではなく一時的に遮断し、障害の連鎖を止めるパターンです。冗長化の有無にかかわらず単独でも効果があり、特に依存先が1つしかない構成では、これ単体が障害の連鎖を防ぐ最後の砦になります。
3. リトライとタイムアウト設計
一時的な障害には、適切な間隔・回数でのリトライが有効です。ただし無制限のリトライは相手側の負荷を悪化させるだけなので、指数バックオフなどの制御が前提になります。実装が最も雑になりやすい箇所でもあります。
4. レプリケーション
データを複数箇所に複製し、1箇所が失われても継続できるようにする手法です。ただし、複製先へのデータ反映を即座に行う「同期レプリケーション」にするか、多少の遅延を許容する「非同期レプリケーション」にするかで、性能と整合性のどちらを優先するかが変わります。冗長化・フェイルオーバーとセットで使われることが多い一方、この整合性のトレードオフという別の難しさが絡むため、設計の初期段階で方針を決めておく必要があります。
5. 設計だけでは終わらない、という話
単一障害点(SPOF)の排除、監視による早期検知、段階的な劣化(Graceful Degradation)の許容、コストバランス。これらは設計における重要なチェック項目ですが、それだけで本番のトラブルを防ぎきれるわけではありません。
本当にエンジニアがつまずくのは、設計書を離れて本番環境と向き合ったその先にある「想定外の細部」です。「冗長化してあるから安心」で終わらせず、意図的に障害を起こして切り替えの挙動を確認する検証まで含めて、初めてフォールトトレランスと呼ぶことができます。
6. 身近な例で考えるフォールトトレランス
たとえば、家の中の照明を考えてみます。1つの部屋に電球が1つしかなければ、それが切れた瞬間に部屋は真っ暗になります。ですが、照明を複数系統に分けておけば、1つが切れても別の照明で最低限の明るさは保てます。これは「冗長化」そのものです。
あるいは、スマートフォンの通信も似ています。Wi-Fiが不安定になったとき、多くの端末は自動的にモバイル回線へ切り替えます。ユーザーは「今、回線が切り替わった」とすら気づかないことが多いはずです。まさに「フェイルオーバー」が裏側で働いている例だと言えます。
うまく機能しているフォールトトレランスほど、利用者からは「何も起きていない」ように見えます。これが設計で目指すべきゴールです。
7. 「気づかれない」は、確認しない限り信用できない
ただし、ここに落とし穴があります。6節で挙げた例は、あくまで「うまく機能した場合」の話です。冗長構成やフェイルオーバーの仕組みは、設計書の上ではきれいに完結して見えても、実際に障害を起こしてみるまで、本当に切り替わるかどうかは分かりません。
たとえば、待機系のサーバーに最新の設定が反映されていなかったり、切り替え自体は成功していても監視側がそれを検知できていなかったりすると、「何も起きていないように見える」状態と「実は静かに壊れている」状態を、外からは区別できません。うまく機能しているときの見た目と、壊れているのに気づかれていないときの見た目は、同じなのです。
これに対する答えが、意図的に本番相当の環境で障害を発生させ、実際に切り替わるかどうかを確認する、いわゆるカオスエンジニアリングの考え方です。サーバーを1台落としてみる、ネットワークを意図的に遅延させてみる、といった実験を通じて、「設計上は冗長化されているはず」を「実際に切り替わることを確認済み」に変えていく作業です。
8. まとめ
フォールトトレランスは、「壊れる部分があっても、全体は止めない」ための設計思想です。ただ、ここで本当に焦点を当てたいのは手法の網羅ではなく、「うまく機能している仕組みほど、平常時の見た目からはその真価が見えにくい」という点にあります。
どれほど綿密な冗長化設計を行っても、それだけでシステムが動き続ける保証にはなりません。フェイルオーバーテストを通じて、実際に切り替わることを確かめるプロセスが不可欠です。