はじめに
自身のトラブル案件の経験を元に今あるシステムはどうあるべきなのかを検討し、その経験をウェビナーで講演しました。このようなトラブルを経験する方が今後少なくなる為にも、私の実体験をまとめておきます。
きっかけ
既に運用中のシステムで、ある日スパイクアクセスがあった事で、本来対応できるはずのアクセス数が対応できずにシステムがダウンするという障害がありました。
これだけ聞くとよくある話じゃんと思う方もいるかもしれませんが。
よくある話の中でも色々経験できたのでまとめておきます。
システム構成図
よくあるWeb三層構造のシステム構成図です。
フロントにロードバランサーがあり、Web/APサーバはAutoScaling構成で、バックエンドにDBを持っています。
トラブった原因
主な原因としてはDBのバージョン依存のバグでした。
Aurora MySQL v2.11.1 の利を利用していたのですが、このバージョンには接続高騰時にaborted Connection とりエラーとなってしまう問題を孕んでおりました。これによってスパイクアクセス時にEC2→DB間の接続がうまくいかず、結果としてEC2の負荷が高騰、LBのヘルスチェックに失敗するのでAutoScalingのループという無限ループに陥ってしまいました。
https://docs.aws.amazon.com/AmazonRDS/latest/AuroraMySQLReleaseNotes/AuroraMySQL.Updates.2111.html
どう立ち直ったのか
ヘルスチェックが要因となりAutoScalingの無限ループになっていたのでヘルスチェックを解除したところAutoScalingのループは止まりユーザからのリクエストが処理され始めました。
ちなみにお浚いですが、AutoScalingにはヘルスチェックタイプが3つあります。
このシステムにおいてはElasitc Load Balancingのヘルスチェックを採用しておりました。
ここでまた問題発生
トラブルの原因究明において何よりも重要なのはログですが、問題だったのはこのシステムログがほとんど取れてなかったので、AWSサポートに調査依頼を投げるにも数少ない状況証拠を投げていくしかなくなってしまいました。。
泣きっ面に蜂とはまさにこのことですね。
学んだ事
運用系の言葉で「オブザーバビリティ(可観測性)」という言葉をよく耳にしますが、まさにこれって重要で例えリアルタイムに観測はできなくとも、後から追える状態の仕組みを導入しておく事は改めて必要だと今回のような障害を通して学びなおしました。その上でAWSで今回のシステムに対してオブザーバビリティのアプローチをするのであればどのような事が重要なのかをまとめたので書きたいと思います。
AuroScaling(EC2)
EC2においてはアプローチ手法は多々ありますが、有名どこで攻めるとまずはCloudWatch Agentを入れる方法。その他であればライフサイクルフックを入れてTerminate時にログを退避しておく方法。リアルタイムを求めるのであればKinesis Agentかfluentd(td-agent)入れておくアプローチがあります。
Aurora
Auroraは改めて調べていてビックリしたのですが、こんなに取れるログがあります。
その中でも主にAWSサポートとやり取りをしていて、これはマストで有効化したほうがいいというログは赤字にしてます。
まとめ
AWS Well-Architected Flamework の信頼性の柱にもある通り、障害は起こしたくなくても起きてしまうものです。(Design for Failur)問題はそこからどう調査し、ユーザビリティを失わないように早急に復旧できるかにかかっているので、その為の仕組みをシステムに組み込んでおく事が何よりも重要です。
また、どこが原因か分からない時は、自分のDBやOSのリリースノートを確認し、重大なバグがないかチェックする癖をつけておくことも大事だと今回の障害を体験して学びました。このメモが誰かの役に立てば幸いです。
講演資料
ウェビナーで登壇した際の資料まとめておりますので、興味がありましたらご参照ください。