re:Invent 2023: AWSが提案するレジリエンス戦略とツール活用
はじめに
海外の様々な講演を日本語記事に書き起こすことで、隠れた良質な情報をもっと身近なものに。そんなコンセプトで進める本企画で今回取り上げるプレゼンテーションはこちら!
📖 AWS re:Invent 2023 - Reducing your area of impact and surviving difficult days (ARC306)
この動画では、コーヒーショップ経営者Aliceの成長物語を通じて、ワークロードの影響範囲を最小限に抑える方法を学びます。マイクロサービス、cell-based architecture、shuffle shardingなど、AWSの実践的なレジリエンス戦略が紹介されます。AWS Resilience Lifecycle Frameworkや、AWS Resilience Hub、AWS Elastic Disaster Recoveryといったツールの活用法も解説。エンジニアの皆さんに、大規模サービスの障害対策の最前線をお届けします。
※ 動画から自動生成した記事になります。誤字脱字や誤った内容が記載される可能性がありますので、正確な情報は動画本編をご覧ください。本編
無料または重要なワークロードへの影響を軽減する方法:イントロダクション
今日は、無料または重要なワークロードへの影響を軽減する方法についてお話しします。私たちは皆、長年にわたってワークロードに関する様々な状況を経験してきました。今日は、障害やイベントが発生した際に影響を最小限に抑えるための素晴らしいヒントやベストプラクティス、パターンについて学んでいただけると思います。これを実現するためのいくつかの方法について説明します。
今日は3人の人物を紹介します。 まず、コーヒーショップを経営するAliceについてお話しします。彼女のコーヒーショップが小さな店から大きな事業に成長していく過程と、困難な時期を乗り越えるために影響を軽減し、本当に減らしていった方法についてお話しします。
今日は、私たち2人で面白い実験をしながらプレゼンテーションを行います。AWSでは、最も影響力のある重要なワークロードについて考え、お客様と話をする際、常にそれらのワークロードをいかに最も耐障害性の高いものにするかについてアイデアを出し合います。今日お話しする多くのコンセプトは、私たちエンジニアが実際に行っているそういった会話や、それをどのように実現するかについての考えです。そのための原則と、それを達成するための最良の方法をみなさんと共有したいと思います。
みなさん、ようこそ。私はBruno Emerと申します。AWSのプリンシパルテクノロジストとして7年以上働いています。そして、私の親友のByron Arnaoも一緒です。彼もAWSでプリンシパルテクノロジストとして3年半働いています。
Aliceのコーヒーショップ:小規模ビジネスから大規模事業への成長
さて、それでは、ビジネスケースの理解から始めたいと思います。レジリエンスは常に必要であり、 ビジネスニーズにマッピングできるときに非常に素晴らしいものになることを私たちは理解しています。そこで今日は、Byronが説明したように、Aliceについてお話ししたいと思います。
Aliceはある会社で働いていましたが、休暇を取ってブラジルに旅行し、そこで本当に美味しいコーヒーを飲みました。アメリカに戻ってきた彼女は、仕事を辞めてコーヒーショップをオープンすることを決意しました。最初はとても小さなコーヒーショップで、友人や近所の人たちにコーヒーを売るだけのつもりでした。そして、自動化に関しては全く使用していませんでした。彼女は実際、昔ながらのペンと紙の方法を使い始めました。
商品を売るたびに、彼女は実際にノートに記録を取っていました。そして、店で販売するためにコーヒーを仕入れるたびに、それについても記録を取っていました。ビジネスが成長するにつれて、彼女は効率的に働きながら同時に手動でメモを取ることが難しいことに気づきました。そこで、彼女は注文を管理するためのITシステムが必要だと悟りました。ここから彼女の旅が始まったのです。
ちょっと待ってください。ネタバレになりますが。今は本当に小さなコーヒーショップの話をしていますが、この会話を進めていくうちに、現在よりもずっと大きくなっていきます。そのことを皆さんに知っておいてほしいのです。
レジリエンスの定義とAliceの初期システム設計
でも、Aliceとそのコーヒーショップの話をする前に、定義から始めたいと思います。そして、レジリエンスの定義から始めたいと思います。レジリエンスとは、何かが失敗したときにワークロードが回復する能力のことです。つまり、ワークロードがより多くのリソースを得る能力、障害を回避して何かが壊れても運用を続ける能力、そして何かが壊れたときに通常の状態に戻る能力について話しています。レジリエンスが実際に何を意味するのか、皆さんと同じ認識を持っていることを確認したかったのです。そして、これが今日のこの話のすべてです。
Aliceのコーヒーショップに話を戻しましょう。本当に小さく始まりました。小さなコーヒーショップだったと言いましたよね。彼女はガレージでコーヒーを売っていました。 そして、実際には注文管理アプリケーションの単一のインスタンスから始めました。そのインスタンスを構築し、とても小さなものでしたが、それをデプロイしました。 彼女は実際にデータベースを使用して注文、つまり彼女が持っているすべての情報をホストしていました。そして1時間ごとに、彼女はスナップショットを取り、そのデータベースのバックアップを取っていました。 なぜなら、問題が発生しても何が起こっているかを理解できることが彼女にとって非常に重要だったからです。
そして実際に問題が発生した時、彼女は昔ながらのペンと紙の方法に戻っていました。バックアップを復元している間も、ただペンと紙でメモを取っていたのです。この時点で、彼女が影響を受ける範囲は、実質的に1つのコーヒーショップだけでした。
しかし、アプリケーションの調子が悪かったり問題が発生したりすると、システムの観点からはAliceのコーヒーショップビジネス全体に影響が及ぶことになります。最初に影響を受けるのはコーヒーショップ自体です。
予想通り、そのコーヒーショップは本当に成長し始めました。ストーリーのネタバレになりますが、成長するにつれて、Aliceは別のコーヒーショップをオープンし、ITインフラをスケールアウトする必要が出てきました。私たちは皆、そういった状況を経験したことがあるでしょう。あなたが持っているワークロードのことを考えてみてください。それらが拡大し始めたとき、どのようなことを考慮する必要があるでしょうか。Aliceが新機能の構築を始めると、デプロイメントプロセスによってサーバー全体やワークロード全体がダウンする可能性がありました。
レジリエンスの基礎:望ましい特性と障害カテゴリー
そういうわけで、システムの耐障害性を高めながら、Aliceのビジネスへの影響をどのように軽減できるかを考えてみたいと思います。これに対処するために、まずは耐障害性の基礎について話し始めるべきでしょう。ここで考慮すべき重要な2つの点があります:望ましい耐障害性の特性と障害のカテゴリーです。
望ましい耐障害性の特性という観点から、5つの特徴を考慮する必要があります。まず第一に、ここで重要なのは障害許容性です。これには、高可用性、Auto Scaling Group、RAIDのようなストレージソリューションなどについて考えることが含まれます。次に十分な容量です。新しいカフェラテモカ抹茶ドリンクを導入したときに、容量が足りなくてAliceのアプリケーションが失敗するような作り方はしたくありません。
タイムリーな出力も非常に重要です。レジが効率的に動作し、注文が迅速に処理され、お客様が満足できるようにする必要があります。 正確な出力も同様に重要で、モバイルデバイスからの注文が正確に処理され、適切な場所に届くようにしなければなりません。 最後に、障害の分離が極めて重要です。これについて考える際に、何よりも強調したいのは、適切な障害分離境界を設けることです。これにより、障害が発生した場合(必ず発生します)、影響を最小限の人数に抑えることができます。
障害の種類と共有運命(Shared Fate)の概念
これらの特性を理解すると、アプリケーションがどのように壊れる可能性があるかを特定しやすくなります。アプリケーションがこれらの特性のいずれかに違反するたびに、障害に直面する可能性が高くなります。これを考える一つの方法は、それらの障害を異なるカテゴリーにグループ分けすることです。 最初のカテゴリーは、単一障害点です。これは、アプリケーションに冗長性や高可用性がない場合に発生し、アプリケーション全体がダウンする可能性があります。
もう一つの懸念は過剰な負荷です。これは特定の日に発生する可能性があります。例えば、Aliceが Black Friday に大規模なプロモーションを実施したい場合、追加の負荷に対応できるよう、ビジネスを十分にスケールアップする必要があります。同様に、毎日午後6時に人々が仕事を終えてコーヒーを多く購入する時間帯には、その販売に対応するための追加の処理能力が必要です。過剰な負荷は、処理できる限界プラス1に達したときに発生します。これがシステムが破綻する瞬間だからです。
過度の遅延も別のカテゴリーです。ビジネスの観点からは、すべてが正常に見えるかもしれません - サーバーは正しい応答を送信しています - しかし、ユーザーに到達するのに時間がかかりすぎると、システムが障害を起こしているか機能していないと認識されてしまいます。これが過度の遅延の現れです。最後に、設定ミスとバグは、考慮すべき別の障害カテゴリーです。
Aliceが正しく機能していない不適切な機能をリリースしてしまった場合、それはコードの障害と見なされる可能性があります。例えば、お客様がカプチーノを注文したのに、代わりにモカを受け取ってしまった場合、これは設定ミスまたはバグとなります。 このような種類の障害がシステムの障害を引き起こすことになります。これらの異なる方法で障害が発生し、障害分離境界を越えた場合(つまり、障害が封じ込められなかった場合)、それは shared fate の一例となります。
後ほど共有運命についてより詳しく説明しますが、簡単に言えば、Aliceが外部アプリケーションに依存していて、そのアプリケーションが失敗すると彼女のビジネス全体が停止する可能性がある、というようなケースです。これは彼女のシステムにとって望ましくない特性であり、以前は考慮していなかったものです。これが共有運命の概念を示しています。アプリケーションがどのように失敗する可能性があるかを、これらの異なる特性にマッピングすることで、潜在的な問題をより良く理解し、予測することができ、ビジネスへの影響を回避できるようになります。
Aliceのシステムの課題:単一障害点と影響範囲
では、これらの概念をワークロードにどのように適用できるか考えてみましょう。 そのために、コーヒーショップの例に戻りましょう。 覚えているかもしれませんが、Aliceが持っていたものはすべて単一のアプリケーションによって提供されていました。彼女は1つのデータベースを使用する注文管理アプリケーションを持っており、1時間ごとにバックアップを取っていました。 このアプローチはAliceにとってしばらくの間うまく機能しましたが、いくつかの課題がありました。
最初の課題は、注文管理アプリケーション自体が彼女のビジネスにとって単一障害点と見なされる可能性があったことです。このアプリケーションがダウンすると、すべてがダウンしてしまいます。Aliceは高可用性の実装や、このような問題を回避する方法を考慮していませんでした。 さらに、アプリケーションを変更したり新機能を追加しようとするたびに、すべてがこのアプリケーションの単一インスタンスに結びついているため、システム全体をダウンさせる可能性がありました。
この観点から見ると、アプリケーション自体が単一障害点であったと言えます。影響範囲を考えると、このアプリケーションがダウンした場合、すべてのコーヒーショップが影響を受けるだけでなく、アプリケーションが提供していたすべての機能がすべてのコーヒーショップで影響を受けることになります。この場合、非常に大きな影響範囲について話しているのです。
さて、Byron、Aliceのコーヒーショップの影響範囲を減らすにはどうすればいいでしょうか? 「単一のアプリケーションを持つこのシンプルな設計を取り上げてみましょう」とByronは答えました。「注文管理システムがあり、これはレジや店舗の入り口と考えることができます。そして、その背後にAmazon RDSデータベースがあります。また、バックアップも行っています。 私たちが本当にやりたいのは、これをマイクロサービスアプローチに移行することです。」
マイクロサービスアプローチへの移行:利点と考慮事項
さて、私たちは単純な注文管理システムから始めましたが、これらの主要機能や重要なユーザージャーニーをシステム全体で分解したらどうなるでしょうか?その注文管理システムから4つのシステムを作り出すことができます:在庫管理システム、顧客ロイヤルティプログラム、コーヒー価格設定エンジン、そして注文管理システム自体です。このように見ると、システム内の各マイクロサービスに対して1つの機能を作成していることがわかります。このアプローチにより、何か問題が発生した場合の影響範囲や影響を特定のアプリケーションだけに限定することができます。
この時点で、このアプローチの利点のいくつかを簡単に見ることができます。Byronが言っていたように、マイクロサービスを通じて環境を分離することで、Aliceはいくつかの利点を得ることができます。彼女が利用できる最初の利点は、各機能が独立して障害を起こすことです。これは、1つのアプリケーションに問題があった場合、その問題は特定の機能に限定され、システムの他の部分は引き続き機能し続けることができるということです。
例えば、顧客ロイヤルティアプリケーションに問題があった場合でも、注文は引き続き処理されます。これは、障害の影響を特定の機能に限定することに関するものです。これがマイクロサービス分離の最初の利点となります。
指摘したい2つ目の利点は、適切な技術スタックを選択できることです。なぜこれが重要なのか疑問に思うかもしれません。より回復力のあるアプリケーションを構築するためには、シンプルさが鍵となります。過度に複雑なシステムは避けたいのです。なぜなら、シンプルであればあるほど、管理や保守が容易になるからです。そのため、サービスの1つに永続化層が必要な場合、その仕事に適したツールを使用することができます。別のシステムが一時的なデータのみを保存する場合、そのジョブに適したツールを使用することができます。これにより、各特定のジョブに適したツールを使用することで、全体的により回復力のあるシステムを構築することができます。
このアプローチから得られる3つ目の利点は、アプリケーションのスケーリングがはるかに容易になることです。以前は単一のアプリケーションしかなく、すべての機能がそれによって提供されていたことを思い出してください。もし何かのプロモーションや施策により、ロイヤルティプログラムに参加しようとする顧客数が増加した場合、私たちはほぼすべてをスケールアップしなければならなかったでしょう。なぜなら、これが私たちが注目していた指標だったからです。このアプローチでは、各サービスがどのように独立して機能するかを理解することができます。十分な容量とそれを顧客需要に合わせて提供する方法について話していたことを思い出してください。私たちは適切なデータ、適切な情報を得ることができ、環境全体を測定することなく、各サービスを独立してどのようにスケールするかを理解することができます。これもまた、はるかに容易になるでしょう。
最後に、私たちは分離されたデプロイメントを実行する能力を持つことになります。以前の問題を思い出してください。グリーンからブルーへの移行を開始すると、システム全体が壊れる可能性がありました。このリスクは、このスケールで大幅に軽減されます。例えば、顧客ロイヤルティプログラムを更新して新しいバージョンに移行する一方で、注文管理システムは全く変更せずにそのままにしておくことができます。
Availability Zoneを活用した共有運命の回避
これについて話す中で、多くの方がmicroservicesについて聞いたことがあると思いますが、これがすべての解決策になるわけではないと言いたいです。すべてに使える万能の解決策ではありません。確かに複雑さが伴います。私たちの例では4つのmicroservicesがあると言いましたが、デプロイメントには多くの複雑さが伴います。それらすべてにわたって観測可能性のための計装を行う必要があります。そして、それぞれのサービスやAliceのコーヒーショップの機能ごとに複雑さが増していくことになります。デプロイの方法がより複雑になっていくのです。バランスを取る必要がありますが、分離メカニズムとして、また影響範囲を減らすためには、本当に良いメカニズムであり、それを達成する方法です。
Aliceがこのmicroservicesアプローチを採用することで、影響範囲が本当に縮小されたことがわかります。以前は、すべての店舗のすべての機能が壊れる可能性がありましたが、今では本当に1つの機能だけに最小限に抑えることができます。それらのアプリケーションのいずれかに問題がある場合でも、彼女のすべてのコーヒーショップで1つの機能だけが動作しなくなるだけです。つまり、販売ができない状態から、環境内で1つの機能だけが動作しない状態に変わったのです。私たちは本当に影響範囲をさらに減らすことを考えており、このアプローチがこのケースでどのように使用できるかを示しています。
これを踏まえて、このシステム設計には共有運命があるでしょうか?私たちは先ほど、障害のカテゴリーを説明する際に共有運命について話していました。私が言ったことの1つは、基本的に共有運命の定義は、障害が分離境界を越えるときだということです。これについては2つの観点から考えることができます。もし私がアプリケーションに与える影響について全く考えずに、それが起こってしまったら、それは間違いなく悪いことです。どこかで機能障害が起きたため、間違いなく悪い日になるでしょう。例えば、依存関係が失敗した、つまり私が頼っていたものが失敗して、システム全体がダウンしたとします。これは望ましくありません。
しかし、時にはこれがアプリケーションで追求する動作である場合もあることを明確にしたいと思います。時には依存関係に頼り、その依存関係がダウンした場合、実際に「その依存関係が損なわれたら、私のアプリケーションも動作しないようにしたい」と決めることもあります。共有運命は、それについて考えたことがある場合、実際には良いことかもしれないからです。最初からこのことを明確にしたかったのです。もし全く考慮していなかった場合、それは大きな問題になります。なぜなら、どこかで障害が発生すると、それが連鎖的に広がってシステム全体をダウンさせてしまうからです。そしてこれこそが、避けたいことなのです。
Aliceのケースでは、彼女がモノリシックアプリケーションからマイクロサービスへ移行した話をしました。 この種のアーキテクチャは何度も見てきましたね。しかし、彼女が気づかなかったのは、複数のマイクロサービスを使用していたにもかかわらず、 実際にはすべてが単一のAvailability Zoneにデプロイされていたということです。つまり、彼女は単一のAZ実装だったのです。これの問題点は、もしその特定のAvailability Zoneで障害や機能低下が発生し、トランザクション(つまりコーヒーの注文)の処理に影響が出た場合、アプリケーション全体がダウンしてしまうことです。
このケースでは、単一のAZデザインは彼女が意図したものではありませんでした。避けるべきものだったのです。なぜなら、繰り返しになりますが、処理を続ける能力に影響を与えるAvailability Zoneの問題が発生すると、アプリケーション全体がダウンしてしまうからです。これは彼女が望んでいたことではありませんでした。そして、次に浮かぶ疑問は、 Aliceがこの環境での共通の運命(shared fate)をどのように減らすことができるかということです。
Cell-based Architectureの導入:さらなる分離と影響範囲の縮小
はい、これらが重要な基盤の一部です。この時点で多くの方々がこれらについて考えていることと思います。私たちには世界中に32のリージョンがあり、Availability Zoneがあります。これらは最適なポイントで、今日の話の中心になります。そして、それらのAvailability Zoneを構成するデータセンターがあります。よく耳にすることの一つは、 Bruno、これは何度も出てくる話なのですが、お客様がオンプレミス環境からの移行を考える際に、そのデータセンターを頭の中でAvailability Zoneに置き換えて考えてしまうことです。
実際、AWSのAvailability Zoneは多くのデータセンターで構成されることがあり、それぞれのAvailability Zoneには独自の接続、インフラ、電源供給などのコンポーネントがあります。障害分離境界について考えるとき、これこそが私が本当に強調したい部分です。「これはお客様がアプリケーションへの影響を最小限に抑えるために使用すべき主要なメカニズムです」と言いました。これは実際にそれを行うための重要な方法の一つなのです。
そう、Aliceがこのシナリオで共通の運命を避ける一つの方法は、Byron、単一のAvailability Zoneから複数のAvailability Zoneに移行することでした。これは、 Byronが説明した障害分離境界を本当に活用することです。そして、AWSが提供するインフラストラクチャとワークロード間の共通の運命という考えを避けることです。もし何らかの理由でそれらのAZの1つに障害が発生し、彼女のワークロードが注文を処理できなくなったとしても、複数のAvailability Zoneにデプロイすることで、全く影響を受けないのです。まだ注文を処理する能力があるので、通常通り店舗でコーヒーを販売し続けることができるのです。
Aliceのビジネスは成長を続け、今では全国に何百もの店舗を展開するまでになりました。そして最近、予想通りのことですが、彼女は損失を被りました。その損失額は537,000.22ドルにも上りました。これはかなり大きな出来事です。彼女の店舗を世界中に拡大しようと考えていたベンチャーキャピタリストたちは、心配し始めました。そして、これが彼女のビジネスを「大きすぎて潰せない」ものにしてしまったのです。Aliceは、さらに影響を軽減する方法について、次のレベルの思考に進む必要がありました。
先ほど申し上げたように、Aliceには「全国的なグローバルストアを作る」というビジョンがありました。彼女の頭の中には、至る所にコーヒーがある光景が浮かんでいたのです。しかし残念ながら、そのような影響と、広まってしまったニュースによって、全店舗に影響が及び、アプリケーションに対する人々の信頼が揺らぎ始めました。これは聞き覚えのある話ではないでしょうか?
Shuffle Shardingの実装:極めて重要なワークロードの回復力向上
この馴染みのあるシナリオを踏まえると、全てのコーヒーショップに同時に影響が及ばないようにするには、どのように影響を軽減できるか考える必要があります。さらに進んで、別の仕組みを使うことはできないでしょうか?
改善方法を理解するためには、もう一度立ち戻って、どのように物事が機能していたかを理解する必要があると思います。思い出してみると、全ての店舗は実際には、Aliceが複数のAvailability Zoneにわたって適用していたmicroservicesと通信していました。それらのサービスのいずれかに障害や問題が発生すると、彼女の全ての店舗がその影響を受けることになります。つまり、コーヒーやカプチーノを買うことができなくなってしまうのです。
Aliceができることの一つは、店舗とアプリケーションの接続方法を変更することです。彼女は、同じmicroservicesの複数のコピーを作成し、必要なすべてを理解した上で、そのコピーを複数デプロイすることができます。そうすれば、一部の店舗を選んで、それらのアプリケーションのインスタンスにマッピングすることができます。ちなみに、私たちが話しているこれらのコピーは、cellと呼ぶことができます。これは、この場合、より分散化されたものに移行するという考え方です。つまり、cell-based architectureに移行し、そこでデータのセル化を始めることができるのです。
このアプローチは彼女にもいくつかの利点をもたらすでしょう。例えば、セルの1つが調子の悪い日があったとします。新機能をデプロイしていたり、アプリケーションに何か問題が発生したりした場合です。先ほど話した障害のカテゴリーのいずれかが実際にそれらのセルの1つで起こっていたとしましょう。この影響に気づくのは、そのセルと通信している店舗だけです。他のすべての店舗は、通常通り運営を続けることができます。
彼女がこれらのセルをアメリカの州にマッピングしていて、調子の悪い日を過ごしているセルがネバダ州をサポートしているセルだったとしましょう。そして、私たちがここラスベガスでコーヒーを買おうとしても、買えないでしょう。しかし、カリフォルニア、コロラド、フロリダ、あるいはコロンビアのボゴタのユーザーは、引き続きコーヒーを購入できます。彼らには全く影響がありません。問題が発生した場合、1つの機能がすべての店舗に影響を与えるという状況から、1つの機能が悪い日には一部のコーヒーショップにのみ影響を与えるという状況に変わるのです。
セルベースのアーキテクチャについて考えると、アプリケーション全体、おそらく先ほど話したマイクロサービスを取り、そのスタック全体を1つのセルに配置することになります。これは素晴らしい分離です。ただし、これにも複雑さが伴います。最大の障害や障壁の1つは、実際にデータのパーティショニングについて考えることです。先ほどの例を使って、「店舗が異なる州にあるか、あるいは東海岸、中央、西海岸を表す3つの異なるセルに分割した」と言いました。そのように考えた場合、実際にデータベースとデータを取り、それぞれの地域が異なるセルにマッピングされるような方法でパーティショニングする必要があります。
これは、意味のある次元であれば何でも行うことができます。金融サービス業界の顧客や人々がこれを行っているのを見たことがありますが、彼らは市場データシステムに対してこれを行い、基本的に株式シンボルで分割して異なるセルに配置しています。人々がこれを達成する方法は多くありますが、この特定の部分には複雑さが伴うことを言っておきたいと思います。ここでの重要なポイントの1つは、セル間で完全な分離を行い、障害を本当に制限できるようにすることです。そして、これは部分的な分離ではなく、完全な分離であることに注意してください。
単一障害点について話すとき、セル間で共有されるスタックの底にデータベースがあるのはセルベースのアーキテクチャではありません。なぜなら、他のものと運命を共にすることになるからです。もう1つの本当に重要な利点は、必要に応じてセルを追加して線形にスケールアウトできることです。セルがあり、「その特性を理解している」と言えるという事実には、多くの予測可能性があります。
Aliceのコーヒーショップの成功と分離メカニズムの効果
シャーディングがセルの実装の鍵であることを忘れないでください。
Byronが説明したように、セルについて話すとき、私たちは障害の影響範囲を本当に縮小することになります。Aliceのビジネスで悪い日があったときのことを覚えていますよね?コーヒーショップがダウンしたために、537.22ドルの損失に加えて、全国の主要な新聞の一面に載ってしまいました。アプリケーションに隔離境界が実装されておらず、アプリケーションが調子の悪い日を過ごしていると、誰もがそれに気づき、影響を受けることになります。そして、これはまた一面記事になる可能性があります。
しかし、セルを実装すると、アプリケーションに問題があった場合でも、特定のセルにマッピングされているユーザーの一部が影響を受け、特に寒い日にコーヒーを買えなくなるかもしれませんが、影響は大幅に軽減されます。すべてのユーザーがコーヒーを買えなくなるわけではありません。すべてがダウンしているわけではありません。実際には、一部のユーザーがAliceからコーヒーを買えないだけです。これが、新聞の一面から後ろのページへと移行する方法です。
しかし、Byronの説明の中で考えさせられることがあり、もう少し深く掘り下げてみたいと思います。Byron、セルについて説明するとき、あなたが言及したことの1つは、各セルが完全なスタックのようなものだということです。共有された運命はなく、共有データベースもありません。つまり、各個別の店舗が自分のデータがどこにあるかを知る必要があるということですね。そこにインテリジェンスが必要です。そこで、データが分割されている場合、各店舗がどのセルにマッピングまたは接続する必要があるかをどのように知るのか、説明していただけますか?
素晴らしい質問です。これを実現する方法として、多くの人は薄いルーティング層を追加する必要があると考えるかもしれません。「単一障害点を導入してしまったのでは?」と思うかもしれません。そして、実際にそうなのです。しかし、ベストプラクティスの1つとして、それを極めてシンプルに保つことができます。どういう意味かというと、例えば5行、10行、15行程度のコードを考えることができます。リクエストを処理し、誰かがどこに行くかを把握するためにデータベースをポーリングするようなことはしたくありません。代わりに、そのマッピングを定期的にルーティング層にプッシュし、非常に静的に安定させたいと思います。これが超レジリエントであることを確実にしたいのです。そして、ルーティング層に多くの複雑さを追加することは、確実に多くの複雑さをもたらすタイプのものです。したがって、それは一時的なものである必要があります。
AWS Resilience Lifecycle Frameworkの紹介
これについて考えると、考慮すべき重要なシステムプロパティがいくつかあります。 ワークロードの分離については、少し触れましたね。セルとそのフルスタックがそのセル内にのみ存在することを確実にすることが、本当に重要なポイントです。 そして、障害の封じ込めも別のプロパティです。なぜなら、私たちがここにいる理由であり、影響範囲を最小限に抑えることについて話しているからです。ちなみに、ここで少し秘密をお話しします。これはAmazonが行っていることなのです。お客様とお話しするとき、最もよく聞かれる質問は、どのようにして数十万や数百万のAPIコールが数秒や数分の間に発生するような超大規模サービスを構築しているのかということです。
この障害の封じ込めは、私たちがそのために行っている重要なことの一つです。例えば、単一のセルでサービスに影響が出た場合、それは全体のワークロードの10分の1か20分の1程度しか表していないかもしれません。ここで示している例を見ると、他のセルは影響を受けていないことがわかります。以前にこのようなことを目にしたことがあるかもしれません。一部のものに影響が出ているけれど、一部のユーザーには徐々に回復が見られるといった具合です。これは、プラットフォーム全体やサービス全体が一度に影響を受けないように、セル化しているからなのです。
これにより、単に規模を拡大するだけでなく、本当の意味でスケールアウトする能力も得られます。私たちがそれを実現する主な方法の一つは、セルに最大サイズを設定することです。これについて考えてみてください。 システムを構築する際、Aliceの場合、彼女はレジや店舗で1時間に1,000杯のコーヒーを処理できるようにしたいと考えています。
テストを行う際、私はすべてのセルに最大サイズがあることを確認します。 インフラが予想外の規模にまで拡大し、アプリケーションに予期せぬ影響を与えるような状況に遭遇したくありません。この最大サイズを設定することで、テスト可能性が実現可能になります。
100万や10万のトランザクションをシミュレートしようとする状況を想像してみてください。 長年のパフォーマンスエンジニアリングの経験から、私はこれを管理可能な部分に分割してアプローチすることを学びました。10個のセルに分割すれば、その10分の1をテストし、その特定のセルのパフォーマンス特性を理解することができます。最後に強調したいシステムプロパティは管理のしやすさです。
re:Inventのラスベガスで、みんながセッションで眠らないようにコーヒーを必要としているときのように、1つのセルに異常に高いトラフィックを経験しているストアがある場合、何が起こるのか疑問に思うかもしれません。セルを退避させ、より大きなストアを別のセルに移動する能力は、自分で構築する必要があります。現在、この目的のための特別なソフトウェアやセル管理プラットフォームは存在しません。 モノリスや他のアプリケーションでレジリエンスを高めるために行うことはすべて、セルにも適用されることを覚えておくことが重要です。高可用性と災害復旧へのアプローチは、セルを使用しているからといって変わるわけではありません。この複雑さが、セルベースのアーキテクチャが高度な分離が必要な最も重要なワークロードに最適である理由です。
セルベースのアーキテクチャは素晴らしかったのですが、Aliceの従業員が使用する注文処理システムは注文処理にとって極めて重要でした。私たちの例では、セルに障害が発生すると、ストア全体に影響が及びます。 Aliceは、マイクロサービスやセルが提供できる以上に影響をさらに軽減したいと考えていました。彼女はさらに一歩進んだ対策を望んでいました。 そこで、Aliceはこの特定のサービスをさらにレジリエントにできるでしょうか?
ここで、Aliceがこの特定のサービスにさらなるレジリエンスを実装するのに役立つ、異なるアーキテクチャパターンについて議論し始めます。この追加のパターンを理解するために、一歩下がって物事がどのように進展しているかを見てみましょう。それぞれの画像がユーザーがレジスターと対話している様子を表していると想像してください。もしそれらのユーザーやレジスターの1つがサーバーに不正なリクエスト(ポイズンピルや予想以上のデータを含む大量のリクエストなど)を送信していたら、サーバー全体がダウンする可能性があります。
しかし、Aliceは初日からレジリエンスについて考えており、これに対処するメカニズムを実装していました。彼女は賢明にも、環境に問題がある場合や、クライアントが利用できないサーバーと通信しようとした場合、リトライメカニズムを実装することを決定しました。 しかし、不正なリクエストだったため、リトライが別のサーバーをダウンさせる可能性があり、さらに別のサーバーもダウンさせる可能性があります。そして、システム全体に影響が及び、正常に機能しなくなる可能性があります。このシナリオは、システム全体に影響を与える可能性のある拡大する影響範囲を示しています。
私たちが本当に話しているのは、すべての顧客に影響を与える影響範囲についてです。これが以前の動作方法でした。進んで、シャーディングについて話しました。セルベースのアーキテクチャの概念を導入したとき、状況が変わりました。これらのアプリケーションやアプリケーションと対話するユーザー、つまりレジスターは、すべてのリクエストをフリート全体に送信していたわけではありません。私たちはデータをシャーディングしていました。
この場合、ユーザーの猫が注文を通そうとしていたけれど、これが不正なリクエストだったとすると、実際にシャードまで到達してしまいます。 間違いなくサーバーがダウンしてしまうでしょう。poison pillsの問題と同じだと仮定すると、サーバーに影響が出て、ユーザーは再試行し、 そこで止まってしまい、シャード全体またはセル全体がダウンしてしまいます。でも、これは以前よりも良い状況だということがわかります。 なぜなら、他のユーザーはまだ注文を通すことができるからです。
これは、Aliceがモノリシックからセルラーアーキテクチャに移行することで得られるものとほぼ同じです。今話したことですね。この場合、影響範囲は実際には顧客数をシャードの数で割ったものになります。 これは全顧客数よりも小さいです。つまり、ここでも効果的に影響範囲を減らしているわけです。でも、Aliceが使える別のパターンもあります。これがどう機能するか理解するために、少し話を変えてみましょう。
shuffle shardingというパターンがあります。shuffle shardingのアイデアは、数学を使ってユーザーとサーバーの相互作用の割り当て方を変えることです。ここでshuffle shardingを使うと、単にシャードを構築して固定のユーザーをそれらのシャードに割り当てるのではなく、ユーザーに全く同じインフラを共有させるのではなく、少し違うやり方をします。各ユーザーは依然として2つの異なるサーバーを使用しますが、全く同じインフラを共有することはありません。
基本的に、これが得られる結果です。そして、この実装が行われていても、猫が注文しようとしていて、これが不正なリクエストだったとします。先ほど見たようなケースです。クライアントの視点からは実際には変わりません。猫は1台目のサーバーをダウンさせ、次に2台目のサーバーをダウンさせます。シャーディングについて話したときに見た、同じ2台のサーバーがダウンするわけです。
しかし、ここでの違いは、この場合、ユーザーの猫が他のすべてのユーザーと同じインフラを共有していなかったため、他のユーザーはまだ注文を通すことができるということです。他のユーザーが感じる全体的な影響は実際に減少します。なぜなら、彼らはシャード全体を共有していなかったからです。これがshuffle shardingについて話すときに得られる結果です。つまり、影響範囲を減らすことができるのです。この例では、単一のユーザーにまで減らせます。もちろん、より多くのユーザーやより多くのインフラを扱う場合、これらの数字は異なる可能性があります。しかし基本的に、影響範囲は顧客数を可能な組み合わせの数で割ったものに等しくなります。つまり、さらに影響範囲を減らすことができるのです。
復習しましょう。 アプリケーションで障害が発生した際の影響を軽減するために、4つの重要な概念について説明しました。 まず、アプリケーションや機能をマイクロサービスに分解して、一度に全機能が影響を受けないようにする方法を紹介しました。例えば、レジと決済処理は非常に重要な機能ですが、退店時にクッキーを勧めるような機能はそれほど重要ではありません。これは本当に重要な機能であり、Aliceの仕事の核心部分です。
Aliceが学んだもう一つのことは、フォールト分離境界を活用することです。 マイクロサービスはその一例ですが、AWS RegionsやAvailability ZonesなどのAWSのフォールト分離境界を理解し、さらにはcell-based architectureに移行することで、Aliceは共有運命を回避できるようになりました。これにより、問題を本当に分離し、障害が彼女の定義した境界を越えないようにすることができます。このようにして、共有運命のシナリオを乗り越えることができるのです。
これらのcell-based architectureにより、Aliceはさらなる分離を実現できました。これは慎重に扱うべき話題で、後ほどBrunoと一緒にその実装方法について説明します。確かに複雑さは増しますが、cell-based architectureを採用することで、さらなる分離が可能になります。
Aliceが使用しているワークロードの一つは、彼女のビジネスにとって非常に重要でした。このワークロードがダウンすると、ビジネスに大きな影響が出てしまいます。この特定のワークロードには、極めて高い回復力と、他に影響を与えずに障害に耐える能力が必要でした。さらなる分離が必要だったため、彼女はshuffle shardingを実装することにしました。Shuffle shardingは複雑で、実装は簡単ではありません。ちなみに、AWSでも使用している技術です。例えば、Route 53はshuffle shardingを使用して全体的な回復力を高めています。Aliceにとっては非常に重要だったため、すべてのトレードオフを受け入れて実装することにしました。その結果、システム全体の回復力をさらに向上させることができました。
re:Inventなので、この話には幸せな結末があります。 Aliceのコーヒーショップは、これらの分離を実装した後、全国規模の事業になりました。実際、皆さんにもこの後、Aliceのコーヒーを見つけたら飲んでみることをお勧めします。私も一緒に行きましょう。この地図を見ると、今では全国に展開していることがわかります。 これらの分離メカニズムを使用することで、影響範囲を劇的に縮小することができたのです。
AWSのレジリエンス関連サービスとソリューション
Alice のストーリーに加えて、AWS は AWS Resilience Lifecycle Framework をリリースしました。このフレームワークは、お客様が全体的なレジリエンス態勢を向上させるために活用できる戦略、サービス、メカニズムを共有しています。世界中の多くのお客様と協力して学んだことの1つは、レジリエンスは一度行えば終わりというものではないということです。レジリエンスは常に実行し続ける必要があります。Alice の例でも見たように、彼女は常に改善を試み、新しい問題を見つけ、それらの問題や影響を軽減するためにアーキテクチャを進化させ続けていました。
このため、ソフトウェア開発ライフサイクルと同じ視点でライフサイクルが作成されました。お客様がソフトウェアを構築する過程で、このライフサイクルを活用できるようにという考えです。ライフサイクルには5つの異なるフェーズがあります:目標設定、設計と実装、タスクの評価、運用、そして対応と学習です。これらの各フェーズは、それぞれの領域で使用できるインサイト、情報、サービス、メカニズムをもたらします。
アーキテクトや技術者として、ここにいる多くの方々は、これに対して異なるツールを使用するかもしれません。私たちが提供するツールの中には、この旅路で役立つものがいくつかあります。最初に紹介するのは AWS Resilience Hub です。これは素晴らしいツールです。多くのお客様と話をしましたが、ほとんどの方がこれをガバナンスのような役割で使用しているのを見ています。RPO や RTO を理解し、それらを達成できるかどうかを把握するのに本当に役立ちます。Resilience Hub で私が気に入っている点の1つは、RPO と RTO を設定すると、データの保存場所とその回復方法を把握しているため、データの復元時間に基づいてそれらを達成できるかどうかを実際に教えてくれることです。
もう1つ私が本当に気に入っていて、Bruno と私がお客様とよく話し合うのは、レジリエンスをどのように向上させるかという質問です。私は「練習、練習、練習」と言います。回復とその方法が第二の天性になるまで、つまりそれに慣れて、初めてのことではないという状態になるまで練習してください。数え切れないほど多くの場合、イベント中にお客様との通話で「これを実行する準備はできていますか?フェイルオーバーすべきですか?」と全員が尋ねているのを聞きました。これは第二の天性であるべきで、日常的に行うタイプのものであるべきです。
最後に、AWS Elastic Disaster Recovery は本当に使えるものです。これはバックアップを支援し、オンプレミスシステムとの統合も行い、回復能力を向上させるのに役立ちます。
他にも、お客様のレジリエンスを支援するサービスとして、AWS BackupとAmazon Route 53 Application Recovery Controllerがあります。AWS Backupは、お客様がデータを保護し、バックアップを簡単かつコスト効率よく管理するのに役立つサービスです。以前、Aliceが1時間ごとにデータベースのバックアップを取っていたことを覚えているでしょうか。改善方法を考えると、AWS Backupを使えば、AWSサービスで稼働しているすべてのデータソースからバックアップを取ることができます。
もう1つのサービスは、Amazon Route 53 Application Recovery Controller、略してRoute 53 ARCと呼んでいるものです。このサービスは、障害が発生した際にAvailability ZoneやRegionにトラフィックを送信しないよう、リカバリの管理と自動化をお客様に簡単かつマネージドな方法で提供します。
最後に、AWS Solutions Libraryがあります。ここでは、お客様は目的に特化したAWSのレジリエンスソリューションやパートナーソリューションを見つけることができます。AWS Solutions Libraryには、先ほど説明したレジリエンスライフサイクルなど、お客様が全体的なレジリエンス態勢を改善するために活用できる非常に豊富な情報が含まれています。
まとめと謝辞
以上で終わりです。皆様、ご来場いただきありがとうございました。re:Inventにお越しいただき、ありがとうございます。Byronが言ったように、お帰りの際にAliceのコーヒーショップを見つけたら、ぜひ立ち寄ってみてください。彼女は今、非常にレジリエントなアーキテクチャに頼っていることがわかっています。そして、モバイルアプリでセッションのアンケートにご回答いただくことをお忘れなく。本日はご来場いただき、誠にありがとうございました。
※ こちらの記事は Amazon Bedrock を様々なタスクで利用することで全て自動で作成しています。
※ どこかの機会で記事作成の試行錯誤についても記事化する予定ですが、直近技術的な部分でご興味がある場合はTwitterの方にDMください。
Discussion