忙しい人のための AWS 規範ガイダンス「Resilience Analysis Framework」

2024.03.28

いわさです。

先日 AWS によるレジリエンスのためのガイドである「Resilience Lifecycle Framework」を紹介しました。

上記の Resilience Lifecycle Framework は、組織がレジリエンスに取り組む際にどこからはじめたら良いのか、ステージごとのガイドとなっていました。
実はその中でも少し登場しているのですが、よりワークロードのレジリエンス特性を分析するためのフレームワークとして「Resilience Analysis Framework」というものがあります。

Resilience Lifecycle Framework と比較すると、ドキュメントを読んでも中々理解出来なかったのですが、5 回くらい読んで re:Invent のレジリエンスセッションも見ることでようやく理解出来てきましたので、忙しい人向けにサッと知ってもらえるようにまとめておきたいと思います。

Resilience Analysis Framework とは

レジリエンスの観点からワークロードの弱点を発見し、見直しを行うためのフレームワームになっています。

具体的には、フレームワーク内では SEEMS モデルという障害カテゴリを定義しており、アーキテクチャーコンポーネントをユーザーストーリーベースで整理した上で、コンポーネントごとに SEEMS モデルを当てはめて弱点を発見し、トレードオフを意識しながら継続的に改善を行っていくといった考えとなってます。

一応 SEEMS モデルというものが定義はされているのでフレームワークっぽさもあるのですが、ガイダンス上抽象的に書かれている部分が多いコンポーネントごとに確認していくなど、そこそこ泥臭く地道に分析していく必要がありまして、サクッと当てはめて終わり!みたいな感じじゃないです。
後半に紹介する re:Invent のセッションでも、このフレームワークを採用する際にはしっかりリソース投資しましょうねという点に触れられています。

とはいえ、レジリエンス何からやったら良いか全くわからん。という場合など考え方の基準に出来るフレームワームだと思います。

SEEMS モデル

レジリエンスがあると言うために満たすべき特性があり、このフレームワーク内でそれらを基に障害カテゴリと呼ばれる 5 つのカテゴリを定義しています。これらの頭文字をとって SEEMS と名付けられているようです。

  • Single points of failure (単一障害点によるシステム全体の障害)
  • Excessive load(高負荷による障害)
  • Excessive latency(高レイテンシによる障害)
  • Misconfiguration and bugs(構成誤りやコードのバグによる障害)
  • Shared fate(上記の障害によって他の領域にまで及ぶ障害)

単一障害点については AWS というか、クラウドの設計原則的に良く出てくる概念ですね。
他のものも言われてみればそういう障害

フレームワークの使い方

フレームワークの使い方ですが、雑にいうとワークロードを整理して、上記 SEEMS モデルの観点を参考にアーキテクチャーをチェックしていきましょうね。という感じです。

コンポーネント整理

で、チェック前のワークロードの整理方法についてもフレームワーク内で言及されています。
忙しい人向けなので要点だけまとめますと、4 つの共通コンポーネント(コード&構成、インフラ、データストア、外部依存)とユーザーストーリーを意識してアーキテクチャーを整理することが推奨されています。

分類例として次のような構造が紹介されています。

画像引用元:Understanding the workload - AWS Prescriptive Guidance

共通コンポーネントごとに分類しておくと障害カテゴリを分析する際にわかりやすいよというのと、ユーザーストーリーごとに分類しておくと、トレードオフを行う際などにビジネス価値から優先順位を設定しやすいからです。

障害カテゴリごとに質問していく

フレームワーク内で質問セットが用意されているので、コンポーネントごとに次の観点でチェックを行っていきます。
英語ドキュメントから抜粋したものを機械翻訳かけたのでところどころ日本語訳が怪しい気もしますが雰囲気は伝わるのでまぁ良いですかね。良いよね。

  • Single points of failure (単一障害点によるシステム全体の障害)
    • コンポーネントは冗長性を考慮して設計されていますか?
    • コンポーネントに障害が発生した場合はどうなりますか?
    • アプリケーションは、単一のアベイラビリティーゾーンの部分的または全体的な損失を許容できますか?
  • Excessive load(高負荷による障害)
    • このコンポーネントの遅延が増加した場合、またはコンポーネントが対話するコンポーネントの遅延が増加した場合 (または TCP リセットなどのネットワーク中断が発生した場合) はどうなりますか?
    • 再試行戦略を使用してタイムアウトを適切に構成していますか?
    • 失敗するのは早いですか、それとも遅いですか? すぐに障害が発生するため、障害のあるリソースにすべてのトラフィックが意図せず送信されるなどの連鎖的な影響はありますか?
    • このコンポーネントに対して行われる最もコストのかかるリクエストは何ですか?
  • Excessive latency(高レイテンシによる障害)
    • このコンポーネントを圧倒するものは何でしょうか? このコンポーネントはどのようにして他のコンポーネントを圧倒するのでしょうか?
    • 決して成功しない作業にリソースを浪費しないようにするにはどうすればよいでしょうか?
    • コンポーネント用に設定されたサーキット ブレーカーはありますか?
    • 何かが乗り越えられないバックログを生み出す可能性はありますか?
    • このコンポーネントはどこで二峰性の動作を経験するのでしょうか?
    • どのような制限またはサービス クォータを超えることができますか (ストレージ容量を含む)?
    • 負荷がかかるとコンポーネントはどのようにスケールされるのでしょうか?
  • Misconfiguration and bugs(構成誤りやコードのバグによる障害)
    • 構成ミスやバグが実稼働環境にデプロイされるのをどのように防ぐことができますか?
    • 不適切なデプロイメントを自動的にロールバックしたり、更新または変更がデプロイされた障害のあるコンテナーからトラフィックを移動したりできますか?
    • オペレーターのミスを防ぐためにどのようなガードレールを設置していますか?
    • どのアイテム (資格情報や証明書など) が期限切れになる可能性がありますか?
  • Shared fate(上記の障害によって他の領域にまで及ぶ障害)
    • 障害分離の境界は何ですか?
    • デプロイメント ユニットに対する変更は、少なくとも意図した障害分離境界と同じくらい小さいものですが、理想的にはワンボックス環境 (障害分離境界内の単一インスタンス) など、より小さいものに行われますか?
    • このコンポーネントはユーザー ストーリーまたは他のワークロード間で共有されますか?
    • このコンポーネントと密接に結合している他のコンポーネントは何ですか?
    • このコンポーネントまたはその依存関係に部分的な障害または灰色の障害が発生した場合はどうなりますか?

結構多いですね。これをコンポーネントごとに行うとは大変だ。
ただ、上記ドキュメント内では初回で全部を行う必要はないですよ。フレームワークは複数回繰り返し行っていきましょうとも言及されています。

障害に対する緩和

上記の質問から障害がありそうなコンポーネントが見えてきたら、緩和策を検討します。
緩和策検討の流れは、トレードオフの分析・可観測性を備える・緩和策の実装です。

トレードオフ

レジリエンスの文書では繰り返しトレードオフについて言及されています。フレームワーク内では一般的にどういったトレードオフが必要になるのかも紹介されていますので参考に出来ます。なるほどって感じです。

  • コスト
    • コンポーネントの冗長化、可観測性の強化、ツールの追加、またはリソース使用率の増加により、コストが増加します。
  • システムの複雑さ
    • 緩和ソリューションを含む障害モードの検出と対応、およびマネージド サービスを使用しない可能性により、システムの複雑さが増大する結果になります。
  • エンジニアリングの取り組み
    • 障害モードを検出して対応するソリューションを構築するには、追加の開発時間が必要です。
  • 運用上のオーバーヘッド
    • より多くの障害モードを処理するシステムを監視および運用すると、特にマネージド サービスを使用して特定の障害モードを軽減できない場合に、運用上のオーバーヘッドが増加する可能性があります。
  • 待ち時間と一貫性
    • PACELC の定理で説明されているように、可用性を重視した分散システムを構築するには、一貫性と待ち時間のトレードオフが必要です。

可観測性

フレームワーク内ではこのあたりは具体的に言及されていないのですが、「このままだと障害が発生するかも」という指標と、「今、障害が発生してるわ」という指標の 2 つの観点で考慮が必要だと言及されています。

例えばデータベースであれば、前者は接続数の監視、後者は接続エラーの監視が例として挙げられています。

緩和策の実装

緩和策についてもいくつか具体的な例がドキュメントで紹介されていますので以下も参考にしてください。

いくつか抜粋すると、Excessive load(高負荷による障害)であればレートリミットを設定するとか、Single points of failure (単一障害点によるシステム全体の障害) であればシンプルですがコンポーネントの冗長化などが例として挙げられています。

さいごに

本日は、AWS 規範ガイダンス「Resilience Analysis Framework」をしっかり読まなくても雰囲気だけでも伝わるようにまとめてみました。

私も AWS を学び始めた直後は、あまり深く考えずにとりあえずマルチ AZ にしとくのが良いのかなとか考えていたのですが、色々なワークロードやビジネス上の要件などからレジリエンスはどうするか考える必要がありますよね。
そのあたりの考え方の基準となるというか、言語化してくれてる気がします。このフレームワークは。
単純に適用して終わりというフレームワークではないのですが、レジリエンスを考える際に目を通すだけでもしておきたいですね。

ちなみに、AWS re:Invent 2023 のブレークアウトセッションのひとつ「A consistent approach to resilience analysis for critical workloads (ARC313)」では Resilience Analysis Framework の概要の説明、実案件での採用事例、AWS 組織内での採用事例など、フレームワークを活用した結果や例が紹介されています。

上記ではフレームワークを通してどういう分析が行われ、アーキテクチャーがどう変わったのかなどが紹介されており、よりイメージしやすいと思いますので、是非チェックしてみてください。