次の方法で共有



年 9 月 2015

ボリューム 30 番号 9

Microsoft Azure - クラウドにおけるフォールト トレランスの問題点と解決策

Mario Szpuszta | 年 9 月 2015

Microsoft Azure には、障害が発生してもサービスやアプリケーションを利用できるようにするメカニズムがいくつか組み込まれています。このような障害には、ハードディスクのクラッシュなどのハードウェア障害や、ストレージ サービスやネットワーク サービスといった利用中のサービスでの一時的な可用性の問題も含まれます。Azure とそのソフトウェア管理のインフラストラクチャは、こうした障害を予測し、対処できるように作成されています。

障害が発生すると、Azure インフラストラクチャ (ファブリック コントローラー) が即座に反応し、サービスとインフラストラクチャを復元します。たとえば、物理ホストのハードウェア障害が原因で仮想マシン (VM) に問題が発生すると、ファブリック コントローラーがその VM を別の物理ノードに移動します。移動先の物理ノードは、Azure Storage でその VM が格納されていたのと同じハード ディスクを基準に決定されます。同様に、Azure にはサービスにダウンタイムが生じないように、アップグレードや更新を調整する機能があります。

コンピューティング リソース (クラウド サービス、従来型 IaaS VM、VM スケール セットなど) の場合、高可用性を実現するうえで最も重要かつ基本的な概念が、障害ドメインと更新ドメインです。この 2 つのドメインは、Azure の誕生以来 Azure に含まれています。今回は、あまり知られていないこの 2 つの概念について解説します。

Azure データセンター アーキテクチャ

障害ドメインと更新ドメインを完全に理解するには、Azure データセンターの大まかな構造を図示するとわかりやすくなります。Azure データセンターは、マイクロソフト内で「Quantum 10」と呼ばれるアーキテクチャを採用しています。Quantum 10 は、それ以前のデータセンター アーキテクチャよりも高いスループットを確保しています。Quantum 10 のトポロジは、ブロッキングのない、完全なメッシュ ネットワークを実装し、Azure データセンターごとに高帯域幅の一体型バックプレーンを提供します (図 1 参照)。

Azure データセンター アーキテクチャの概要
図 1 Azure データセンター アーキテクチャの概要

各ノードはラックに配置されます。そのラックが集まってクラスターを形成します。各データセンターには異なる種類のクラスターが多数存在します。クラスターには Storage を担当するものもあれば、Compute や SQL などを担当するものもあります。Top-Of-Rack (TOR) スイッチがラック全体に対する単一障害点になります。

クラスターのファブリック コントローラーがすべてのマシン (ノード) を管理します。ファブリック コントローラーは、クラスター内でのノード間のデプロイを編成します。各クラスターは、フォールト トレランスを目的としてファブリック コントローラーを複数保持します。ファブリック コントローラーは、クラスター内の各ノードの正常性を認識する必要があります。このように正常性を認識することで、ノードがデプロイを実行できるかどうかを適切に判断できるようになります。また、正常性の認識は障害検知にも役立ちます。障害を検知することで、ファブリック コントローラーは障害の影響を受けた VM を別の物理ノード上に再プロビジョニングし、自動的にデプロイを復旧できるようになります。

ファブリック コントローラーによるノード正常性の判断をさらに的確にサポートするために、クラスター内で実行される各マシンにはさまざまなエージェントが組み込まれています。そのエージェントが、継続的にノードの正常性を監視し、その正常性をファブリック コントローラーに報告します。重要なのは、これらを実現するために、さまざまなコンポーネントが連携するしくみを理解することです。重要なコンポーネントは以下のとおりです (図 2 参照)。

  • ホスト OS: 物理マシンで実行中の OS。
  • ホスト エージェント: 各ノードで実行中のプロセスで、物理マシンからファブリック コントローラーへのコミュニケーション ポイントを提供。
  • ゲスト OS: VM 内で実行中の OS。
  • ゲスト エージェント: VM 内に常駐し、VM の正常性を監視、管理するためにホスト エージェントと通信。

Microsoft Azure クラスターの物理マシンの内部
図 2 Microsoft Azure クラスターの物理マシンの内部

障害ドメインと更新ドメイン

PaaS (サービスとしてのプラットフォーム) アプリケーションの高可用性を確保するために、ファブリック コントローラーがホストする各 PaaS アプリケーションは、異なる障害ドメインと更新ドメインに展開されます。

障害ドメインは、障害の物理的単位で、データセンターの物理インフラストラクチャと密接に関連します。Azure の場合は、サーバーの各ラックが障害ドメインに相当します。Azure プラットフォームがホストする (複数のインスタンスを備えた) PaaS アプリケーションはすべて、複数の障害ドメインで利用できることが保証されます。ただし、PaaS アプリケーションの展開先となる障害ドメインの総数は、データセンター内のマシンの可用性に基づき、ファブリック コントローラーによって決定されます。

更新ドメインは、システムに更新プログラムを提供する際に、アプリケーションの可用性確保を支援する論理単位です。PaaS アプリケーションの場合、更新ドメインはユーザーが構成する設定です。Azure のアプリケーションは、アプリケーションのインスタンスを最大 5 つの更新ドメインに展開できます (図 3 参照)。

障害ドメインと更新ドメインの構成
図 3 障害ドメインと更新ドメインの構成

障害ドメイン、更新ドメイン、および IaaS VM

障害ドメインと更新ドメインに Iaas (サービスとしてのインフラストラクチャ) VM を展開する際、Azure では可用性セットという概念を導入します。可用性セット内のすべてのインスタンスは 2 つ以上の障害ドメインに展開され、別の更新ドメイン値が割り当てられます。

VM を可用性セットに割り当てない場合、その VM はサービス レベル アグリーメント (SLA) の対象外になります。この条件は重要です。障害が発生した場合や、更新プログラムを Azure データセンターで展開する場合でも、この条件を満たしているかどうかで、サービスやアプリケーションの高可用性を実現する方法が変わってくるためです。VM を可用性セットに割り当てるだけで、そのような障害からの影響を回避できます。

可用性セットに割り当てる重要性を示すために、次のシナリオを考えてみます。Azure 製品チームは、すべてのデータセンターに OS の更新プログラムを定期的に提供します。更新プログラムをデータセンター全体に提供するには、(物理マシンの) ホスト OS と ゲスト OS (PaaS アプリケーションをホストする VM または IaaS VM) が最新の OS に更新されている必要があります。アプリケーションの可用性を損なうことなく更新プログラムを展開するには以下のことが必要です。

  1. すべての利用可能な障害ドメインに対して、データセンター全体のホスト OS を、1 度につき 1 つの障害ドメインで更新します。
  2. すべての利用可能な更新ドメインに対して、各ユーザー アプリケーションのゲスト OS を、1 度につき 1 つの更新ドメインで更新します。

上記のアプローチを実行することで、Azure は、サービスの可用性を確保しながら Azure インフラストラクチャに対して更新プログラムを提供できます。ただし、サービスごとに少なくとも 2 つのインスタンスを実行するか、または可用性セット (負荷分散 Web サービスや SQL Server AlwaysOn 可用性グループ ノードなど) の一部として少なくとも 2 つの VM を実行することが条件です。

障害ドメインの数

PaaS のようなワークロードは多くの場合ステートレスですが、このようなワークロードに関しては障害ドメインと更新ドメインによって可用性の確保が支援されます。ステートレスな Web アプリケーションは上記のアプローチと互換性があります。一時的なダウンタイムや更新サイクル中にノードのサブセットが利用できなくなったとしても、Web アプリケーション全体やサービスは引き続き利用可能です。

(RDBMS や NoSQL などの) データベース サーバーのように、ステートフルな性質を持つインフラストラクチャに関しては、状況がもっと複雑になります。このようなケースでは、サーバーが複数の障害ドメインに展開されることを把握するだけでは不十分な場合があります。データベース クラスターでは、クラスターの正常性を確保するために、最少数のノードが常時稼働している必要があります。障害が発生した場合に新しいマスター ノードを選出するために、クォーラム ベースのアプローチを検討してください。

IaaS VM の場合、Azure は同一の可用性セット内の VM が少なくとも 2 つの障害ドメイン (つまり 2 つのラック) に展開されることを保証します。1 つの可用性セット内の VM が 3 つ以上の障害ドメインに展開される可能性もいくらかありますが、保証はされません。過去数年間にわたって実施した実用的なテストにおいて複数の米国地域と、北欧や西欧に対して展開したとき、そのプロジェクトで使用された障害ドメインの数は常時 2 つだけでした (図 4 参照)。

サンプル SQL AlwaysOn 可用性グループ クラスターの障害ドメイン
図 4 サンプル SQL AlwaysOn 可用性グループ クラスターの障害ドメイン

図 4 は、Azure PowerShell をで実行した Get-AzureVM コマンドの結果を示しています。この結果は Azure PowerShell の GridView コントロールに表示されています。GridView コントロールは、クラスター内の VM が 2 つの障害ドメインと 3 つの更新ドメインに展開されていることを示しています。また各 VM はすべて同一の可用性セットの一部です (GridView コントロールには示されていません)。

このサンプルの sql1 ノードと sqlwitness ノードは同一の物理ラックに配置されています。同一の TOR スイッチでこのラックとデータセンターの残り部分が接続されています。sql2 ノードは別のラックに配置されています。

たった 2 つの障害ドメイン

Web API や Web アプリケーションのようなステートレス アプリケーションの場合、展開される障害ドメインが 2 つだけでも、少なくとも整合性の観点からは問題にはなりません。しかしデータベース サーバーのようなステートフル ワークロードの場合は、少なくとも可用性の観点から見ると話が変わってきます。

クラスターのしくみによっては、障害が発生してダウンした場合でも、クラスターの正常性に影響しないノード数を把握しておくことが重要になる可能性があります。クラスターが特定の処理、たとえば新しいマスターの選出や読み取り要求の整合性の確認などをクォーラム投票や票数ベースの投票に依存している場合は、最悪の事態でもダウン可能なノード数を把握しておくことがさらに重要です。

障害ドメインによって VM が自動的に回復するとはいえ、同時に障害が発生しても問題のないノード数を意識しておくことは必要です。VM 自体と、その VM が実行されているデータベース システムの回復にファブリック コントローラーが必要とする時間によっては、回復処理に時間がかかる場合があります。

アップグレード時における Azure の自動処理の内部動作を把握する場合は全体的なトピックの方が重要です。IaaS VM の場合、VM をホストしている各物理ノードのハイパーバイザーで実行中のホスト OS に対してアップグレードを展開すると、そのアップグレードはすべて障害ドメインで実行されます。多くの開発者コミュニティで想定されているように、更新ドメインで実行されるのではありません。更新ドメインが使用されるのは、PaaS VM 内で実行されているアプリケーションを更新する場合に限られます。つまり、標準間隔では四半期ごとに、ホスト OS アップグレードの影響を受けることになります。クラスターが 2 つの障害ドメインに展開されていても、票数ベースの投票やそれに準じた方法に依存している場合は継続的にダウンタイムが発生する可能性があります。

よくある例が、MongoDB のレプリカ セットを Azure に展開している場合です。MongoDB の各レプリカ セットはマスターを 1 つだけ必要とします。そのマスター ノードに障害が発生した場合は残りのノードから新しいマスターが選出されます。その選出では、マスターを選ぶために過半数の投票が必要とされます。新しいマスターの投票に十分な数のノードが起動されていない場合は、レプリカ セット全体が異常な状態にあると宣言され、"ダウン" していると見なされます。

MongoDB のドキュメント (bit.ly/1SxKrYI、英語) には、レプリカ セットのサイズごとにフォールト トレランスが明確に記載されています。3 ノードのレプリカ セットでは、障害が発生しても問題のないノードは 1 つだけです。5 ノードのレプリカ セットでは、障害が発生してもクラスター全体がダウンしない最大ノード数は 2 です (図 5 参照)。

図 5 MongoDB レプリカ セットのフォールト トレランス

メンバー数 新しいプライマリ選出に必要な過半数票 フォールト トレランス
3 2 1
4 3 1
5 3 2
6 4 2

レプリカ セットでの実行が必要なデータベース ノード数が同数の場合 (たとえば、1 つのレプリカ セットに対して 2 つのデータベース ノード)、MongoDB では決定者の考え方が採用されます。決定者はマスター選出時に投票サーバーとしての役割を果たします。ただし、(コストとリソースを節約するために) データベース スタック全体を実行することはありません。そこで、MongoDB レプリカ セットのデータベース ノードは 2 つで十分という形に落ち着いた場合、第 3 のノード、つまり決定者が必要になります。この決定者は、障害が発生した際に過半数ベースのマスター選出で票数を増やすためだけに配置されます。

SQL Server AlwaysOn 可用性グループでも同様の状況が発生します。この場合、新しいプライマリ ノードを選出するために過半数のノードが必要になります。投票しか実行しないメンバーの動作原理は MongoDB と同様のものです。SQL Server の場合、このメンバーは監視と呼ばれます (MongoDB のように決定者とは呼ばれません)。

上記の 図 4 で示した SQL Server とそのデプロイを考えると、sql1 と sqlwitness が同じ障害ドメインに配置され、sql2 が別の障害ドメインに配置されていることが明確に記載されています。障害ドメイン "0" に障害が発生した場合は、マスターと監視が両方ともダウンしているため、sql2 のみが残されます。しかし、sql2 だけではクラスター内で新しいマスターを選出するための過半数条件を満たせません。つまり、障害ドメイン "0" に障害が発生した場合、クラスター全体が異常と見なされます。

sql1 と sql2 が同一の障害ドメインに配置された場合はこの状況はさらに悪くなります。この場合、ファブリック コントローラーがノードを潜在的な障害から回復するか、ホスト OS のアップグレード プロセスが完了するまで、データベース ノードは両方ともダウンします。

MongoDB レプリカ セットでも似たような状況が発生します。図 5 の表は、MongoDB の公式ドキュメントに掲載されているものですが、3 ノードのレプリカ セットの場合、クラスター全体がアクティブで利用可能な状態を維持するには、障害が発生しても影響の出ないノード数が 1 つだけであることがはっきりと示されています。したがって、限られた数の障害ドメインに、どのようにノードが展開されているかが重要です。その展開方法によって影響が及ぶ可能性があるのは Azure ホスト OS のアップグレードと潜在的な障害の両方になります。

ステートフルなサービスの高可用性

次の疑問点は、Azure では VM が 2 つの障害ドメインに展開されることがほとんどである場合に、どうすれば高可用性を確保できるかということです。この疑問点には、中期的な解決策と短期的な解決策があります。

中期的には、Azure 製品グループが状況を劇的に改善するように取り組んでいます。(新しい Azure リソース マネージャー API に基づく) バージョン 2 の IaaS VM をデプロイする場合、Azure はワークロードを少なくとも 3 つの障害ドメインに展開できます。これはバージョン 2 の VM と Azure リソース マネージャーを使用する十分な理由になります。

短期的な場合、または依然として従来の Azure サービス管理とバージョン 1 の IaaS VM を利用する場合、解決策はもっと複雑です。SLA、回復時刻の目標 (RTO)、および回復ポイントの目標 (RTO) に応じて、ダウンタイムのリスクを減らすための選択肢は 2 つあります。図 6 にその両方のアプローチを示します。どちらも SQL Server AlwaysOn 可用性グループに基づいています。

SQL Server AlwaysOn 可用性グループのデプロイ
図 6 SQL Server AlwaysOn 可用性グループのデプロイ

目標は、定期的に発生するホスト OS アップグレードと偶発的な障害の両方による影響を常に減らすことです。単一のデータセンター内の 3 ノードのクラスターでは、1 つのノードを VM 可用性セットの外側にデプロイし、2 つのノードを同一の VM 可用性セットの一部としてデプロイします。

このアプローチを取ることで、ホスト OS のアップグレードによる影響は限界近くまで軽減されます。可用性セット内の VM は、単一 VM のホスト OS とは異なるタイミングでアップグレードされます。可用性セットを使用せず 1 つの VM を実行しているホスト OS は通常、可用性セット内で VM を実行しているホスト OS よりも約 1 週間早くアップグレードされます。

障害ドメインでの障害については影響が及ぶ可能性が低減するだけです。可用性セットの外側のノードが、可用性セットの内側にある VM のいずれかの障害ドメインに配置される可能性は常にあります。この点は Azure データセンターで使用されているリソースと利用可能なリソースによって大きく変わります。

図 6 に示すような Active Directory ドメインでは、上記のような解決策は必要ありません。どちらにしても、プライマリ ドメイン コントローラーと、高可用性を確保するためのバックアップ ドメイン コントローラーしか存在しません。つまり 2 つのノードは完全に分離して 2 つの障害ドメインに展開され、Azure ではこれがバージョン 1 の IaaS VM に対して保証されます。

この場合、図 6 の SQL ノードを適切に配置することに依然として課題が残ります。このリスクは、sqlwitness を同一のデータセンターにデプロイしないことで低減できます。この方法では、リスクが減るだけではなく、本質的にはリスクそのものがなくなります。この解決策も 図 6 に示しています。つまり、2 つの領域にデプロイを分散します。

2 つの選択肢

SLA、PRO、および RTO の各ニーズと、高可用性に対してどの程度コストを掛ける意思があるかによって、ここでも主に次の 2 つの選択肢があります。第 2 領域に完全に機能するバックアップをデプロイする方法か、セカンダリ リージョンに決定者または監視のみを配置する方法です。

第 2 領域で完全な機能をデプロイすることは、セカンダリ リージョンにデプロイ全体をレプリケートすることを意味します。このデプロイには、フロントエンドと中間層のアプリケーションおよびサービスも含まれます。プライマリ リージョンで大きな障害が発生した場合は、顧客をセカンダリ リージョンにリダイレクトできます。

上記のようなデプロイを構築するのは、基本的に PRO または RTO の高い目標値に対応するためです。MongoDB や SQL AlwaysOn のようなデータベース システムで短時間の RPO および RTO を設定している場合、通常はそのニーズに対応するために、レプリカ セットや SQL 可用性グループ クラスターが 2 つの領域にまたがり、この両領域間で継続的なレプリケーションが実現されます。領域をまたがるレプリケーションは遅延とパフォーマンスの問題があるため非同期で行われますが、レプリケーションは数十分から数時間ではなく、数秒から数分の範囲内で実行されます。

一方、セカンダリ リージョンで監視または決定者だけを単一の VM として実行する方法はずっと安価な代替手段になります。障害ドメインで障害が発生した際にプライマリ クラスターがダウンしないことだけが必要な場合はこの方法で十分です。この場合、新しいノードや VM をセカンダリ リージョンで稼働するような一部の追加的な重要な手順を省くことで、すぐにセカンダリ リージョン全体にフェール オーバーする選択肢は利用できなくなります。

図 6 の例に示すように、完全な SQL ノードをセカンダリ リージョンで唯一のノードとして実行することもできます。この SQL ノードは単一の VM として実行されるため、アップグレード サイクルが異なります。また、このノードは異なるデータセンターで実行されるため、主要な可用性セットのノードとまったく同時にアップグレードされたり、障害が発生したりする可能性が低くなります。

まとめ

開発するアプリケーションやサービスで高可用性とフォールト トレランスを実現することは簡単なプロセスではありません。その実現には根本的な概念を理解し、順応することが求められます。障害ドメイン、更新ドメイン、および可用性セットを理解する必要があります。Azure に移行する際には、インフラストラクチャで使用中のステートフル システムのフォールト トレランス要件を特に理解する必要があります。Azure の障害ドメインおよび更新ドメインの動作に対するフォールト トレランス要件を調査してください。

新しく完全な IaaS を展開する場合は、Azure リソース マネージャーおよび Azure リソース グループでの作業の一環として必ずバージョン 2 の IaaS VM を利用してください。バージョン 2 の IaaS VM を利用することで、3 つ以上の障害ドメインにデプロイすることによるフォールト トレランスのメリットを得ることができます。従来のサービス管理を使用してデプロイする場合は、今回概要を説明した実情を必ず理解して受け入れてください。今回のアドバイスを実行することで、障害ドメインのダウンタイムの影響と、ホスト OS のアップグレードのようなメンテナンス イベントの影響を減らすことができます。今回概要を述べた考え方を参考にし、慣れることで、望んでもいないことに驚かされることなく高可用性を実現できるでしょう。


Mario Szpuszta は、DX Corp の Global ISV チームの主席プログラム マネージャーです。世界中の独立系ソフトウェア ベンダーと協力し、Microsoft Azure で各社のソリューションとサービスを実現しています。連絡先は、ブログ (blog.mszcool.com、英語)、Twitter (twitter.com/mszcool、英語) または marioszp@microsoft.com (英語のみ)です。

Srikumar Vaitinadin は、DX Corp の Global ISV チームのソフトウェア開発エンジニアです。それ以前は Microsoft サービスの Azure への移行に携わっていました。Srikumar の連絡先は、srivaiti@microsoft.com (英語のみ) です。

この記事のレビューに協力してくれた技術スタッフの Guadalupe Casuso および Jeremiah Talkar に心より感謝いたします。
Guada Casuso は、Microsoft Azure に携わるテクノロジ エバンジェリストであり、クラウドおよびクラウド プラットフォーム モバイル開発の経験が豊富にあります。余暇にはサーフィンをしたり、ドローンを飛ばしたりしています。Guada はブログ (atomosybitsenlanube.net 、英語) と Twitter (twitter.com/guadacasuso、英語) で自分の考えを発表しています。