Query Insights はいいぞ!SREのとあるデータベースのインシデント対応
つい先日データベースの負荷が急激に上昇したのを気にレイテンシーが悪化し続けるインシデントがありました。その対応過程とCloudSQL Query Insightsがどのように役に立ったかまとめます。
こんにちは Typoが治らない @sakajunquality です
Site Reliability Engineeringしてますか??
ブーメランが突き刺さりそうなのでこれ以上やめておきます。
さて今日の内容ですが、先日とある理由で弊社のtoC向けサービスにアクセスが集中し(通常の数倍程度のトラフィック増加)、一時リクエストが捌けなくなるインシデントがありました。検知から対応までSREがどのように動いたか、またQuery Insightsがどのように役に立ったかまとめます。
インシデントの検知
まず使用しているデータベースの負荷の上昇アラートが来ました。(残念ながらSLO低下やError Budget超過のようなかっこいいアラートではありません)
このデータベースについて
少し本筋とはずれてしまいますが、このサービスはデータベースにCloudSQL for PostgreSQLというPostgreSQLのマネージドサービスを利用しています。最近のアップデートで機能が拡充しているものの、スケールアップをするには再起動を含む数分のダウンタイムが必要です。
toC(一般の方向けの)サービスのため、いきなアクセスが増加することもありますし(実際過去に数回テレビに取り上げていただくこともありました)、医療ということでクリティカルな局面で使っていただくこともありちょっとしたダウンタイムもできるだけ避けたいところです。
そこで普段このデータベースは過剰にプロビジョニングをしています。CPU使用率が多くてもざっくり20%程度に収まるようにしています。そのためこのアラートはほとんど発火することはありません。
影響調査
さて本題に戻りますが、次に実際にどのようなユーザー影響があるか見てみます。極端な話データベースの負荷が貼り付いていても、リクエストを正常に捌けていれば問題ありません(そんなことはほとんどないと思いますが)。
ダッシュボードでこのサービスのトラフィックを確認したところ、レイテンシーが相当悪化し始めてました。
また、インフラでのリトライも動いておりユーザーがほとんどまともに使えてないことが推測できました。
しかし、トラフィックの総量は普段の数倍程度で、数十倍耐えられるとは言わないものの少し疑問が残ります。普通にもう少し耐えてほしいw
一次対応
いずれにしろサービス全体が正常に利用することができないため、一次対応としてデータベースのスケールアップを行いました。
コネクション数やメモリには余裕があったのでCPUだけ増やしました。前述の通り1回スケールアップするのに数分のダウンタイムが発生するため多少過剰気味にリソースを増やします。
このとき勢い良くスケールアップしようとしましたが、冷静な @kamina-zzz がメモリとコネクションは全然開いてると指摘してくれてCPUだけ増やしましたw
根本対応
その後様子を見ていると、かなり増強したにもかかわらずCPU使用率が50%近くを推移していました。取り急ぎユーザーにはレスポンスを返せるようになったので一次対応としてはいいのですが、これ以上の負荷が心配です(当然課金も心配)。
そもそもここまでCPUバウンドになっているのも気がかりです。そこで、データベースのクエリについて深堀りをすることにしました。
Query Insights について
CloudSQL for PostgresQLには Query Insights というものがあり、クエリごとの統計情報や、クエリごとにサンプリングした詳細を見ることができます。
弊社のSREでは Observability をテーマの1つに掲げていて、各レイヤーで何が起こっているのかを観測できるようにいろんな施策を行っています。@kamina-zzz がそのち分散トレーシングについてまとめてくれると思います。データベースについてもObservability の例外ではありません。Query Insightsが発表されてから軽く調べ、@itkq が入社してすぐに検証をして本番まで展開を行いました。(ちなみに terraform provider 対応も彼が行いましたw)
また本題に戻りますが、このインシデント発生時のQuery Insightを見るとデータベース全体で、CPUバウンドの負荷がかかっていることがわかります。
そしてクエリ一覧でレスポンスが遅く、頻繁に実行されているクエリを見つけます。
犯人!?
さぞ複雑なクエリだろうと、思ってクエリを見てみると、実にシンプルなクエリを実行していました
普通によくあるやつでは!? と思うもののこれはもしや…
ということで古来からの文明みんな大好き EXPLAIN を見てみます。
勘のいい読者の方はお気づきかもしれませんが結論は、インデックスがありませんでした。
そこで少しトラフィックが落ち着くのを見計らってインデックスを貼ったっか当然のごとくCPU使用率はゼロになりました。一件落着。
Clean-up
過剰ということがわかったのでスケールアップしたデータベースはスケールダウンするメンテナンスを後日行いました。
まとめ
対応としては即座のデータベースのスケールアップ判断、それと並行したアプリケーションの変更調査、クエリー調査により、比較的MTTRも短く復旧できたので良かったと思います。
最後にトラフィックの状況とデータベースの負荷を並べてみました
Takeaways
インシデント対応の一連の流れを紹介しました。
当たり前ですが、ある程度インフラに余裕をもたせ大型のトラフィックに備えていても、実際にそのトラフィックに耐えられるわけではありません。
価値検証も含めほぼ毎日リリースを行っているようなスタートアップのプロダクトでは、コストやパフォーマンスの過度な最適化を行うよりも、限られたリソースである程度のパフォーマンスを維持しつつ、リリースを安定してできることが非常に重要だと思っています。
そんな中で、Query Insightsはクエリの中で許容範囲を超えたものから対応するなどコスパよくパフォーマンスを改善したり、今回のようなインシデント時の調査にも役に立つので重宝しています。
Cloud SQLを利用している方は、Query Insightsを是非検証してみてください。クエリの改善が非常にやりやすくなります。価格やパフォーマンス影響については公式ドキュメントをご覧ください。弊社としてはそれをすべて加味しても入れる価値があると判断しました。
余談
これは少し蛇足になりますが、SREというと世の中的には某銀行ドラマを思い出す方もいるかも知れませんが大抵全く異なるので、社内外にしっかりとアウトプットしていくと良いかもしれません。