グローバルテーブルを使用したリクエストルーティング
グローバルテーブルのデプロイで最も複雑な部分は、おそらくリクエストルーティングの管理です。リクエストは、まずエンドユーザーから、何らかの方法で経路が選定されたリージョンに送る必要があります。リクエストは、そのリージョンでサービスのスタックに遭遇します。これには、AWS Lambda 関数、コンテナ、または Amazon Elastic Compute Cloud (Amazon EC2) ノードでバッキングされたロードバランサーを構成要素とするコンピューティングレイヤーや、場合によっては他のサービス (別のデータベースなど) が含まれます。このコンピューティングレイヤーは DynamoDB と通信します。この通信は、そのリージョンのローカルエンドポイントを使用して行う必要があります。グローバルテーブルのデータは、参加している他のすべてのリージョンにレプリケートされ、各リージョンには DynamoDB テーブルを中心に同様のサービスのスタックがあります。
グローバルテーブルは、さまざまなリージョンの各スタックに同じデータのローカルコピーを提供します。1 つのリージョンの 1 つのスタックを対象とした設計を行い、ローカルの DynamoDB テーブルに問題が発生した場合は、セカンダリリージョンの DynamoDB エンドポイントにリモート呼び出しを行うということも考えられます。しかし、これはベストプラクティスではありません。リージョンをまたいだ場合のレイテンシーは、ローカルアクセスの場合より 100 倍も高くなる可能性があります。5 回のリクエストを往復する場合、ローカルの実行は数ミリ秒で済みますが、地球を横断する場合は数秒かかることがあります。エンドユーザーを別のリージョンにルーティングして処理することをお勧めします。レジリエンスを確保するには、マルチリージョンのレプリケーションが必要であり、データレイヤーだけでなくコンピューティングレイヤーのレプリケーションも必要です。
エンドユーザーのリクエストをリージョンにルーティングして処理するための代替手法は数多くあります。最適な選択は、書き込みモードとフェイルオーバーに関する考慮事項によって異なります。このセクションでは、クライアント主導、コンピューティングレイヤー、Route 53、Global Accelerator の 4 つのオプションについて説明します。
クライアント主導のリクエストルーティング
クライアント主導のリクエストルーティングでは、アプリケーションなどのエンドユーザークライアント、JavaScript を使用したウェブページ、または別のクライアントにより、有効なアプリケーションエンドポイントを追跡します。この場合、リテラルの DynamoDB エンドポイントではなく、Amazon API Gateway などのアプリケーションエンドポイントが対象になります。エンドユーザークライアントは、独自の組み込みロジックを使用して、どのリージョンと通信するかを選択します。この選択は、ランダムな選択、観測された最低のレイテンシー、観測された最大の帯域幅測定値、またはローカルで実行されたヘルスチェックに基づいて行うことができます。
![クライアントが選択したターゲットへの書き込みの仕組みを示す図。](images/gt-routing-is-clients-choice_v2.png)
クライアント主導のリクエストルーティングの利点は、パフォーマンスの低下に気付いた場合に、実際のパブリックインターネットのトラフィック状況などに対応して、リージョンを切り替えることができることです。クライアントは、すべての潜在的なエンドポイントを認識している必要がありますが、新しいリージョンエンドポイントの立ち上げは頻繁に起こることではありません。
任意のリージョンへの書き込みモードでは、クライアントが優先エンドポイントを一方的に選択できます。1 つのリージョンへのアクセスが損なわれた場合、クライアントは別のエンドポイントにルーティングできます。
1 つのリージョンへの書き込みモードでは、クライアントは現在アクティブなリージョンに書き込みをルーティングするメカニズムが必要になります。これは、どのリージョンが現在書き込みを受け入れているかを経験的にテストする (書き込み拒否を確認して別のリージョンにフォールバックする) という基本的なものから、グローバルコーディネーターを呼び出して現在のアプリケーションの状態をクエリするという複雑なものまであります。後者の場合は、このようなニーズに対応してグローバル状態を維持するために、Route 53 Application Recovery Controller (ARC) ルーティング制御に基づいて構築し、5 リージョンのクォーラム駆動型システムを提供するようなメカニズムとなります。クライアントは、読み取りを任意のリージョンに送って結果整合性を確保するのか、アクティブなリージョンにルーティングして強力な整合性を確保するのかを決定できます。詳細については、「Route 53 の仕組み」を参照してください。
自分のリージョンへの書き込みモードでは、クライアントは使用するデータセットのホームリージョンを決定する必要があります。例えば、クライアントがユーザーアカウントと一致し、ユーザーアカウントごとに 1 つのリージョンをホームとする場合、クライアントはグローバルログインシステムに対して適切なエンドポイントをリクエストできます。
例えば、ユーザーがウェブ経由で財務を管理できるよう支援する金融サービス会社では、自分のリージョンへの書き込みモードでグローバルテーブルを使用できます。各ユーザーは中央サービスにログインする必要があります。このサービスは、認証情報と共に、認証情報が機能するリージョンのエンドポイントを返します。認証情報の有効期間は短期です。有効期間後に、ウェブページは新しいログインを自動ネゴシエートし、ユーザーのアクティビティを新しいリージョンにリダイレクトする機会を提供します。
コンピューティングレイヤーのリクエストルーティング
コンピューティングレイヤーのリクエストルーティングでは、コンピューティングレイヤーで実行されているコードが、リクエストをローカルで処理するか、別のリージョンで実行されているそれ自体のコピーに渡すかを決定します。1 つのリージョンへの書き込みモードを使用する場合、コンピューティングレイヤーは、そのリージョンがアクティブリージョンではないことを検出すると、ローカルの読み取りオペレーションを許可する一方で、すべての書き込みオペレーションを別のリージョンに転送する場合があります。このコンピューティングレイヤーコードは、データトポロジとルーティングルールを認識する必要があります。また、どのリージョンをどのデータに対してアクティブにするかを指定する最新の設定に基づいて、これらのデータトポロジとルーティングルールを確実に適用する必要があります。リージョン内の外側のソフトウェアスタックは、読み取りリクエストと書き込みリクエストがマイクロサービスによってどのようにルーティングされるかを認識する必要はありません。堅牢な設計では、受信側リージョンが書き込みオペレーションの現在のプライマリであるかどうかを検証します。プライマリでない場合は、グローバル状態を修正する必要があることを示すエラーが生成されます。プライマリリージョンが変更中の場合、受信側リージョンが書き込みオペレーションをしばらくバッファリングすることもあります。いずれの場合も、リージョン内のコンピューティングスタックはローカルの DynamoDB エンドポイントにのみ書き込みますが、コンピューティングスタック間で相互に通信する可能性があります。
![コンピューティングレイヤーのリクエストルーティングを示す図。](images/gt-compute-layer-routing1.png)
このシナリオでは、金融サービス会社がフォローザサン型の単一プライマリモデルを使用しているとします。このルーティングプロセスにはシステムとライブラリを使用します。システム全体は、AWS の Route 53 ARC ルーティング制御と同様に、グローバル状態を維持します。グローバルテーブルを使用して、どのリージョンがプライマリリージョンで、次のプライマリの切り替えがいつ予定されているかを追跡します。すべての読み取りおよび書き込みオペレーションは、システムと連携するライブラリを経由します。このライブラリを使用すると、読み取りオペレーションを低レイテンシーでローカルに実行できます。書き込みオペレーションの場合、アプリケーションはローカルリージョンが現在のプライマリリージョンかどうかをチェックします。プライマリリージョンである場合、書き込みオペレーションは直接完了します。そうでない場合、書き込みタスクは現在のプライマリリージョンにあるライブラリに転送されます。受信側のライブラリは、自身もプライマリリージョンであると認識したことを確認します。そうでない場合は、エラーを生成します。これにより、グローバル状態の伝播が遅延します。このアプローチでは、リモート DynamoDB エンドポイントに直接書き込まないため、検証上の利点があります。
Route 53 のリクエストルーティング
Amazon Route 53 Application Recovery Controller は、ドメインネームサービス (DNS) テクノロジーです。Route 53 の場合、クライアントは既知の DNS ドメイン名を検索してエンドポイントをリクエストし、Route 53 は最も適切と思われるリージョンエンドポイントに対応する IP アドレスを返します。Route 53 には、適切なリージョンを決定するために使用するルーティングポリシーのリストがあります。Route 53 は、フェイルオーバールーティングを実行して、ヘルスチェックに失敗したリージョンからトラフィックをルーティングすることもできます。
![コンピューティングレイヤーのリクエストルーティングの図。](images/gt-rt-53-anycast_v2.png)
任意のリージョンへの書き込みモードを使用するか、バックエンドでコンピューティングレイヤーのリクエストルーティングと組み合わせることで、ネットワークに最も近いリージョン、地理的に最も近いリージョンなど、複雑な内部ルールに基づいてリージョンを返すフルアクセスを Route 53 に許可できます。
1 つのリージョンへの書き込みモードでは、(Route 53 ARC を使用して) 現在アクティブなリージョンを返すように Route 53 を設定できます。
注記
クライアントは、ドメイン名の有効期間 (TTL) 設定で指定された期間にわたって、Route 53 からの応答に含まれている IP アドレスをキャッシュします。TTL を長くすると、すべてのクライアントが新しいエンドポイントを認識するまでの目標復旧時間 (RTO) が長くなります。フェイルオーバーを使用する場合は通常 60 秒です。すべてのソフトウェアが DNS TTL の有効期限を完全に順守しているわけではありません。
自分のリージョンへの書き込みモードでは、コンピューティングレイヤーのリクエストルーティングを一緒に使用する場合を除いて、Route 53 を避けるのが最善です。
Global Accelerator のリクエストルーティング
クライアントは、AWS Global Accelerator
![Global Accelerator を使用したクライアント書き込みの仕組みを示す図。](images/gt-routing-gax-excerpt_v2.png)
任意のリージョンへの書き込みモード、またはバックエンドのコンピューティングレイヤーのリクエストルーティングと組み合わせることで、Global Accelerator はシームレスに動作します。クライアントは最も近いエッジロケーションに接続するため、どのリージョンがリクエストを受け取るか気にする必要はありません。
1 つのリージョンに書き込む場合、Global Accelerator のルーティングルールにより、現在アクティブなリージョンにリクエストを送信する必要があります。ヘルスチェックを使用すると、グローバルシステムによってアクティブなリージョンとは見なされていないリージョンの障害を人為的に報告できます。DNS と同様に、読み取りリクエストがどのリージョンからでも可能な場合は、代替の DNS ドメイン名を使用して読み取りリクエストをルーティングできます。
自分のリージョンへの書き込みモードでは、コンピューティングレイヤーのリクエストルーティングを一緒に使用する場合を除いて、Global Accelerator を避けるのが最善です。