[レポート] SUP401 Building resilient multi-site workloads using AWS global services #reinvent #reinvent2022
こんにちは。
ご機嫌いかがでしょうか。
"No human labor is no human error" が大好きな吉井 亮です。
セッション名 : Building resilient multi-site workloads using AWS global services
概要概要(機械翻訳) : このセッションでは、AWSがどのように予測可能な分離境界を使用して、ゾーン、リージョン、およびグローバルサービスを作成するかを発見してください。また、単一障害点を防ぐためにグローバルサービスを利用するためのベストプラクティスを紹介します。Netflixがどのようにこれらのベストプラクティスを使用して、問題を検出したときにAWSリージョンを確実に退避させるためのツールを作成したかを確認します。このセッションの終わりには、コントロールプレーンとデータプレーン、静的安定性の概念、およびAWSグローバルサービスを使用する際に弾力性のあるマルチサイトワークロードを構築する方法について、より深く理解できるようになります。
スピーカー :
Michael Haken, Principal Technologist, AWS
James Aitken, Sr Software Development Manager, AWS
Ryan Schroeder, Senior Software Engineer, Netflix
レポート
聴衆のみなさんで dependency failure を経験された方はいますか?
どの AWS サービスがグローバルとみなされるか、ご存知の方はいらっしゃいますか?
静的安定性と呼ばれるパターンをご存知の方はいらっしゃいますか?
このセッションでは、AWS の障害隔離境界を理解して、グローバルサービスに依存する弾力性のあるワークロードを構築する方法について説明します。
fault isolation boundaries
AWS は世界中に30の地理的リージョンがあり、それぞれのリージョンは、物理的に分離した複数のアベイラビリティゾーンで構成されています。
すべてのリージョンは現在3つ以上のアベイラビリティゾーンを持っており、あるリージョンで障害が発生しても、他のリージョンは通常、影響を受けません。
リージョン内の各アベイラビリティゾーンは、他のすべてのアベイラビリティゾーンから最大60マイルまで有意に離されており、これは相関障害を防ぐのに十分な距離です。
電力や水の供給停止、ファイバーの分離、地震、火災、竜巻、洪水などの災害シナリオの影響を同時に受けないように設計されています。
AWS はグローバルに分散したポインツ・オブ・プレゼンス・ネットワークも運営しています。
グローバル・エッジ・ネットワークは現在、48カ国90都市以上にある400のエッジロケーションと13の地域ミッドティアキャシュを含む410以上のポップで構成されています。
Route 53、Global Accelerator、その他エッジネットワーキングサービスは、1つのポップまたはエッジに影響を与えるイベントが発生した場合でも、他のホップやエッジやグローバルネットワークに影響は及びません。
パーティションという概念もあります。AWS パーティションは、異なるリージョンのグループであり、すべてのリージョンはどこか1つのパーティションに含まれます。
コマーシャルパーティション、中国パーティション、GovCloud パーティションが存在します。
いくつかの AWS サービスは、S3 のクロスリージョンレプリケーションや Transit Gateway のリージョンピアリングのようなクロスリージョンの機能を提供います。これらの機能は同じパーティションでのみ機能します。
IAM も同様です。IAM クレデンシャルは他パーティションで使用することはできません。
Control plane and data plane
AWSは、ほとんどのサービスをコントロールプレーンとデータプレーンという概念に分離しています。
コントロールプレーンは、リソースの作成、読み込み、更新、削除に使用される管理APIを提供します。
以下は EC2 インスタンスを起動するときのコントロールプレーンのアクションです。
- 容量のある物理サーバを探す
- ネットワークインターフェースを割り当てる
- EBS ボリュームを準備する
- IAM 認証情報を生成する
- セキュリティグループのルールを追加する
- 他複数
データプレーンは、サービスの日々の運用を提供します。
これらはすべてデータプレーンの操作です。
- EBSボリュームから読み書きする
- EC2 インスタンスの実行
- S3 バケットへのオブジェクトの取得と配置
- Route 53 DNSクエリへの応答
- ヘルスチェックの実行
- 他複数
コントロールプレーンは複雑な仕組みです。
データプレーンはコントロールプレーンほど複雑ではなく、可動部品が少ないため、データプレーンでの障害はコントロールプレーンよりも統計的に発生しにくくなっています。
データプレーンとコントロールプレーンの両方がサービスの成功と運用に不可欠である一方、AWS はそれらを別個のコンポーネントとみなしています。この分離は、パフォーマンスと可用性の両方の利点をもたらします。
Static stability
静的安定性についてお話ししましょう。
AWS がこの言葉を使う意味は「システムが静的な状態で動作し、依存関係に障害が発生しても、通常通り動作し続けることができる」というものです。
私たちは、依存関係と運命をイコールとは考えていません。依存関係からシステムの可用性を解き放ちます。
循環的な依存関係を排除すると、静的安定性を実現するのに役立ちます。
DNS を例に出します。多くのシステムが DNS に依存して機能している場合、DNS 障害でなにもかもできなくなる可能性があります。
静的安定性を実現するもうひとつのアプローチは、事前にプロビジョニングをしておくことです。
プレプロビジョニングは AZ 障害のような損失への対応に役立ちます。
コントロールプレーンとデータプレーンに戻って考えてみましょう。
データプレーンは既存の状態を維持します。コントロールプレーンに障害が発生しても、データプレーンの可用性に影響を与えないようにするためです。データプレーンは更新されないかもしれませんが、コントロールプレーンに障害が発生する前に動作していたものは、すべてそのまま動作し続けます。
プレプロビジョニングが障害復旧に有効なのか、これがその理由のひとつです。
そして最後に、同期的な相互作用を排除し、依存関係を解消し、非同期的な相互作用を使用することです。
例えば、いくつかのリクエストをキューに入れ、後でそれを処理します。非同期ジョブやワークフローが該当します。
依存関係の一時的な障害に耐えることができます。
Static stability takeaways
静的安定性とは、静的な状態で動作し、依存関係の障害や使用不能時に変更を加える必要なく通常通り動作し続けることを意味します。
AWS はサービスのデータプレーンからコントロールプレーンの依存性を取り除くことで静的安定性を達成しています。
コントロールプレーンは統計的に故障しやすいです。より信頼性の高いアプローチは、データプレーンに依存することです。 例えば、DNS レコードを書き換える方法より Route 53 ヘルスチェックを採用すべきです。
AWS service types
障害隔離境界に基づいて3つのタイプのサービスを提供しています。
ゾーナルサービス、リージョナルサービス、グローバルサービスです。
ゾーナルサービスは、EC2 や RDS のようなもので、リージョン内の各アベイラビリティゾーンで独立して動作します。
さらに重要なのは、各アベイラビリティゾーンで独立して障害が発生することで、あるアベイラビリティゾーンのサービスが別のアベイラビリティゾーンのサービスに依存するのを最小限に抑えることができるということです。
ゾーナルサービスでは、ゾーンデータプレーンとリージョナルコントロールプレーンを持っています。
2つ目のカテゴリーはリージョナルサービスです。これらは、AWS がアベイラビリティゾーンの上に構築したサービスです。
SQS や DynamoDBのようなサービスはリージョナルサービスの一例で、複数のアベイラビリティゾーンに展開されたサービスを論理的にグループ化し、単一のリージョナルエンドポイントを提供します。
アベイラビリティゾーンの独立性と冗長性を利用して、可用性と耐久性のリスクであるインフラ障害を最小化します。
リージョナルサービスはその名の通り、リージョナルデータプレーンとリージョナルコントロールプレーンを持っています。
最後のカテゴリはグローバルサービスです。グローバルサービスは、単一のリージョンに制約されるリソースを持たないサービスです。
そのため、一般にグローバルと呼ばれることが多いのですが、この用語は少し誤解を招く可能性があります。これらのサービスは依然としてコントロールプレーンとデータプレーンを分離するという従来のAWSのパターンに従っているということです。
グローバルサービスは、単一のリージョンに集中化されたコントロールプレーンと、グローバルに分散化されたデータプレーンを持っています。
Global service categories
AWSのグローバルサービスには、3つの主要なカテゴリがあります。パーティショナルサービス、エッジサービス、エッジサービスのなかで動作するサービスです。
最初の2つのサービスは単一のリージョンでホストされるコントロールプレーンを持っています。この単一のコントロールプレーンは単一障害点となる可能性があります。
3つ目のサービスも単一のリージョンに依存性をもっており、同じく単一障害点となる可能性があります。
Route 53レコードの作成、更新、削除の操作を例にだして、もう少し詳しく説明します。
例えば、ロードバランサーをプロビジョニングするたびに、DNS 名を付与します。
そのDNSレコードを作成するために、us-east-1 で Route 53 と話をする必要があります。(その他の多くのサービスにも当てはまります)
S3では、バケット作成や削除だけではなく put や delete などのほとんどのアクションが us-east-1 に依存します。バケット名はグローバルに一意でなければならないからです。
状態を管理し、グローバルな一意性を確保する必要があり、それを es-east-1 を通じて一元的に行っています。
Multi-Region Access Points は us-west-2 にホストされる単一のコントロールプレーンを持っています。
最後に CloudFront です。
API Gateway は CloudFront に依存しています。
IAM control plane and data plane
ここでは、IAMのデータプレーンを見ることができます。
データプレーンはリージョンごとに独立して存在し、リージョン内の AWS サービスは IAM データプレーンと直接会話します。
Sig V4 を使って行うすべての API コールの認証と認可は、このデータプレーンを通して行われます。
コントロールプレーンもあって、これはアイデンティティやポリシーといった IAM リソースを管理するために使うものです。 ロールの作成を呼び出すと、それはコントロールプレーンを経由します。 コントロール・プレーンは、その変更を必要な場所に伝搬させる役割も担っています。
コマーシャルパーティション (商用リージョン) の IAM コントールプレーンは単一です。この依存関係には本当に注意しなければなりません。
Multi-site workloads
一般的に、AWSのマルチサイトワークロードには2つの種類があります。マルチ AZ とマルチリージョンです。
マルチサイトワークロードの障害隔離境界は、爆発半径を抑制し、相関性のある障害を防止するために使用されます。
マルチ AZ にしておけば、ゾーナルサービスに影響が出た場合、別のアベイラビリティゾーンに退避することが可能です。
マルチリージョンの計画があれば、リージョナルサービスに障害が発生しても影響を軽微にすることが可能です。
Global service best practices
リージョナルサービスやゾーナルサービス障害に対処する基本的な戦略は持っています。
グローバルサービスに障害が発生したら退避する先はありません。グローバルサービスを安全かつ確実に使用するためのベストプラクティスをいくつか見てみましょう。
グローバルサービスのベストプラクティスのひとつは、リカバリーパスにコントロールプレーンのアクションを入れないようにすることです。 というのも、コントロールプレーンは統計的に故障しやすいからです。
データプレーンに依存したリカバリは、より信頼性の高いパターンです。リカバリーパスを静的に安定させることができます。 このガイダンスは、ゾーナルサービスやリージョナルサービスを含むあらゆるサービスに適用することができます。
このようなガイダンスをどのように実践するか、具体的な例をいくつか見てみましょう。
Route 53 best practices
マルチリージョンのセットアップを行い、Route 53を使用して、トップレベルドメイン名として www.example.com を使用しています。そして今は east1.example.com を指しています。
リージョン障害が発生したとき、やってしまいそうなことは DNS レコードを更新することです。私が言いたいのは、こんなことをしてはいけないということです。
Route 53 ヘルスチェックを頼ってください。
Route 53 ヘルスチェックはデータプレーンの一部です。ヘルスチェックで障害を検知可能です。そのリージョンを切り離すことも可能です。
Global Accelerator best practices
Global Accelerator はトラフィックダイヤルでリージョンに転送するトラフィック量をコントールできます。このような設定を利用していると API を使ってトラフィックダイヤルを更新したくなるかもしれません。 これはやめておいた方がいいと思います。
Global Accelerator が提供するヘルスチェックを利用して、あるリージョンの障害を検知しそのリージョンを切り離すようにします。
IAM best practices
外部 IdP を利用しているケースがあります。外部 IdP に問題が起きたとします。
緊急 IAM ユーザーを作成して管理者ポリシーを割り当てるような運用をしたくなります。しかし、このようなことはしないでください。IAM コントロールプレーンに依存してしまいます。
代わりに緊急 IAM ユーザーは事前に作成しておき、認証情報を物理的または仮想的な保管庫に閉じ込めておきます。IdP に問題が発生したら保管庫から取り出し使用します。
CloudFront best practices
異なるリージョンにある2つの S3 バケットからコンテンツを配信しているケースを考えます。
一方のリージョンで障害が発生すると、ディストリビューションを更新して別のリージョンへ切り替えたくなるかもしれません。
このようなことはせず、オリジンフェイルオーバーを使用してリージョンを切り替えるようにします。
もう少し柔軟なものが必要な場合は、CloudFront Functons を使って自分がコントロールするイベントに基づいてルーティング先を動的に変更することができます。
Using AWS Health for multi-site resilience
レジリエントなアーキテクチャを構築するために AWS Health のダッシュボードを使用し、観測可能なベストプラクティスが実装できます。
アプリケーションからアラームが発せられたとき、その問題がコードに依るのか AWS リソースの問題なのかを理解することが難しい、という話をお客様から聞くことがあります。
AWS Health の主な目的の1つは、問題を根本的なインフラストラクチャの課題として迅速に解決するのを助けることです。
AWS のサービスチームは AWS Health を利用して、顧客に影響を与える可能性のある計画的または非計画的なイベントを顧客に伝えています。
イベントは AWS Health ダッシュボードに表示されます。ビジネスまたはエンタープライズサポートプランをお持ちのお客様には API も提供しています。
また、プログラムによる統合やサードパーティツールへのイベント配信は、Eventbridge を通じて実現できます。
Netflix casestudy
現在の Netflix は、マルチリージョンのアクティブ・アーキテクチャを採用しています。どのようにここに至ったかを理解するために、簡単な歴史を振り返ります。
Netflix のレジリエント物語は、2011年のカオスモンキーの登場から始まりました。 カオスモンキーの目的は、本番環境で EC2 インスタンスをランダムに終了させることで、開発者に障害を考慮した設計をさせることです。 カオスエンジニアリングという学問を生み出しました。
Netflix が 2012 年に成長するにつれ、アベイラビリティゾーン全体の機能停止をシミュレートするカオスゴリラに成長しました。 しかし、当時はまだそれぞれの地域が独立して運営されており、その判断は2012年のクリスマスイブに試されることになりました。 Netflixは6時間に及ぶ地域的な大停電を経験し、その内容はよく知られています。
私たちは、2013年末までに、マルチリージョン展開に移行し、自分たちの可用性をコントロールする必要があるという教訓を得ました。 1回のフェイルオーバーに2時間以上かかっていたリージョン全体から避難する行為とそれをサポートするツールは、2016年までにカオスコングと呼ばれるようになりました。
地域ごとのフェイルオーバーにかかる時間は45分まで短縮されました。 しかし、私たちはもっと良い方法があると考え、プロジェクト Nimble を立ち上げ、フェイルオーバーの準備時間をわずか5分まで短縮しました。
Netflixのアーキテクチャは進化し、適応してきました。指針となる原則の1つは、常にリージョンの分離を維持する必要性を考慮し、設計することでした。そして、会員に影響を与えることなくリージョンフェイルオーバーをできることです。
では、実際にどのようにすればよいのでしょうか。
私たちは主に、毎秒「Starts」と呼ばれるトップレベルのメトリックに関心を持っています。
Netflix のメンバーがコンテンツの視聴を開始するたびに、そのイベントを1つの開始イベントとしてカウントしています。これらのイベントを全地域で合計すると、1秒あたりの視聴開始回数のグローバルビューが得られます。
これらの測定基準が、私たちが想定しているベースラインから大きく逸脱している場合、私たちのチームは調査を開始するよう促されます。もし影響が1つの地域に限定されると判断された場合、フェイルオーバープロセスを開始します。
私たちのアクティブアクティブ構成では、各リージョンはインフラストラクチャの同一のコピーを実行しています。各リージョンにおいて、各サービスが他のリージョンに依存することなく必要なものを備えています。
リージョン間は会員データ (視聴履歴、ウォッチリスト、メンバー設定、ブックマークなどの全データ) のレプリケーションを維持しています。データをグローバルに複製することで、リージョン間のトラフィック移動をシームレスに実行できます。
フェイルオーバーを会員に気付かれることはありません。
どの地域でも同じインフラが稼働し、データも複製されているのでプロセスはとても簡単です。
スケールアップ、トラフィックシフト、リカバリーです。
各サービスが必要とするインスタンス数は、受信トラフィックに基づいて適切に設定するために、自動スケーリングに依存しています。
私たちが運営しているサービスの中には、起動時間が20分以上かかるものがあります。
スケーリング時間を短縮するために、Nimble というプロジェクトを立ち上げました。
Nimble は、1日中いつでも予測されるトラフィックシフトを使用して、フェイルオーバーをサポートするために必要なインスタンスを事前にプロビジョニングします。Nimble は非稼働の ASG にインスタンスを起動します。
稼働中の ASG で追加のインスタンスが必要になったら、インスタンスを Nimble ASG からデタッチして、アクティブな ASG にアタッチすることだけです。
フェイルオーバーの準備にかかる時間は、45分から5分に短縮されました。
アクティブな ASG がスケールアップされば、トラフィックをそちらへシフトできます。
トラフィックシフトは DNS に依存しています。この DNS ルーティングは、私たちのオープンコネクトインフラで行われています。
このタイムラプスは実際のフェイルオーバー中のトラフィックシフトをモニターしたものです。
右のリージョンから他の2つのリージョンへとトラフィックが移動します。
上部のグローバルなグラフなスムーズなままです。
所感
コントロールプレーン、データプレーンの違いを理解することは可用性設計において重要な要素だと理解できました。
この2つを分けて考えておかないと、いざフェイルオーバーとなった際に期待通りの動作をしない可能性があるかもしれません。
コントールプレーンはデータプレーンと比較したばあいに、障害発生率が高く、可用性を確実に実現するためにはデータプレーンへの依存度を高める設計が必要です。もちろんデータプレーンとは何かの理解もです。
グローバルサービスを採用する際にも、コントロールプレーンがどのリージョンに置かれているかを把握したうえので設計が必要です。グローバルサービスといえど機能不全に陥る可能性はあり、こちらもデータプレーンに依存した利用方法を確立しておくようにしたいものです。
AWS パート → Netflix 社事例までの流れでとても気付きが多いセッションでした。世の中の可用性設計エンジニアのみなさんにお勧めしたいセッションです。
以上、吉井 亮 がお届けしました。