CPUなどのリソース監視をする際にノイジーアラートを抑制するために普段とっている基本的な方針のメモです。
ノイジーアラートは抑制しないといけない
監視の文脈でノイジーアラートという言葉があります。システム監視において対応不要なアラートが大量に発生し、重要なアラートを見逃すリスクを高める現象を指す言葉です。ノイジーアラートをいかに抑制するかは監視設計の重要な要素です。
ノイジーアラートを見つけたら即改善というのは、監視におけるファーストアクションとして日々経験を積み重ねることができます。
リソースの監視
リソース監視は監視の文脈においてアラートとして不適切といわれることがあります。例えば、アラートはシステムの状態を示すものであり、CPUの監視はシステムの状態を示すものではない、だからCPU監視をとりあえず行うというのはおかしいという文脈が多いようです。少し考えてみましょう。
そもそもCPUやメモリはシステム稼働の監視対象としてはユーザー体験を直接示す指標ではありません。仮にCPU100%でも応答速度が十分早めければシステムとしては問題ありません。CPU50%でも応答速度が劣化する状況ならばシステムとしては問題です。このように、CPUからシステムの状態を直接推し測るだけの関連性を見出すことは難しく、これはI/Oボトルネック1やバッチ等2では概ね共通しているようです3。
とはいえ、応答速度などユーザー体験を直接示す監視は最重要情報として、CPUやメモリの監視は補足情報になりえます。システムにおいて「どの程度の優先度アラートか」はおいておいても、CPUやメモリがあまりに異常な状態ならアラートを発生させることに意義はあるでしょう。おそらくCPUアラートが出るときには、レスポンスタイム悪化などより重要なアラートが出ているでしょうから。
CPUの監視
CPU監視の特徴として、CPUの使用率は瞬時に変動することが多いです。例えばCPUの使用率が瞬時に上昇しても、その後すぐに下がるような状況が発生しえます。CPUの性質を監視する際、単純な閾値監視ではノイジーアラートとして過剰検出しやすいです。
メモリの監視
メモリの監視はCPUとは異なる側面があります。それはOOMの存在です。メモリが不足するとOSがプロセスを強制終了させるため、メモリの監視はシステム安定性に直接かかわる重要な監視対象です。CPUとは別軸で捉える側面があるんですね。ただ、スケールアウトを前提としたシステムでは、1部サーバーがOOMで強制終了してもシステム全体として異常が生じないなら問題ありません。一方で、インメモリで処理をするサーバーではOOMはシステム障害と直結します。アプリケーションの性質によって重要度が変わるのでシステムにとってどのような立ち位置かを考える必要があります。
メモリはアプリケーションの性質にも寄りますが、ある程度段階的にメモリが変動しつつ、GCなどで一気にメモリ解放されることがあります。変動のしやすさで見るとCPUとよく似た側面があるのですが、一定の値を超えたらアウトというのが違います。
リソースにはそれぞれ特徴があり、キリがないのでここまで。
ノイジーアラートを抑えたリソース監視
CPUを例にDatadogをベースに説明しますが、他の監視ツールでも同様のコンセプトでやっています。
CPUは振れ幅が激しくなりやすいため、CPU監視には以下のようなアプローチが有効です。
- 値は
average
かmedian
を用いる4 - 期間の
average
を用いる - 期間を短くしすぎない
- 期間中ずっと超える条件にする
順に見ていきましょう。
値はaverage
かmedian
を用いる
システムの瞬間負荷が大きかったらまずいんじゃない?と頭をよぎることはないでしょうか。この考えに基づくと値のmax
を用いたくなりますが、これはノイジーアラートを招きやすいです。
システムに対する瞬間的な負荷ではなく継続した高負荷こそが障害トリガーになるケースが多いため、average
かmedian
を用いることでノイジーアラートを抑制できます。
期間のaverage
を用いる
値を取得したら、期間中の値をどう評価するか決定する必要があります。期間中にCPU使用率が閾値を予想より超えたらアウト!と思ってしまうとmax
を用いたくなりますが、これはノイジーアラートを招きやすいです。
先ほど同様に継続した高負荷こそが障害トリガーになるケースが多いため、期間のaverage
を用いることでノイジーアラートを抑制できます。
期間を短くしすぎない
期間を5minなど短くしすぎると、5min中にCPU使用率が高くなった瞬間でアラートが発生してしまいます。CPU使用率って面白くて、少し高負荷が続いてもすぐに下がることも多く、このような状況でアラートが発生するとノイジーアラートになりやすいです。
逆に、期間を長くしすぎると、障害が発生してからアラート発生として検知するまでの時間が長くなります。このため期間は適切に...となるのですが、システムに応じてってなりやすいですよね。
私は15min程度に設定することが多いです。15min継続して閾値を超えているというのはスケールアウトも効いていない可能性があり十分異常を示せています。これはWebやAPI、ワーカーなど色々なアプリケーション動作形態においてノイズにならず適切なケースが多いです。5
期間中ずっと超える条件にする
Datadogは、アラートデフォルト設定で期間中一度でも超えたらアラート発生という設定Do not require a full window of data for evaluation
になっています。これはノイジーアラートを招きやすいです。
先ほど同様に、継続した高負荷こそが障害トリガーになるケースが多いため、期間中ずっと条件を満たした場合アラートRequire a full window of data for evaluation
という設定にすることでノイジーアラートを抑制できます。
Datadogモニターの設定例
ノイジーアラートを抑制しつつCPU監視するDatadogのモニター設定例を示します。
まとめ
あくまで一例ですが、DB系も似た考え方を基本にアラートを設定するのがよいでしょう。移動平均とかも使うの検討してもいいのですが、検知が遅れると意味がないのでスムース系はアラートにあまり向いていないです。
監視に関する考え方は、入門 監視が良いです。2019年の本なため一部内容が古かったりしますが、監視の基本的な考え方として参考になります。
参考
- Web、APIをはじめ、データベース・ネットワーク・ストレージが支配的なシステムはCPU使用率を監視しても有益でないケースが多い↩
- バッチ処理や非リアルタイムなジョブ処理は、一時的にCPU使用率が100%になっても問題にならない場合が多い↩
- CPUボトルネックなアプリケーションである動画処理、機械学習、シミュレータは、CPU使用率が高いとパフォーマンス低下に結びつきやすく、CPU使用率を監視に意義がある↩
-
個人的には
average
を使うことが多いです。median
はavg
よりも外れ値に強いですが、avg
の方が直感的に理解しやすくAWSなど多くの監視指標と合致します。↩ - 5minとかの短期間の高負荷は、メトリクスやAPMなどでみればいいので、監視上は15minなどでいいという発想です↩