re:Invent 2023: AWSのBuy with Primeチームが語るマルチテナントSaaS運用術
はじめに
海外の様々な講演を日本語記事に書き起こすことで、隠れた良質な情報をもっと身近なものに。そんなコンセプトで進める本企画で今回取り上げるプレゼンテーションはこちら!
📖 AWS re:Invent 2023 - SaaS operations in action: Buy with Prime (BWP301)
この動画では、Buy with Primeチームが実践するマルチテナントサービスの運用ベストプラクティスを紹介します。テナント分離の自動検証やAWS CDKを活用した可観測性の向上など、具体的な手法を解説。50年分のエンジニアリング工数を節約した秘訣や、Prime Big Deal Dayで10倍の注文数を処理した実績も明かされます。AWSのSolutions ArchitectだったJiwon YeomとJimin Kimが、内部の知見を惜しみなく共有する貴重なセッションです。
※ 動画から自動生成した記事になります。誤字脱字や誤った内容が記載される可能性がありますので、正確な情報は動画本編をご覧ください。本編
Buy with Primeの概要とセッションの導入
みなさん、こんにちは。本日は、セッションBWP301「Buy with Primeのためのサービス運用実践」にご参加いただき、ありがとうございます。今日は、Buy with Primeチームがマルチテナントサービスの運用で学んだベストプラクティスをご紹介し、プレゼンテーションの最後には、皆さんが始められるようにサンプルコードもお見せします。私はBuy with PrimeのPrincipal EngineerのDavid Ramosです。本日は素晴らしい共同発表者として、 AWSのSenior Solutions ArchitectのJiwon Yeomさんと、Buy with PrimeのSolutions ArchitectのJimin Kimさんをお迎えしています。
始める前に簡単な自己紹介をさせていただきますと、私はAmazonに11年以上勤務しています。その大半は機械学習に焦点を当てたプロジェクトに携わってきました。Fire Phone、Alexa、Audible、そして最近ではBuy with Primeに携わってきました。Buy with Primeチームに加わったのは、その技術的ビジョンに感銘を受けたからです。マルチテナントサービスとコンポーザビリティへのアプローチは、興味深いユースケースを可能にすると同時に、スケールアップを学ぶ上でユニークな課題をもたらします。そしてもちろん、私自身がPrimeメンバーなので、あらゆる場所でPrimeを利用するのが大好きです。
本日は、まずBuy with Primeの概要と、アーキテクチャとマルチテナンシーについて簡単に説明します。その後、Jiwonが登壇し、顧客リソースのテナントごとの分離を確実に実施するために使用している継続的なメカニズムについて説明します。次に、JiminがBuy with Primeチームが使用しているメトリクスについて話し、紹介した様々な手法をまとめます。最後に質疑応答の時間を設けています。そして、新米パパとしての義務を果たすために、赤ちゃんの写真もお見せしますよ。
Buy with Primeのアーキテクチャとマルチテナンシー
では、始めましょう。Buy with Primeは、何百万人ものPrimeメンバーが、Amazonで期待される信頼できる体験を持って、直接商人のオンラインストアで買い物ができるようにするサービスです。これには、迅速な無料配送、シームレスな決済体験、簡単な返品が含まれます。 Buy with Primeは現在、米国を拠点とする商人向けに利用可能で、皆さんの中にはすでにお気に入りの店舗でBuy with Primeボタンを見たことがある方もいるかもしれません。商人は、Buy with Primeウィジェットを取得するためのJavaScriptコードスニペットをインストールするか、Shopify商人の場合はShopify用のBuy with Primeアプリをインストールすることで、Buy with Primeを直接ウェブサイトに統合できます。
また、増え続けるAPIとリアルタイムイベントサブスクリプションも提供しています。私たちは顧客のいる場所で対応し、採用を促進するためにインターフェースをできるだけ柔軟にしたいと考えています。Buy with Primeは商人とその顧客の双方にとってWin-Winです。 私のようなPrimeメンバーは、Primeの買い物特典と馴染みのある決済方法を楽しむことができ、一方で商人は顧客との関係を育み、ブランドロイヤリティを構築できます。これまでのところ、Buy with Primeは平均で25%の購入者コンバージョン率の向上を示しています。このデータポイントは、Buy with Primeでの購入オプションが利用可能だった場合と、同じ期間中にボタンが表示されなかった場合とを比較して、注文を行った購入者の平均増加率を測定したものです。
昨年4月のローンチ以来、私たちは顧客と共に初めてのPrime Dayイベントを開催しました。全体として、Prime Dayの活動に参加した出店者は、Prime Day発表前の月と比較して、イベント期間中の1日あたりのBuy with Prime注文数が10倍に増加し、注文からの1日あたりの収益が8倍に増加しました。では次に、実際にどのようにしてお客様にサービスを提供しているかに焦点を当てましょう。私たちのサービスはすべてマルチテナントです。 つまり、1つのサービスが多くの異なる利用インスタンスをサポートしています。テナントリソースの分離を確実にすることは、私たちにとってオプションではありません。これは出店者と顧客の信頼を得るために不可欠なのです。
そういうわけで、Buy with Primeのアーキテクチャについて簡単に概要を説明させていただきます。 これは、プレゼンテーションの主要トピックであるマルチテナントデータ分離と可観測性の文脈を設定するためです。より詳しく知りたい方は、右上のQRコードを使って昨年のre:Inventセッションをご覧ください。そちらではもう少し深く掘り下げています。Buy with Primeは、開発者の同時性と効率性を実現するためにマイクロサービスアーキテクチャパターンを採用しています。これにより、サービスチーム間で独立して新機能を迅速に反復できます。先ほど述べたように、私たちは出店者がフロントエンド機能とバックエンドAPIの両方と統合できるようにしています。つまり、出店者はBuy with Primeウィジェットをそのまま使用することも、それらのエクスペリエンスを支える同じデータAPIに直接オンボーディングすることもできます。これにより、私たちと出店者の両方が、ショッパーエクスペリエンスの新しいイノベーションを実験できるのです。
マイクロサービスとテナントIDの管理
ここでマルチテナンシーの最初の側面として言及したいのは、各サービスが独自のAWSアカウントを管理し、それぞれのAWSアカウントが複数の出店者リソースを管理しているということです。この基数により、サービスチームは独立して運用できると同時に、一貫したデータ処理、セキュリティ、構成を強制することができ、ログ記録、計測、その他の分析などの側面も簡素化できます。後ほどJiminが、これらのアカウント間でテナントリソースの可視性を得る方法について詳しく説明します。これにより、単一のマイクロサービスまたは特定のテナントに固有のトレンドを特定し、問題をデバッグすることができます。
しかし、私たちのマイクロサービスは完全に孤立して開発されているわけではありません。 テナントリソースの管理を支援するために、いくつかの共通のデータ処理および通信標準を強制しています。これらの共通標準の1つがテナントIDです。これは、Buy with Primeのすべてのサービスで個々のテナントのリソースに関連するあらゆるアクティビティに付随する一意の識別子です。出店者がBuy with Primeにオンボーディングする際、私たちはAWS CloudFormationを活用して、その統合のためにすべてのマイクロサービスにわたる関連リソースを合成します。また、カスタムリソースとしてテナントIDを生成し、それらのサービスに伝播させます。これにより、関連するリクエストやデータ要素にタグを付けることができます。
これらはほとんどの場合、舞台裏で行われます。出店者は、APIと統合する際にのみテナントIDを意識する必要があります。これにより、関連するリソースを操作できるようになります。 このようにして、各マイクロサービスが各出店者のリソースとそれらの出店者のテナントIDを持つことで、一時的なIAM AssumeRoleセッションを通じて各テナントのリソースへのきめ細かなアクセスを可能にするためのすべての要素が整います。 私たちのアイデンティティサービスによって支えられる各サービスは、リクエストが関連するテナントIDに適切にスコープされたデータにのみアクセスすることを強制できます。
さて、これは私たちのアーキテクチャの側面についてのごく簡単な概要でした。昨年のre:Inventセッションのより詳細な内容へのQRコードを表示しました。もちろん、プレゼンテーション後にはどんな質問にもお答えします。では、Jiwonを壇上にお招きします。
AWSソリューションアーキテクトの視点からのBuy with Prime
ありがとうございます。Davidさん、ご紹介ありがとうございます。皆さん、こんにちは。AWSのSolutions ArchitectのJiwon Yeomです。本日、ラスベガス時間の午後4時にこの場に皆さんとご一緒できて大変嬉しく思います。ご来場いただき、ありがとうございます。皆さんと一緒に楽しい時間を過ごせるよう努めます。 DavidがBuy with Primeの内部動作と私たちのサービスについて少し説明しましたが、ここで少し視点を変えて、皆さんがなぜここにいらっしゃったのかを考えてみたいと思います。Buy with Primeの経験と事例から学び、これらのプラクティスを自分たちの環境にどう活かせるかを知ることが目的ですよね。
このプレゼンテーションを行うことにした理由をお話ししたいと思います。私は最初にAWSに入社し、その後Buy with Primeに移り、そしてAWSに戻ってお客様とお会いすることにしました。Buy with Primeに来た当初、正直なところ驚きの連続でした。なぜなら、AWSのSolutions Architectがお客様に推奨している最善のプラクティスを、彼らが美しく洗練された方法で実践していたからです。私は「これは絶対にお客様にもっと話すべきことだ」と思いました。Amazonのチームが実際にどのように実践しているのか、そしてこれが他のアーキテクトや開発者の皆さんにとってどれほど有益なものかを示せると考えたのです。これが今回のプレゼンテーションの趣旨です。私たちの理念は、この会場を後にする方が一人もいないようにすることです。いくつかの素晴らしい例をご用意しました。皆さんと共有できることを楽しみにしています。
Operational Excellenceとマルチテナントサービスの課題
しかし、その前に、AWSのアーキテクティングフレームワークにおけるOperational Excellenceについて少し思い出していただきたいと思います。これは基本的に、過度の運用上のオーバーヘッドなしに、ビジネス要件を効率的に満たすようにワークロードを運用し、設計することについてです。ここにあるアイコンの一つ一つについて詳しく説明するつもりはありません。これについては素晴らしいプレゼンテーションがありますので、そちらをご覧ください。むしろ、私たちがパイプラインにとって非常に重要だと考えるいくつかのポイントに注目していただきたいと思います。それは、タスクを自動化し、
プロセスを継続的に改善することです。これにより、失敗から学び、同じ問題を繰り返さないようにすることができます。2022年4月にサービスを開始したばかりの若いビジネスであるため、基本的に毎日新しいビジネスクリティカルな機能をリリースする必要があります。私たちは本質的に加盟店のインフラストラクチャーであるため、絶対的な耐障害性を持つべきです。そして、他のAmazonサービスと同様に、セキュリティをJob Zeroとして扱いながら、これらすべてを実行する必要があります。
私たちはSoftware as a Serviceプロバイダーであるため、これにはさらなる複雑さが加わります。すべてのテナントにわたって何が起こっているかを把握し、すべての加盟店に私たちが提供したい品質を確実に体験してもらう必要があります。また、彼らの利用パターンを把握し、その利用状況に基づいて体験を最適化できる方法がないか見つけ出すべきです。これらは、一般的なAWSワークロードに対する通常の運用の卓越性に加えて、私たちが気にかけるべきことです。
これらをすべて一つの図にまとめると、正直なところ、かなりの量になります。そこで、Buy with Primeがこれらの運用の卓越性の実践について持っている、理解しやすい2つのバージョンをご紹介したいと思います。コードによる運用の実行については、開発者が毎日新機能をロールアウトできるようにする一方で、 堅牢なテナント分離境界を維持するために、このテナント分離の検証をパイプラインに組み込みました。これが最初に深く掘り下げるトピックになります。
2つ目は、先ほどDavidが言ったように、私たちは大規模なマイクロサービスショップであり、複数の異なるエンジニアリングチームが異なるマイクロサービスを管理しています。もちろん、異なるAWSアカウントで行っています。そのため、異なるチーム間で同じレベルのメトリクス、ログ、そしてこれらの観測可能性に関するものをすべて非常に標準化された方法で持つことは少し課題がありました。私たちは、これをスマートな方法で標準化する方法を見つける必要があり、AWS CDK(Cloud Development Kit)を使用してこれを実現しました。
テナント分離の自動検証プロセス
一歩下がってこれら2つの原則を見ると、すべては1つのことに集約されます:自信です。私たちのエンジニアリングチームが素晴らしいものを作り上げたことは分かっていますが、テナンシー層があることで多くのことが複雑になっているため、顧客のために全チームにわたって同じ統一された高い基準を設定していることを本当に確認したいのです。 そのため、これについてより深く掘り下げることにワクワクしています。それでは、このテナント分離を自動的に検証する部分に入っていきましょう。
これはパイプラインの一部として行われるので、パイプラインの個々のステップを簡単に説明したいと思います。AmazonのCI/CDのベストプラクティスに馴染みがある方なら、これはかなり似たものに見えるでしょう。ここで最初に起こるのはソースのチェックインです。 例えば、あなたにアプリケーションがあるとします。このアプリケーションを動作させるには、多くのものが協調して機能する必要があります。アプリケーションソース、運用ソース、ツールソース、Infrastructure as Code、そしてこれらすべての依存パッケージがあります。これらのいずれかに変更があると、パイプラインが起動します。
その後、ビルドフェーズに進み、コンパイル、ユニットテスト、静的解析など、楽しいビルド作業をすべて行います。 これらのビルドアクションがすべて成功すると、プリプロダクション環境に移ります。 Buy with Primeのプリプロダクション環境には、Alpha、Beta、Gammaの3つのステージがあります。AlphaとBetaでは、主に最新のコードが期待通りに機能しているかを検証します。Gammaでは、これらの検証に加えて、より本番環境に近い状態にします。本番環境に近いとは、本番と同じデプロイ設定を使用し、Primeの本番環境と同じモニタリングとアラームを設定することを意味します。また、本番環境で行っているのと同じ継続的な合成テストも実施します。Alpha、Beta、Gamma全体で、さまざまな統合テストを実行します。モックに関する想定を検証し、期待通りに動作することを確認し、自動ロールバックのウィンドウに組み込みます。これらのタスクが事前に定義された時間枠内で失敗した場合、自動的に前のバージョンに戻ります。ソフトウェアエンジニアとして、定義された時間枠内ですべてが実行されるようにする必要があります。
今回の主役である自動化されたテナント分離検証は、さまざまなプリプロダクション環境での統合テストの一環として行われます。 これらの統合テストがすべて成功すると、最後にOneBoxステージに進みます。ここでは、この新しいソースが後方互換性を持つこと、つまり既存のソースと並行してデプロイできることを確認します。例えば、新しいソースが現在のコードで解析できない形式でデータを書き込んでいないことを確認する必要があります。そうでないと、システム全体が破綻してしまいます。
ここで行うのは、新しいソースをフリート全体の小さなサブセットにデプロイすることです。これは1台の仮想マシン、1つのコンテナ、あるいはLambda呼び出しの小さな割合かもしれません。これを並行して設置し、一定の時間枠(例えば1時間)、有機的にトラフィックを消費させます。合成テストを実行し、成功した結果とモニタリングメトリクスを確認します。これにより、この新しいソースが副作用を引き起こしたり、以前のバージョンに影響を与えたりしていないことがわかります。このOneBoxステージが完了すると、ついに本番環境に到達し、新機能がリリースされます。
この厳密な検証プロセス全体を通じて、 テナント分離検証をその一部として追加することにしました。ここで「パイプラインの仕組みはわかったけど、このテナント分離が自動的にどのように機能するの?」と思われるかもしれません。この部分についてもう少し深く掘り下げてみましょう。この概念は少し馴染みがないかもしれませんが、これらの作業を行う方法は必ずしもロケット科学ではありません。
Buy with Primeの目的別ダッシュボードと可用性トラッカー
まず、ここにある設計ベクトルについて説明しましょう。Davidが紹介したように、マイクロサービスにはコントロールプレーンとデータプレーンがあります。コントロールプレーンにはテナントのメタデータが保存され、実際の重要なビジネスデータはデータプレーンのデータベースに保存されます。この2つのデータベースの次元があり、認可された人だけが自分のデータにアクセスできるようにするために、2つの境界を利用しています:AWS account IDとtenant IDです。これら2つをIAM AssumeRoleセッションのメタデータの一部として使用し、個々のシナリオに基づいて期待される結果が得られるようにしています。
これらのIAMロールを使用すると、実際のプロセスは簡単です。このセキュリティ統合テスト、つまり分離検証の部分が行われると、Test Runnerがインスタンス化されます。インスタンス化されると、最初のIAMロールを引き受けます。 許可リストに載っているAWSアカウントと載っていないAWSアカウントがあるので、許可リストに載っていないAWSアカウントから始めますが、特定のユーザー(例えばJiwon)を名乗り、Jiwonのデータを要求します。
この場合、Buy with Primeのマイクロサービスエンドポイントがあり、正当な加盟店のデータにアクセスしようとする可能性があるようなものです。 もちろん、セキュリティ上の理由からこれは失敗するはずで、私たちのマイクロサービスはどのAWSアカウントを許可または拒否すべきかを十分に理解しています。
これにより、アクセス拒否を示す400エラーが発生し、次の許可リストに載っているAWSアカウントでtenant IDが一致しないケースに進みます。 そこで、作成、読み取り、更新、削除を行い、これらすべてがカバーされていることを確認します。2番目のケースでは、私がなんらかの方法でBuy with Primeのマイクロサービスにハッキングしたとして、Jiwonのデータだけでは満足せず、Davidのデータも欲しいと考えるようなものです。JiwonのIDを持っていると主張しながら、Davidのデータを要求するわけですが、これも当然失敗し、同じ400エラーコードでアクセス拒否例外が発生するはずです。
最後に、許可リストに載っているAWSアカウントでtenant IDが一致する場合、正常なケースとなります。これはおそらくBuy with Primeが承認した正当なパスを通じてきているからです。これらはかなり単純明快ですよね?要するに、これらのテナントの活動について想定できるすべてのケースについて、より綿密に考えることが大切なのです。ここで、このTest Runner部分について3つの重要な考慮点をお話ししたいと思います。
まず、自分のテナント分離境界を把握し、それらを確実にIAMロールに組み込むことが重要です。私たちの場合はAWSアカウントとテナントIDでしたが、あなたの場合はVPC、ECSクラスター、EKSクラスターなど、選択した境界が何であれ、それらをIAMロールポリシーのリソースまたは条件として必ず組み込む必要があります。次に重要なのはデータの次元です。私たちの場合は単にコントロールプレーンとデータプレーンでしたが、もし複数の異なるAWSデータベースをサポートする必要がある場合は、それらのデータソースや異なるデータの次元、テーブル、そしてアプリケーションが実行できるすべての操作をカバーしていることを確認する必要があります。そして、ポジティブケースとネガティブケースのすべてのコーナーケースをカバーしていることを確認してください。
しかし、言うは易く行うは難しです。そして、このプレゼンテーションで最後に望むのは、皆さんに何も持ち帰らずに帰っていただくことではありません。そこで、私が説明したTest Runnerの非常にシンプルな実装をまとめました。右上のQRコードをスキャンすると、テストフレームワークだけを含むGitHubリポジトリに移動します。これは、提供されたIAMロールを引き受け、指定されたDynamoDBテーブルに対してCreate、Read、Update、Delete操作を試みるという非常にシンプルなものです。これによって、適切な出発点を提供したいと考えています。
これをオフィスに持ち帰り、実際に使用しているIAMロールに拡張し、EKSクラスターオプション、VPCオプションなどをこのIAMロールセクションの一部として組み込んでください。また、Secrets Managerや他のAWSデータベースを使用している場合は、サンプルリポジトリと同様に、DynamoDB以外の他のデータや他のAPIにも拡張する必要があります。テストしたい項目を決めたら、次にすべきことはそれをパイプラインに組み込むことです。
例えば、このようなAWS CodePipelineがあるとします。ビルドフェーズが完了し、開発環境に新しいバージョンのソースがデプロイされたら、AWS CodeBuildをTest Runnerとして使用してテストを実行できます。結果はAmazon S3バケットに保存され、レビュアーとしてあなたは承認を行い、分離部分が安全であることを確認し、次のプリプロダクション環境や本番環境に進むことができます。これにより、分離境界に対する信頼性を高めるためのツールが提供されることを願っています。そして、もう一度このQRコードを共有したいと思います。フィードバック、質問、直面している問題などを自由に共有してください。私たちは皆さんの声に耳を傾け、できる限りサポートしたいと思います。以上で、Jiminをステージに招き、Buy with Primeの最も重要な課題の1つである可観測性とその取り組みについて説明してもらいます。ありがとうございました、Jiwon。
CDKを活用したモニタリングの標準化
後半では、SaaSにおける可観測性について話します。Buy with Primeに参加する前は、Jiwonと同様に3年半ほどAWS SAとして働いていました。主にスタートアップやISVのお客様をサポートしており、その多くがSaaSプロバイダーでした。ここにSaaS企業の方はいらっしゃいますか? 素晴らしい。そしてエンジニアの方は? 素晴らしい。今日のコンテンツに共感していただけると思います。
よく寄せられる質問の1つは、どのようなメトリクスを監視すべきか、そしてどのような監視ツールをお勧めするかというものでした。このセッションでは、私たちが監視しているメトリクスと使用しているツールについてお話しますが、皆さんのものとは異なるかもしれません。私たちの選択の背後にある理由と、得られるメリットを強調したいと思います。まずは、observabilityの課題について考えてみましょう。 Buy with Primeは2022年の立ち上げ以来急速に成長し、より多くのリソース、サーバー、データベースを持つようになり、結果として監視すべきメトリクスも増えました。ビジネスの観点から重要なものの明確なベースラインを確立しないと、測定可能なすべてのメトリクスに同等の重みを置いてしまい、アラーム疲れを引き起こすことがよくあります。
マイクロサービスの性質上、observabilityの確保はより複雑になります。すべての依存関係を追跡し、AWS accountsにまたがる可視性を維持する必要があります。マルチテナンシーもさらに複雑さを加えます。では、Buy with Primeはこれらの課題にどのように対処しているのでしょうか? まず、目的に特化したダッシュボードを活用しています。特定のニーズに合わせて作られたダッシュボードにより、重要な問題に集中し、サービスの状態を素早く理解することができます。次に、AWS CDKを使用してobservabilityの設定を標準化しています。各マイクロサービスは異なるチームによって管理されているため、設定の一貫性を保つのは難しい課題です。
私たちが持っている目的別ダッシュボードのいくつかを見てみましょう。ここで最初に紹介する例は、可用性、レイテンシー、トラフィックに焦点を当てた重要システムの健全性サマリーです。これは一般的なダッシュボード形式で、皆さんの多くも似たようなものをお持ちだと思います。これをどのように活用しているかをお見せしましょう。私たちは定期的な運用メトリクス検討会議を開催していますが、Buy with Primeに異動した当初、その大規模で多様なグループに驚きました。技術者だけが参加すると思っていましたが、実際には、VPや技術部門のディレクター、さらには営業部門のディレクター、すべてのエンジニアリングチーム、マネージャー、エンジニアが参加しています。
大規模なグループなので、多くの時間を投資しています。そのため、重要な運用プラクティスに焦点を当てており、その1つがこのダッシュボードのレビューです。これにより、短時間で様々なステークホルダー間で主要なイベントや重要なサービスの状態について共通理解を促進できます。適切に設計されたダッシュボードを定義するだけでは十分ではありません。定期的にそれらを訪れ、レビューする習慣を持つことが重要です。
例えば、過去2日間にトラフィックのピークがありましたが、これは実際10月10日から11日のPrime Big Deal Dayによるものだったので、問題ではありませんでした。しかし、このような場合、何が原因で、どのような影響があったのか、理想的には取った行動について答えられることが期待されます。 次に紹介したいダッシュボードは、可用性トラッカーです。利用可能であることは、サービスの最低限のベースラインです。利用できなければ、誰も使うことができません。そこで、私たちが持つすべてのマイクロサービスをリストアップしました。ここでは4つだけ示していますが、もちろんもっとたくさんあります。
各行は、可用性の目標と、過去7日間、14日間、30日間、そして最大90日間の計算された可用性を示しています。計算された可用性と言うのは、特定の式を使用して決定しているからです。 詳しく見ていきましょう。uptimeについて聞いたことがあるかもしれません。通常、uptimeは稼働時間の総稼働時間に対する比率として計算されます。 一般的に年単位や月単位で行われますが、私たちは顧客の実際の体験により密接に関連しているため、リクエスト数を使用して可用性を計算しています。これはどういう意味でしょうか?
固定の時間枠で可用性を測定すると、真夜中の5分間の中断は、Black FridayやPrime Big Deal Dayのようなピークプロモーション時間帯の中断と技術的には同じになります。しかし、実際の影響は同じではありません。そのため、私たちはリクエスト数を使用して可用性を計算しています。では、なぜ400エラーを除外するのでしょうか?クライアント側の問題を示す重要な指標ではないのでしょうか?その通りですが、時として計算を大きく歪める可能性があるのです。
モニタリングCDKの構成要素とメトリクス
このシナリオを考えてみてください:もし私たちのシステムがDDoS攻撃を受けた場合、多くのリクエストが400エラーになるでしょう。つまり、404(not found)、403(forbidden)、または429(too many requests)エラーが発生します。すべての400エラーを含めると、可用性が歪められ、実際よりも可用性が高く見えてしまいます。そのため、私たちはそれらを除外しています。 一方で、500エラーは分子に入れています。これは明らかに私たちのシステムがサービスを提供できなかった箇所を示しています。
Buy with Primeのどこでも同じアプローチが適用されており、shopper checkoutの可用性も例外ではありません。私たちは購入者の体験を非常に重視しているため、彼らのための専用ダッシュボードを用意しています。週単位と30日単位の両方で集計されたグラフを見ています。Shopper checkoutは単一のワークフローのように見えますが、舞台裏では多くの異なるマイクロサービスからのAPIが関与しています。そのため、私たちは内訳ビューも一緒に持っています。これらのAPIのいずれかが失敗すると、購入者はチェックアウトを完了できなくなります。
内訳ダッシュボードをクリックすると、すべてのAPIの完全なリストが表示され、その下に可用性低下のトップ3が表示されます。これらのトップ3のAPIは、実際に指定された期間で最も大きな可用性の低下を示しています。これにより、特定のマイクロサービス内のどのAPIが利用不可能だったか、そしてそれが集計された可用性にどのように影響したかを特定できます。先ほど見たように、Buy with Primeの監視期間は通常、週単位から30日間にわたります。
短期間の観測は新たなトレンドを発見し、問題に迅速に対処するのに役立ちます。一方で、同じ指標に対してなぜ長期的な観測期間も設けているのでしょうか?一部の変化はとてもゆっくりと進行するため、短期的な視点では見えない可能性があります。そのため、長期的な観測期間を組み合わせることで、将来起こりうる問題を防ぐための簡単な解決策となります。
ショッパーのチェックアウト体験に話を戻しましょう。私たちが注目するもう一つの重要な指標はレイテンシーです。高いレイテンシーはショッパーの満足度に直接影響を与えるだけでなく、APIリクエストのタイムアウトを引き起こす可能性があるため、可用性にも影響します。ショッパーの視点からチェックアウト体験を評価するために、私たちはチェックアウトの過程を3つの個別のステップに分け、それぞれの所要時間をミリ秒単位で測定しています。
まず、ショッパーがBuy with Primeボタンをクリックすると、Amazonアカウントへのログインを求められます。ここでは、ショッパーがログインページに到達するまでの時間を測定します。次のステップでは、ショッパーがAmazonアカウントにログインした後、配送先住所を取得して配送予定日を計算し、支払い情報を連携する必要があります。ここでは、これらの情報を全て取得してチェックアウトページを生成するまでの時間を測定します。
ショッパーが確認を完了し、注文確定ボタンをクリックすると、Buy with Primeは支払いを完了し、ショッパーを注文確認ページにリダイレクトするまでのレイテンシーの追跡を開始します。ショッパーのチェックアウト過程をより小さな単位に分解することで、途中で発生する特定の問題を正確に特定することができます。私たちは個々のステップのレイテンシーをP50とP99の両方で監視するための専用ダッシュボードを用意しており、それぞれに特定の目標値を設定しています。
P50とP99パーセンタイルは、ユーザーのレイテンシー体験を大まかに測定するための一般的なアプローチです。P50は応答時間の中央値を表し、半数のユーザーがそれより速い応答時間を、残りの半数がそれより遅い応答時間を経験していることを意味します。一方、P99は99%のユーザーが経験する応答時間を表し、少数ではあるものの重要な割合のユーザーに影響を与える極端なケースを特定し、対処するのに役立ちます。
これまで、Buy with Primeの目的に特化したダッシュボードをいくつか見てきました。それには、ハイレベルな概要、特定の技術的パフォーマンス、そしてユーザー体験が含まれています。そこで使用されるデータ、例えば可用性やレイテンシーなどは、サービスを所有する各マイクロサービスチームから提供されます。彼らがこのデータを持っているのは自然なことです。なぜなら、サービスを効率的に管理するためにそれが必要だからです。しかし、すべての異なるチームが同じ原則に従っていることを確信できるでしょうか?例えば、彼らが同じ可用性の計算方法を使用しているか、あるいは欠落している指標がないかを知っているでしょうか?
ここで、CDKの出番となります。私たちは、Buy with Prime用のCDKを定義し、ベストプラクティスに従ったAWSリソースをスピンアップできるようにしました。異なるサービスの私たちのエンジニアたちは、Buy with Primeのための共通のベストプラクティスセットを協力して作成しました。このCDKにより、現在すべての異なるチームが使用する中央リポジトリを作成できます。これにより、50年分のエンジニアリング工数を節約しています。はい、その通りです - 5-0年分のエンジニアリング工数です。これは膨大な量です。「Consider Your Construct」というタイトルの別のセッションでは、Buy with PrimeがスケーラブルなアーキテクチャのためにCDKをどのように活用しているかを取り上げています。今日のセッションでは、特にモニタリングCDKに焦点を当てています。これはBuy with Prime CDKのサブセットです。
モニタリングCDKは、ダッシュボード、メトリクス、アラーム、ロギングの4つの部分で構成されています。これから、これらのコンポーネントがモニタリングコンストラクト内でどのように統合されているかのイメージを掴んでいただくために、いくつかのCDKコードスニペットをデモンストレーションしていきます。ちなみに、JiwonとI私は、モニタリングCDKの簡略版をオープンソースとしてリリースしましたので、後ほど詳しく紹介します。モニタリングすべき基本的なメトリクスがいくつかあります。例えば、Elastic Load BalancingとAmazon API Gatewayでは、HTTP 400エラーと500エラーを収集することが推奨されています。コンピューティングに関しては、Amazon ECS、AWS Fargate、AWS LambdaのCPUとメモリ使用率がモニタリングされます。Lambdaには、呼び出し、コールドスタート時間、最大メモリ使用量など、いくつかの固有のメトリクスが必要です。
Log InsightとContributor Insightの活用
では、これらのメトリクスがモニタリングCDKにどのように組み込まれているかを見てみましょう。ここでAPI Gatewayの例を挙げます。パーセンタイルを使用してレイテンシーを測定することを覚えておいてください。ここではP50、P90、P99のレイテンシーと統合レイテンシーとして表されています。明確にしておくと、統合レイテンシーはAPI Gatewayとアップストリームサーバー間のレイテンシーであり、一方でレイテンシーはこの統合レイテンシーと他のAPI Gatewayのオーバーヘッドを含んでいるので、全体の応答時間を表します。私たちは可用性もモニタリングしています。はい、これはAPI Gatewayのネイティブなメトリクスではありません。先ほど議論した式を使用して計算されるカスタムメトリクスです。そのためには、リクエスト数と400および500エラーの数が必要で、これらはCDKによってまとめて収集されます。
メトリクスはCDKの内部で事前に定義されているため、必要なすべてのデータが一貫した方法で収集され測定されることを強制できます。ここでは、API Gatewayのメトリクスがインターフェースとしてエクスポートされ、それによってダッシュボードやアラームなどの上位レベルで消費できるようになっています。ここでアラームがどのように設定されているかを見てみましょう。メトリクスにはしきい値があり、アラームはそれに基づいているので、CDKの観点からはほぼ同じように見えます。しかし、アラームで何をするのでしょうか?観測性の課題の1つとして言及したアラーム疲れを覚えていますか?これを軽減するために、まずアラームを重大度に基づいて明確に分類し、エンジニアからの即時の対応が必要かどうかを判断します。
アラームが即時対応を必要とする場合、私たちはできる限り CDK を使用して運用プラクティスを自動化しています。私たちの運用では CDK を広範囲に活用しています。例えば、CDK は自動的にチケットシステムにチケットを作成し、エンジニアにアサインします。そして、指定された時間内に問題が解決されない場合、重要度が上がりエスカレーションが必要になります。マネージャーレベルのエスカレーションも CDK で定義されており、完全に自動化されています。CDK によって作成されるサポートチケットには、アラーム、ログ、確認すべきダッシュボード、そして運用手順書に関するすべての詳細が含まれています。手順書には具体的な対応手順が記載されており、最初のステップはアラームがまだアクティブかどうか、そして実際に顧客への影響があるかどうかを確認することです。
調査のために、2つの強力なツールを紹介したいと思います: Log Insight と Contributor Insight です。これらが CDK にどのように組み込まれているか見てみましょう。こちらはアプリケーションログ用の簡単な Log Insight クエリです。ログタイプがエラーとラベル付けされたログエントリをフィルタリングし、結果をタイムスタンプの降順でソートし、100エントリに制限して、ログストリームとログメッセージを表示します。このクエリはタイムスタンプ付きのアプリケーションエラーログをフィルタリングし、時間範囲を絞り込んで調査を続けることができます。これはマイクロサービスの種類に関係なく、一般的なアプローチです。
AWS Console で Log Insight クエリを作成するのは難しくありませんが、このようなクエリはどのチームでも使用できます。私たちはこれらを CDK に組み込んで、エンジニアの手作業を排除しています。これが、50エンジニア年を節約できた方法の1つです。Contributor Insight は、高カーディナリティデータを分析するためによく使用するもう1つのツールです。高カーディナリティとは、多くの異なる値とディメンションを含むログを指します。Buy with Prime のアーキテクチャでは、各マイクロサービスが AWS アカウントレベルで分離されているため、アカウント ID は依存関係の観点から重要なディメンションとなります。各マイクロサービスには複数の API があり、API レベルの可視性が必要です。また、テナント ID を使用してテナントを識別するため、テナントレベルの可視性も必要です。
Contributor Insight で何ができるか見てみましょう。テナント ID ごとの API 別サーバーエラーの上位呼び出し元を表示します。単一のサーバーで動作するモノリシックサービスでは、Linux コマンドを使用して上位の呼び出し元を簡単に見つけることができます。しかし、Buy with Prime の複雑なアーキテクチャでは、テナント ID を使用して誰なのか、どのようなエラーが発生しているのか、どの API が関係しているのか、そのパターンが特定のテナントに限定されているのか、または特定の API が複数のテナントでサーバーエラーを生成しているのかを、どれだけ迅速に特定できるでしょうか? Contributor Insight は、このような複雑な分析を大幅に簡素化します。
例えば、グラフから実際のテナント ID や API 名が見えれば、どの API でどのテナントがサーバーエラーの影響を最も受けているかを即座に区別できます。私たちは Contributor Insight も CDK で定義しています。「キー別サーバーエラーの上位呼び出し元」という名前のルール例を見てみましょう。ロググループ名に注目してください。FireLens は Amazon ECS と EKS 用のコンテナログルーターで、EMF は Embedded Metric Format の略です。これは CloudWatch がサポートするメカニズムで、カスタムメトリクスをログの形式で埋め込むことができ、メトリクス API を呼び出したり、ロググループにメトリクスフィルターを作成したりする必要がなくなります。私たちの EMF では、「fault」がサーバーエラーを示します。そのため、マッチ演算子を使用して fault を見つけるフィルター期間があるのです。
システムパフォーマンスに最も影響を与えているのが誰か、または何かを特定するために、コントリビューターを分類することが重要です。ここでのキーは、例えばテナントIDなどです。Buy with PrimeのテナントはテナントIDで識別できます。キーにテナントIDを設定すれば、どのテナントがサーバーエラーの影響を受けているかがわかります。AWS account IDをキーに設定すれば、どの依存関係がサーバーエラーの影響を受けているかを理解できます。具体的なルールやキーフィルターは状況によって異なるかもしれませんが、いずれにせよContributor Insightを使って簡単に分析できます。
オープンソースプロジェクトの紹介と結論
今日からできることがあります。CDKを使用した私たちの可観測性アプローチが気に入ったなら、オープンソースから始めることができます。リポジトリにアクセスするには、QRコードをスキャンしてください。少し小さいですが、心配しないでください。最後のスライドにもっと大きな画像があります。オープンソースに含まれているものを簡単に紹介しましょう。CDKには、カスタムダッシュボードを生成するためのライブラリと、いくつかのサンプルLog Insightクエリ、Contributor Insightルールがあります。CDKをデプロイすると、Amazon ECS Fargateで実行されるサンプルWebアプリケーションがスピンアップされます。ECS Fargateタスクには2つのコンテナがあります。1つはWebアプリケーション用のアプリ、もう1つはFireLens用のサイドカーです。FireLensはすべてのコンテナログを収集し、Amazon CloudWatch logsに送信するので、Log InsightやContributor Insightを使って分析できます。
WebアプリケーションはApplication Load Balancerによってフロントエンドが構成されており、アクセスログを収集してAmazon S3バケットに保存するように設定されています。このS3バケットがどのように安全に構成されているかも確認でき、ALBのHTTPエラー数などのカスタムメトリクスもCloudWatchカスタムダッシュボードに組み込まれます。ここで振り返ってみましょう。今日のコンテンツの主なポイントは、前半でJiwonが紹介したTest Runnerです。これはデプロイメントパイプラインの専用テストステージに組み込まれており、テナントデータが安全に分離され、完全に保護されていることを検証できます。新しいコード変更をリリースするたびに、これを自動化しています。
後半では、CDKを使用した私たちの可観測性アプローチと、その結果として可観測性をどのように向上させたかを紹介しました。どこから始めればいいかわからない場合は、顧客を出発点にするのが良いでしょう。どのようなメトリクスを収集する必要があるか、どのようなツールを使用できるかを決定するのに役立ちます。もう一度言いますが、2つのオープンソースプロジェクトにはQRコードとリンクからアクセスできます。1つ目は、IAMセッションタグを使用して権限を検証するシンプルなTest Runnerです。ここから、ゼロから始めることなく独自のテストシナリオを開発できます。2つ目のリンクは監視用CDKです。監視コンポーネントがどのように定義され、関連付けられているかを確認できます。
これら2つのオープンソースプロジェクトを気に入っていただけたら幸いです。改善のアイデアやフィードバックがあれば、GitHubでissueを開いてください。そうすることで、私たちだけでなく、他の開発者の助けにもなります。最後に、Buy with Primeに興味がある方は、リストに登録できます。Buy with Primeに関する他のセッションもありましたが、すでに終了しています。まだ興味がある方は、後でYouTubeでチェックしてください。Amazonでは、私たちはデータ駆動型の企業です。遅い時間だとは思いますが、今日来ていただいてありがとうございます。ぜひアンケートにご協力ください。本日はご参加いただき、ありがとうございました。re:Inventの残りをお楽しみください。
※ こちらの記事は Amazon Bedrock を様々なタスクで利用することで全て自動で作成しています。
※ どこかの機会で記事作成の試行錯誤についても記事化する予定ですが、直近技術的な部分でご興味がある場合はTwitterの方にDMください。
Discussion