[レポート] ARC306 Multi-Region design patterns and best practices #reinvent #reinvent2022

マルチリージョン DR 戦略を考える際のベストプラクティスを紹介します。通常のシステムをそのままマルチリージョンに展開することはほぼ不可能です。ではどうするのか?そのヒントが紹介されています。
2022.12.09

こんにちは。
ご機嫌いかがでしょうか。
"No human labor is no human error" が大好きな吉井 亮です。

セッション名 : Multi-Region design patterns and best practices

概要概要(機械翻訳) : このセッションでは、マルチリージョンデザインのトピックを深く掘り下げ、そのようなアーキテクチャを実装するためのさまざまな方法を探ります。マルチリージョンアーキテクチャをどのように考えるか、またコスト、運用、エンジニアリングの観点から何が含まれるかを検討します。また、Amazon Route 53 Application Recovery Controller、Amazon CloudFront Functions、Amazon Aurora Global Database、Amazon DynamoDB global tablesなど、マルチリージョンソリューションの構築を支援するAWSサービス機能についても学びます。

スピーカー : Neeraj Kumar, Principal Solutions Architect, Amazon web services inc
Barry Sheward, Chief Cloud Architect, Vanguard
John Formento, Principal Solutions Architect, Amazon Web Services

レポート

現在マルチリージョンを実装している人は何人いますか?そして何人がマルチリージョンを実装して RTORPO は2時間以内と言われていますか?
OK Cool Cool. ありがとうございます。
このプレゼンテーションでご覧いただくものは、このような極端なユースケースを想定したもので、他のケースにも適用できることは明らかです。
これは、私が過去6ヶ月から12ヶ月に渡り、お客様とマルチリージョンについて話し合い、その意味合いやトレードオフについての考えをまとめたフレームワークのようなものです。このフレームワークがあなたの仕事量に合っていれば、Barry Sheward 氏に Vanguard のグローバルなマルチリージョン戦略について話してもらうことにしましょう。

Understard requirements

まず第一に、要件を理解することが必要不可欠です。

顧客と話をするとき、レジリエンスやマルチリージョンについて話し合う機会があります。
「マルチリージョン・アーキテクチャーが必要だ」と聞くと私はいつも立ち止まります。
私は、すべてのアプリケーションがマルチリージョンである必要がある企業には出会ったことがないと断言します。ですから、必要なのは要件を定義することです。
ティアゼロの基準を明確にすることです。5分間のダウンタイムでどれだけの収益が失われるか、あるいは、このアプリケーションがダウンした場合、わが社に不可逆的なブランド ダメージが及ぶか、などです。
明確に定義された基準があると、自分のアプリケーションが実際に何に該当するのかがわかりやすくなります。マルチリージョンの要件に該当するか考える際に大きな違いが生まれます。技術的な判断だけでなく、コストや複雑さといった他の重要な要素もあります。

本日のセッションを通じて、マルチリージョンは必ずしも簡単なことではないということをお解りいただきたいと思います。そこにはトレードオフがあり、ビジネスと IT の間で整合性がとれていなければなりません。

Understand the data

マルチリージョンに関して最も困難なのは、データの理解です。
私たちは、ワークロードを地理的に分散して実装しています。そこで必要なのは、一貫性や可用性とトレードオフの関係になるわけですが、結局のところ、非同期レプリケーションや同期レプリケーションの許容範囲はどうなっているのか、ということになります。

このスライドは、レプリケーション技術やデータの同期方法が、アプリケーションの動作にどのような影響を与えるかを考えるきっかけになればと思い作成したものです。(実際は動画をご覧ください。4:06 あたりです)

マルチリージョンの非同期レプリケーションを考えます。

  1. クライアントはプライマリデータベースにデータを送信します。
  2. コミットされ、クライアントは確認応答を受け取ります。
  3. そのトランザクションは独立してスタンバイデータベースへレプリケートされます。トランザクションは切り離されています。
  4. プライマリ~スタンバイ間レプリケーションが何らかの理由で失敗した場合を考えてみます。
  5. クライアントはそのトランザクションを利用できる可能性があると認識しています。そして、そのトランザクションがコミットされたことを確認することになります。
  6. ここでフェイルオーバーを行うと、飛行中のレプリケーションがスタンバイデータベースに到達しない可能性が高くなります。
  7. 潜在的にすべてのデータがないときに、その領域でどのように一貫性のある状態にするのかを考えなければなりません。

では次に、マルチリージョンの同期レプリケーションについて見てみましょう。

  1. クライアントがデータベースに書き込みを行い、プライマリデータベースにコミットします。
  2. プライマリデータベースからスタンバイデータベースにレプリケートされます。
  3. そしてクライアントは確認応答を受け取ります。
  4. 非同期に比べより多くのレイテンシーが発生します。地理的に分散している場合、非同期レプリケーションに比べてアプリケーションが許容しなければならないレイテンシーが桁違いです。
  5. プライマリ~スタンバイ間レプリケーションが何らかの理由で失敗した場合を考えてみます。
  6. クライアントがトランザクションを書き込んだ場合、確認応答を受け取れません。同期レプリケーションでは両方のデータストアにコミットされる必要があるからです。
  7. トランザクションが複数にコミットされることに依存するような障害モードをどのように扱うかも考える必要があります。

Understanding the dependencies

次の基本的な3つ目は、依存関係を理解することです。

スタンバイリージョンを使いたいのであれば、まず使いたいサービスがそのリージョンで利用可能かを確認する必要があります。
もうひとつは、現在利用しているサービスに、クロスリージョンやマルチリージョンの機能があるかどうか確認することです。

次に、私が最も興味深く、お客様と話していて感じるのは、内部およびサードパーティーの依存関係を理解することに多くの時間を費やします。
例えば、サードパーティとの依存関係がある場合、最近あったのは、サードパーティとの決済処理です。 このお客様は、マルチリージョン・アーキテクチャを構築したいが、サードパーティの支払処理によるエンドポイントを1つだけ使用したいとのことでした。 このエンドポイントで何かが起こった場合アプリケーションは機能しません。ですから、本当にマルチリージョンで耐障害性を確保しようとするならば、すべての依存関係を総合的に見なければなりません。

オンプレミスの依存関係についても同じことが言えます。
ここにいらっしゃる方々の中には、ワークロードをオンプレミスに依存している方もいらっしゃるかと思います。何人かが手を挙げ、うなずいているのが見えます。
ここでよく出てくるのがレイテンシーです。マルチリージョンの話をするときに、レイテンシーが顕在化する領域は本当にたくさんあります。 私が一緒に仕事をしているほとんどの企業は、物理的に近いプライマリーリージョンを選択しています。そして、スタンバイを選ぶときは、その性質上、遠く離れているリージョンを選択することになります。
もしもスタンバイリージョンに切り替わると、レイテンシーが何桁も増加します。通常、このようなレイトエージェンシーや同期レプリケーションのレイテンシーを考慮するためには、何らかのリエンジニアリングが必要です。

サードパーティの場合も同様で、サードパーティのエンドポイントがスタンバイリージョンから遠い場所にあると、突然レイテンシーが長くなることがあります。

ですから、このようなことをよく考えて、マルチリージョンという新しい方式で依存関係がどのように作用するのか、その意味を理解する必要があります。

そして最後に、プライマリからスタンバイへの依存性を排除したいのです。
どのようにすれば、完全に独立したワークロードのスタックや分離された環境を作ることができるのか。 コードが間違えていたとしても、AWS サービスが調子悪い日だったとしても、リージョン間の依存性を排除して運用を継続することができるのかが重要なポイントで、リージョンが独立して動作することを確認する必要があります。

Failover mechanisms

フェイルオーバーの仕組みはそれ自体が一つのアーキテクチャになり得ます。
フェイルオーバーをプライマリリージョンに依存せず実行したいと考えます。
そして、完全に独立していること、必要なときにトラフィックをシフトできること、AWS にある一つのツールでフェイルオーバーをオーケストレーションできることを実現するために、ソリューションを再構築する必要があるかどうか、方法を見つけ出すことが重要です。

Route 53 Application Recovery Controller と呼ばれるサービスがあります。
5つの地域のエンドポイントを提供し、安全かつ自信を持ってプライマリー地域に依存することなくフェイルオーバーをトリガーすることができます。

Operational readiness

通常、お客様が1つのリージョンから始めて、複数のリージョンへと拡大することです。
最初のリージョンでサービスのクォータを増やしていることでしょう。セカンダリーリージョンやスタンバイリージョンで、クォータの観点から同等性を確保する必要があります。

IAMの権限についてです。
IAMはグローバルなサービスなので、リージョン間でロールを共有する場合、 もし、意図しないポリシーの変更を行った場合、両方に影響を与える可能性があります。
そのため、リージョンごとに特定の IAM の原則や役割などを作成する方法について考える必要があります。

デプロイについて考えます。
両方のリージョンに同時にデプロイすることは控えます。
リージョン間の運命の共有は最小限に抑えます。Blue-Green であれカナリアであれ、プライマリーリージョンでインフラを健全な状態にし、コードを健全な状態にし、アプリケーションがある期間、通常のトラフィックを受け付けられるようにします。そして、すべてがうまくいったら、それをセカンダリリージョンに持っていきデプロイを行います。

より高次のメトリクス、例えばユーザー・エクスペリエンス・メトリクスやユーザー・アカウント・トランザクションなどは、セカンダリリージョンにも複製します。
データレプリケーションを行っている場合は、同期遅延を把握して健全性を監視したいのです。

プロセスも重要です。
率直に言って、テストされていない DR 戦略は、DR 戦略ではありません。1年毎、1ヶ月毎、2週間毎にテストするところまで到達したいと考えています。

フェイルオーバーの範囲も考えなければなりません。マイクロサービス・アーキテクチャでは、これはより複雑になります。
いくつかのマイクロサービスが何らかの理由でフェイルオーバーしたとします。その結果、クロスリージョンの呼び出しが繰り返されます。1回の呼び出しでは重要な影響を与えないかもしれません。それが10倍、20倍となるとどうでしょう。
ある機能を構成するすべてのマイクロサービスを協調してフェイルオーバーさせ、一つのリージョンで動作させます。

フェイルオーバーの自動化だけでなく、フェイルオーバーを実行するための意思決定の枠組みを定義する必要があります。 このアプリケーションをフェイルオーバーさせるという決定を下すのは、選ばれた数人の個人であり、その決定の枠組みを明確にする必要があります。 必要なときにフェイルオーバーを実行できるように、意思決定の枠組みを明確にしておく必要があります。

複雑さについて触れたいと思います。多くのエンジニアリングの労力が必要です。
単一リージョン用に構築されたアプリケーションを、複数リージョンの環境に展開することは非常に稀です。複数の地域にデプロイするためにパイプラインを変更する必要があり、フェイルオーバーや定期的なフェイルオーバーのテストのためのプロセスが必要です。

次にコストですが、これは単なるインフラ・コスト以上のものです。
低 RPO、低 RTO のシナリオでは、インフラが短期間でトラフィックを処理できるようにするために、通常 2 倍のコストがかかります。加えて、運用努力やエンジニアリング努力も増加します。マルチリージョンに対応するための再設計やアーキテクチャーが必要になるからです。

Vanguard 社事例

Barry Sheward 氏の登壇です。

John が言ったように、最も重要なのは要件を理解することです。
私たちはユーザーエクスペリエンスを向上させたいと考えています。色々試してそれなりに役に立ちましたが、計算機とデータを顧客の近くに移動させることで得られる利点に匹敵するものはありません。

もうひとつ、私たちが求めていたのは高可用性です。ユーザーへの影響が軽微であることです。

私たちは様々なワークロードに注目し、いくつかのパターンを思いついたので、そのうちの2つを取り上げます。1つ目はハブ&スポークで、これは集中型モデルです。
米国内の集中管理された場所にいるチームがデータを毎日更新し、それらを世界中に分散させて利用します。

もう一つのパターンは、フォロー・ザ・サンです。
トレーダーは世界中に散らばっています。オーストラリアのトレーダーから始めましょう。彼らは一日の仕事の始めにやってきます。 彼らはデータへの高速な読み書きアクセスを求めています。次に英国がオンラインになり、太陽が移動するにつれて米国がオンラインになります。 彼らも同様にデータへの高速な読み取りと書き込みを希望しています。

私たちは、データについて他にも興味深いことを学びました。
一部のデータは始業時と終業時で変化しない、もうひとつは、太陽の位置によって、勤務日特有の間隔でデータが変化することが多いということです。
この2つの特定のパターンを、私たちはプライマリ・セカンダリ・パターンと呼んでいます。その理由は、プライマリとなる地域がある限り、これらのパターンは機能し、複製を作成することができるからです。

複数のリージョンに同時に書き込むこともできますが、私が夜も眠れないのは、データの衝突と一貫性です。
そこで、私たちが実際に行っているのは、マイクロサービスを使ってデータストアの周りに境界のあるコンテキストを構築し、DynamoDB のプライマリ・セカンダリパターンを強制することです。

ハブ&スポーク・モデルを使って、実際の動きを見てみましょう。

ハブまたはプライマリはアメリカです。
ピンクの線は、EU とオーストラリアにあるスポークへのレプリケーションを表しています。
小さな青い矢印は、読み取りアクセスです。
黄色い実線は、そのデータに直接アクセスできることを意味し、EUとオーストラリアでは、書き込みが必要な場合、黄色い点線のパターンに従って、ローカルのマイクロサービスに書き込みを行います。マイクロサービスは、自分たちがセカンダリであることを理解しています。
これにより書き込みの衝突が起こらないようにしています。

次のステップは、スイッチャブルハブです。
プライマリリージョンをアメリカからオーストラリアに移動しました。
これで、オーストラリアが EU とアメリカにデータをレプリケートするようになりました。 この場合、全員が高速なローカル・リード・アクセスを持っていますが、アメリカと EU がデータに書き込む必要がある場合、その権限はオーストラリアに転送されます。
DynamoDB のコンフリクトは発生しません。フェイルオーバーを計画的に行う必要はなく、マイクロサービスに「あなたがプライマリになりました」と伝えるだけでよいのです。

アメリカがダウンした際の挙動です。
アメリカリージョン上で動作するアプリケーションに、EU への読み込み、そして書き込みを行うよう仕向けます。
アメリカ内のユーザーにとっては最適なエクスペリエンスではないかもしれませんが、当社のビジネスモデルは継続可能です。

フェイルオーバーをどう扱っているかを説明します。
マルチリージョン構築の複雑さを取り除くために GOaST と呼ばれるツールを開発しました。例えば、計画外の Aurora フェイルオーバーから回復する必要がある場合、GOaST はそれを処理するツールになります。
チームが GOaST とのやりとりを考えなくて済むように GMRlib と呼ばれるライブラリを用意しました。GMRlib を通じてアプリケーションはどのリージョンがプライマリでセカンダリなのかを知ることができるのです。

テストされていない DR 戦略は DR 戦略ではありません。
私たちが望むのは常にテストを行うことであり、それを何かの標準作業手順書に組み込むことです。
私たちは1日に3回、実際にテストしているので、必要なときに確実に動くと確信しています。

例えば、あるマイクロサービスが「私はセカンダリだから、このリクエストをプライマリに転送する」と言ったときに、その受信者が「私はプライマリではない、他のものがプライマリだ」と言ったとします。 これは、システムのグローバルな状態に何らかの問題があることを示す、とても良い兆候です。
このメッセージがどこかにいってしまわないよう、我々が取り組んでいるのは、意図的に障害を注入することです。

回復力の向上から何が得られるかというと、3つの地域のうち1つ、あるいは2つがダウンしてもシステムは機能し、ユーザー体験の低下を防ぎます。

コスト面でも良いデータを提供できます。
いつも聞かれることなのですが、これは高価なソリューションです。私たちは通常、他の方法と比べて2倍のインフラを稼働させています。 しかし、ビジネスケースの観点からは、もしソリューションを持つことで一つの事故を避けることができれば、システムの寿命が尽きるまですべてペイすることができるのです。

Expanded multi-region architecture patterns

再び AWS パートです。

John はマルチリージョンを決定する前に考えなければならない重要なことを説明しました。
Barry は Vanguard 社がどのようにマルチリージョン化を進めているのか、具体的な実例を示してくれました。
このプレゼンテーションの最後のセグメントでは、少しズームアウトして、他の広範なパターンについて見ていきます。

Two micro patterns

マクロレベルでは、マルチリージョンを考える方法が2パターンあります。

  • アクティブ/パッシブ
    • すべてのユーザーがすべての読み書きトランザクションをプライマリリージョンで行う
    • プライマリリージョンで障害が発生したらセカンダリリージョンにフェイルオーバーする
  • アクティブ/アクティブ

Pattern1 アクティブ/パッシブ

ユースケースとしては、地域的なフェイルオーバー戦略、DR の一貫、事業継続のためのプロセス、規制上の必要性などが考えれます。

フェイルオーバーのトリガーや手順のためにヘルスチェックを行い、そのシグナルを受け取るモニタリングに最新の注意を払います。

リージョン横断的にワークロードを展開する場合、デプロイメント戦略について考えてみてください。
2つのリージョン間で一貫性を持つようにするにはデプロイメントパイプラインをどうするかということを考えなければなりません。

ルーティング戦略では、Route 53 の一部である Application Recovery Controller が役に立ちます。
ルーティングの観点からだけでなく、フェイルオーバーの準備が整っているかどうかのレディネス・チェックなどの機能を提供します。

スタンバイのパターンでは、セカンダリリージョンに全ての設定コード・インフラを用意し、パイロットライトを設置することができます。 実際にフェイルオーバーするときには、コンピュートリソースを立ち上げて、セカンダリリージョンにトラフィックを取り込む体制を取ります。

もう一つのパターンは、ウォームスタンバイです。セカンダリリージョンにスケールダウンした状態のコンピュートリソースを用意しておきます。

アクティブホットスタンバイはその次のステップアップで、セカンダリ領域でプライマリ領域とほぼ同じインフラとキャパシティを稼働させることになります。

パイロットライト、ウォームスタンバイ、アクティブスタンバイのどれを選択するのかは、リカバリ時間の目標に基づいて決定します。

Pattern2.1 アクティブ/アクティブ REGIONAL SHARDING

アクティブ・アクティブを行う方法は1つではありません。推し進めるための様々な方法を紹介します。

1つ目はリージョナルシャーディングで、これはユーザーをそれぞれのリージョンにマッピングさせるということです。データもアプリケーションもリージョン間を行き来することはありません。
ユーザーとそのデータをそれぞれの地域に留めておくことが、規制上必要な場合があります。
そしてもちろん、ユーザーとの距離が近いとパフォーマンスも向上します。
この場合でも、アプリケーションの体験が一貫していることを確認したいので、システムの動作やデプロイメント戦略についてよく考える必要があります。

Pattern2.2 アクティブ/アクティブ SINGLE WRITER MULTIPLE READERS

1つの Writer と複数の Reader が存在するパターンです。
ユーザーはトランザクションを書き込むために常に1つのリージョンを使いますが、読み取りは自分から近いリージョンに対して行います。
読み出しがヘビーなアプリケーションなら負荷分散に役立つかもしれません。一方で考えるべきは一貫性です。データが書き込まれた後の Reader への同期ラグに耐えられるかどうかを考える必要があります。
Writer 障害からどのように回復してどのようにフェイルオーバーするのかも重要な考慮点です。

Pattern2.3 アクティブ/アクティブ SINGLE WRITER MULTIPLE READERS (STRONG CONSISTENCY)

もう一つのバリエーションは、リージョン間の強力な一貫性を実現することです。
このパターンには少し注意が必要です。正しい理由、正しい使用例、正しい方法で行われないと、おそらく、いくつかの異なる種類の故障を引き起こす可能性があります。
特に懸念されるのはレイテンシーの問題です。同期書き込みの場合、リージョン間がどれだけ離れているかによってレイテンシーが追加されます。
このパターンで達成されるのは非常に高度な一貫性です。しかし、分断耐性についても考慮しなければなりません。

Pattern2.4 アクティブ/アクティブ DUAL WRITES

マルチリージョンで強力な一貫性を実現するもうひとつの方法として、Dual Writes という方法があります。
このケースでは、リージョン A からリージョン B に同期的な書き込みが発生するという複雑さを持っています。
さらに複雑なのはデータの原子性をめぐるロジックです。

Pattern2.5 アクティブ/アクティブ MULTIPLE WRITERS; MULIPLE READERS

最後に、マルチライター・マルチリーダーを持つことができます。
この場合、読み込みと書き込みのトラフィックを異なるリージョンに分散させます。
懸念はコンフリクトにどのように対処するかということです。
もしあなたが自分で分散システムを構築していて、書き込みトラフィックを受けられるノードが複数あるような分散システムの場合、最後の書き込みでコンフリクトが発生します。一貫性の観点からコンフリクトの解決について考えなければなりません。

Routing pattens

CloudFront で、リージョン間の複雑なルーティングやダイナミック・ルーティングを行うことができます。Lambda Edge という機能がありエッジで実行される関数です。 例えば、受信するクッキーやリクエストのヘッダーを検査することができます。 サーバーサイドのアプリケーションが返してくる HTTP コードを検査することもできます。 あなたは、特定のユーザーを異なるリージョンのアプリケーションスタックにマッピングできるでしょう。

他に役に立つサービスは Global Accelerator です。
これは我々のネットワーキング・サービスの一つで、マルチリージョン、あるいはシングルリージョンのルーティング機能があります。
Global Accelerator を使うことでレイテンシーを向上させることができます。Global Accelerator は AWS のバックボーンを通過するためトラフィックを加速できるのです。

所感

マルチリージョンでの DR 戦略、このご要望は私にも寄せられることがあります。珍しくありません。
しかし、従来のデータセンターと同じ考え方で複数のリージョンを使えるほど簡単ではありません。
まず DR 要件を細かく精査し本当にマルチリージョンでの DR が必要なのか、そしてコストに見合うのかを熟慮しなければなりません。
本当にマルチリージョンが必要になった場合は、このセッションで紹介されているようにデータの取り扱いが肝になります。様々なパターンが紹介されました。どのパターンが自分たちのシステムに合致しているかは難しい問題です。
そして、オンプレミスまたはシングルリージョンで動くアプリケーションをそのままマルチリージョンに当てはめることはできません。マルチリージョンでの DR を取り入れる際にはマルチリージョンに適合したアプリケーションを作り直すことになる可能性を考慮してもらればと思います。

以上、吉井 亮 がお届けしました。