ABEJA Tech Blog

中の人の興味のある情報を発信していきます

AWSのAZ障害でもサービスを継続させる技術

こんにちは。ABEJAのインフラ管理してる村主 @rwle1221 です。

本ブログは ABEJA Advent Calendar 2019 の11日目です。

今日は、みなさん記憶に新しい2019年8月末に発生した AWS の東京リージョンの AZ 障害について、どのようにしていればサービス影響を与えずにシステムを稼働させられたのか。という話をしたいと思います。

振り返り

障害の詳細報告はこちら

aws.amazon.com

有志によるまとめはこちらから

piyolog.hatenadiary.jp

基本は「AZレベルで冗長化していれば問題ない」

中の人に聞くと「AZレベルで冗長化していれば問題ない」とのことでした。 しかし、2番目の方の記事を見ると有名どころのサービスが割と止まっていました。 じゃあ上で紹介されていたような会社がAZレベルの冗長化が出来ていなかったのか。

※ ALB/WAFの組み合わせでバグはあるという話もあるので、それは多分バグです。もう直ってると思うので今回のスコープからは外します

風の噂によると、ちゃんとしないといけない部分はAZレベル(もしくはリージョンレベル)で冗長化していたが、付随するアプリケーションでAZレベルの冗長化が出来ておらずダウンしたそうな。

どこまで冗長化するかはコストとのバランスなので、サービス停止=ダメというのは早計だということは始めにお伝えしておきます。

弊社の ABEJA Platform というサービスはダウンしませんでした

弊社はAWSの「Machine Learningコンピテンシー」というものを取得し、テックパートナーになっています。 MLコンピテンシーは、Machine Learningの事例があり、且つ該当プロダクトは Well-Architected に準拠していることが求められています。

Well-Architected に準拠しているかはAWSのソリューションアーキテクトにレビューいただきます。その甲斐あってか、弊社ではサービスダウンは発生しませんでした。

その経験を元に、どうすれば良かったのかというのを考えていきたいと思います。

どうすれば障害は防げたのか

Multi AZ 構成でも設定によっては安全とは言い切れない

端的に言えば前述の通り「AZレベルで冗長化していれば問題ない」です。 しかし、利用するコンポーネントが増えれば増えるほど気にする箇所がかなり多くなります。(後述します)

例えば「ALB/EC2/RDSの構成でMulti AZを構成してます!」というのはよくあります。これは安全でしょうか?実は設定によっては安全とは言い切れません。

  • ELB / ALB
    • スティッキーセッションを利用していたため、リクエストが障害のあるAZに振り続けられた
    • ヘルスチェック の感覚が長すぎて一定期間「Down」と認識されなかった
  • EC2
    • AutoScalingを設定しているが、サブネットが分散されていなかった
    • AutoScalingを設定しているが、コスト節約のためインスタンスが1台で一定期間停止した
  • RDS
    • 自動でフェイルオーバーを行ったが、Connection Pooling を利用していて再接続が行われずに、フェイルオーバー前の障害のあるRDSインスタンスに接続しにいっていた
    • 自動でフェイルオーバーを行ったが、MySQLクライアントがRDSのIPアドレスをキャッシュしていたため(DNSではなくIPアドレスで接続している場合も同様)、フェイルオーバー前の障害のあるRDSインスタンスに接続しにいっていた

前提を変えればもっと色々ありますが、とりあえずパッと出てくるところだけでもこんな感じです。RDS周りは特によく聞く話です。 でも、この中でも障害として見るのか、許容するのかは「定義次第」なものがあります。

「障害」は「定義次第」

例えば、「AutoScalingを設定しているが、コスト節約のためインスタンスが1台で一定期間停止した」 これは、うまく設定していると恐らく5分10分程度でインスタンスが立ち上がってきます。

例えば「1ヶ月の稼働率(SLO/SLAなど)は99.95%を満たすこと」と定義していた場合、約21分/月の停止は許容することになります。その場合は、5分10分のサービスはダウンしますが、障害ではありません。冗長化する場合の2台分のコストとサービスのレベルのバランスを取った正しい設計が成されています。

RDSに関しても、Multi-AZ を組んでいても無停止なわけではありません。フェイルオーバー中は切り替えによる数分間の接続断は有り得ます。

ということは数分間のサービス断は許容する必要があり、何を持って障害とするか定める必要はあります。 もし瞬断も許されない仕組みなら止まらない前提な超堅牢な仕組みを利用すれば良いですが、ほとんどのケースにおいて、コストとのバランスを問われると思います。

コストとのバランスでサービス停止の許容範囲を決める=その範囲外は障害

なので「このサービスは、どれくらいのサービス停止は許容できるのか」から始まります。

弊社の場合は、API部分はDBの停止など数分間の接続断は有り得るので、基本はリクエストを投げてもリトライ前提で仕組みを組んでもらうようなコミュニケーションを取っています。

コーポレートサイトは 10分、20分停止しても誰も困らないので 数十分止まっても良い前提で仕組みを作っています。 WordPressなのですが、冗長化するのが面倒で工数含めたコスパ合わないし、冗長化したとしてもそんな変な仕組みを誰かに渡したくもなかったので、シングル前提で作っていました。現にAWSのAZ障害時は巻き込まれて 20分位サービス停止しましたが、想定内なので特に問題はありません。

ここまでのまとめ

  • AZレベルで冗長化すると問題ない
  • 設定によりAZレベルの冗長化が損なわれることも
  • コンポーネントが増えると気にする部分が増える
  • 「このサービスは、どれくらいの停止は許容できるのか」の定義から始める

まず「どれくらいの停止は許容できるのか」定義は出来た。次にすることは?

次は利用するコンポーネントを選択する

もちろん機能要件はあるのですが、一旦耐障害性という面でみていきます。

「コンポーネントが多くなると気にする箇所が増えるんでしょ?じゃあフルEC2!」

おいおい。AWSさんがマネージドしてくれるから楽になってるんじゃん。自ら気にする箇所増やすなよ。「自分で作ると言うことは理解した上で使う」ってことだよ。

「じゃあ、フルマネージドで気にするところがないサーバレス!」

確かにサーバレスだとインフラ面やAZ面なんてのは気にする必要はなくなるね!

ただ一概にサーバレスで解決するかと言うと難しい。例えばAZが丸ごと1個落ちるような障害だと、恐らくLambdaは片方のAZを自動で切り落として稼働し、僕たちは気づかずに利用できるかもしれない。

しかし、ネットワークに問題がありEBSへのアクセスの遅延が発生していたという情報もあった。その場合はLambdaも(恐らくEC2上で動いているから)漏れなく影響受けるでしょう。AWSさんがEBSへの遅延を検知してフェイルオーバーしてくれるかもしれない。でもしてくれないかもしれない。してくれない場合はどうなる?何も手出し出来ないので、AWSさんがなんとかしてくれるまで待つしかない。いつ対応が終わるのだろう。

USリージョンではS3が障害起きたり、DynamoDBが障害起きたりする。手の出しようがない。

つまり、フルマネージドが過ぎるとアンコントローラブルになる。

それならAZレベルでコントローラブルなサービスの方が、まだ対応しやすい。という考え方もある。

とはいえ、自分たちでやるより世界レベルで対応しているAWSさんの方が対応が早いかもしれないし、再発防止策は僕たちで考えなくてもやってくれるので、非常に楽ではある。

つまり言いたいことは「ちゃんと考えましょう」

  • フルマネージド中心にして、AWSさんに任せるところは任せましょう
  • コントロールできないと困るところはちゃんと自分で握りましょう

「利用するコンポーネントを絞って選択した」次にすることは

そのコンポーネントの一部が停止することを想定します。どのように復旧させられるか、どの程度時間がかかるのかを考えましょう。 もちろん考えるだけじゃなくて、試す。実際に。

  • AutoScalingGroupの場合
    • ALBから切り離される時間は?(ヘルスチェック間隔)
    • EC2が起動してくるまでの間の負荷は?(例: 10台 → 5台に減った時に負荷に耐えられるのか)
  • ALBの場合
    • サブネットを3AZに分散した際に、1AZのALBが死んだ時はどのような挙動になるのか
  • RDSの場合
    • フェイルオーバーにかかる時間は?
  • その他
    • 他のサービスでEC2ベースで内部実装のイメージが出来れば、だいたい他のサービスもどのように動いているのか想像できるので、どこに問題が発生しそうかは検討つきます

これらが許容範囲内なのかを確認し、許容範囲内であればそのまま利用します。許容範囲外なら収まるような案をAWSさんに相談してみましょう。

「障害の定義が決まり、利用するコンポーネントも決まり、許容範囲だった」じゃあ次は

そのサービスのBlackBeltを熟読します。特に障害周りの情報を確認します。 気を付けるポイントはほとんどそこに書いてあります。良スライドです。疑問に思ったモノがあればメモって公式ドキュメントを確認しましょう。

aws.amazon.com

時間がなかったり、公式ドキュメント読んでもわからない場合は、担当SAさんもしくは AWS Loft で相談してみるのも有りかもです。たぶん優しく答えてくれます。

「だいたいわかった!」次は?

「Now Go build!」 or 「Go Chaos Engineering!」

f:id:xwkns157:20191210114438p:plain

最後に ステマ

「いやいや、そんなこと言ってもすぐに覚えて使えないわ」って言う方。安心してください。 「AWS認定ソリューションアーキテクト プロフェッショナル」の認定資格を持っているとこれくらいは当たり前です。

その第一歩である「AWS認定ソリューションアーキテクト アソシエイト」から取得してみるのは如何でしょうか。 アソシエイト試験を学ぶことで、体系的に全体的に理解が深まり、AWSがどのような構成を取って欲しいのかがわかります。

ぜひ、以下の本を手に取っていただき資格取得を目指していただければと思います。(他の方の本もオススメです!特にオレンジの..)

ABEJAではイケてるしヤバい人材募集中です!最新の研究成果をキャッチアップしつつ実際のサービスを開発してみたい方・インターンに興味がある方がいれば、ぜひご連絡くださいー

採用情報一覧は以下↓

hrmos.co

www.wantedly.com

ABEJAの中の人と話ししたい!オフィス見学してみたいも随時受け付けておりますので、気軽にポチッとどうぞ↓↓