NRIネットコム社員が様々な視点で、日々の気づきやナレッジを発信するメディアです

注目のタグ

    【Cfnテンプレートあり!】AWS監視をもっと自由に ! CloudWatch Metric Math活用術3選

    本記事は  オブザーバビリティウィーク  3日目の記事です。
    💻📄  2日目  ▶▶ 本記事 ▶▶  4日目  🔔🏢

    はじめに

    こんにちは!オブザーバビリティウィーク3日目担当の山本です!
    皆さんは、 AWS 環境に構築したシステムに監視を入れる際に Amazon CloudWatch(以後、CloudWatch)アラームの評価値はどのように設定しているでしょうか。 通常 CloudWatch メトリクスを閾値と比較することが多いですが、CloudWatch の Metric Math という機能を使うとメトリクスをもとにした柔軟な評価指標の設定が可能になります。
    本稿ではこの機能を使い、実務でも活用できるような評価指標の設定をご紹介します。

    Amazon CloudWatch Metric Math とは

    CloudWatch Metric Math は CloudWatch のメトリクスを使って数学的な計算を行い、新しい時系列データを生成する機能です。これにより、複数のメトリクスを組み合わせて、 ユーザーのニーズに合わせた監視が可能になります。作成した時系列データは CloudWatch コンソールで可視化し、ダッシュボードに追加できます。 代表的な関数としては SUM(合計)や AVG(平均)、IF(条件分岐)などが挙げられます。

    docs.aws.amazon.com

    実務で使える評価指標3選

    今回は実務でも効果的な評価指標とその指標を使った CloudWatch アラームを作成する CloudFormation テンプレートを3つ紹介します。
    ※以下で紹介する CloudFormation テンプレート例は CloudWatch アラームのみを作成するものとなっているため、通知が必要な場合は別途追加が必要です。

    ①移動平均を使った異常検知スコア

    メトリクスの現在値が通常の傾向(移動平均)からどれだけ離れているかを定量的に評価します。 移動平均とは対象期間を移動させながら、一定期間のメトリクスの平均値をとったものです。 乖離は単純な絶対値比較の他にパーセンテージでも評価するようなカスタマイズもできます。

    
    ABS(m1 - AVG(m1))
    
    

    ・m1:任意のメトリクス ※ABS(a):aの絶対値、AVG(a):メトリクスaの平均値

    ・活用例

    ユースケース メトリクス例 乖離が示すこと
    CPUスパイク検知 CPUUtilization 急な負荷上昇
    レスポンスタイム監視 TargetResponseTime UXの悪化兆候
    ネットワーク異常 NetworkIn/Out 通信量の急増・急減

    ・テンプレート例(EC2 の CPU スパイク検知)

    AWSTemplateFormatVersion: '2010-09-09'
    Resources:
      CPUDeviationAlarm:
        Type: AWS::CloudWatch::Alarm
        Properties:
          AlarmName: CPUDeviationAlarm
          AlarmDescription: "Alarm when CPU deviation exceeds threshold"
          EvaluationPeriods: 5
          Threshold: 20  # 偏差の閾値(任意の値を設定する)
          ComparisonOperator: GreaterThanThreshold
          TreatMissingData: notBreaching
          Metrics:
            - Id: m1
              MetricStat:
                Metric:
                  Namespace: AWS/EC2
                  MetricName: CPUUtilization
                  Dimensions:
                    - Name: InstanceId
                      Value: <--ここにインスタンスIDを入れる-->
                Period: 300
                Stat: Average
              ReturnData: false
            - Id: e1
              Expression: AVG(m1)
              Label: MovingAverage
              ReturnData: false
            - Id: e2
              Expression: ABS(m1 - e1)
              Label: Deviation
              ReturnData: true

    ②ALBのターゲットグループリクエスト集中度スコア

    ターゲットグループ間でのリクエスト分散の偏りを検出します。 負荷分散が正しくできていなかったり、DDoS攻撃やボットによるアクセス集中が生じているケースを早期に発見したい場合に有効です。
    ※ターゲットグループ内の個々のターゲット間の偏りを比較したい場合は、ターゲット側でメトリクスを収集し CloudWatch に送信するといった工夫が必要になります。

      
        MAX([RequestCount_Target1, RequestCount_Target2, ...]) - MIN([RequestCount_Target1, RequestCount_Target2, ...])
      
    

    ※MAX(a, b, c):a~bの中で最大の値、MIN(a, b, c):a~bの中で最小の値

    ・テンプレート例
    前提: ALB に2つのターゲットグループが設定されていること。

    AWSTemplateFormatVersion: '2010-09-09'
    Resources:
      ALBRequestConcentrationAlarm:
        Type: AWS::CloudWatch::Alarm
        Properties:
          AlarmName: ALBRequestConcentrationAlarm
          AlarmDescription: "Alarm when request count concentration between target groups exceeds threshold"
          EvaluationPeriods: 1
          Threshold: 100  # ← リクエスト数の偏差閾値(任意の値に設定する)
          ComparisonOperator: GreaterThanThreshold
          TreatMissingData: notBreaching
          Metrics:
            - Id: m1
              MetricStat:
                Metric:
                  Namespace: AWS/ApplicationELB
                  MetricName: RequestCount
                  Dimensions:
                    - Name: TargetGroup
                      Value: <--ここに1つ目のターゲットグループのARNを入れる-->
                    - Name: LoadBalancer
                      Value: <--ここにALBのARNを入れる-->
                Period: 60
                Stat: Sum
              ReturnData: false
            - Id: m2
              MetricStat:
                Metric:
                  Namespace: AWS/ApplicationELB
                  MetricName: RequestCount
                  Dimensions:
                    - Name: TargetGroup
                      Value: <--ここに2つ目のターゲットグループのARNを入れる-->
                    - Name: LoadBalancer
                      Value: <--ここにALBのARNを入れる-->
                Period: 60
                Stat: Sum
              ReturnData: false
            - Id: e1
              Expression: MAX([m1,m2]) - MIN([m1,m2])
              Label: RequestConcentration
              ReturnData: true

    ③アラーム感度スコア

    アラームが発火した回数を一定期間で合計したものを評価します。 これによって閾値が厳しすぎる(頻繁に超える)か、緩すぎる(ほとんど超えない)かを判断して閾値調整の参考に役立てることができます。

      
        SUM(IF(m1 > threshold, 1, 0))
      
    

    ・m1:任意のメトリクス
    ・threshold:評価対象アラームの閾値
    ※IF(a > b, 1, 0):a > bが正の時1をとり、負の時0をとる

    ・テンプレート例( EC2 の CPU 使用率を監視するアラームの感度を評価)

    AWSTemplateFormatVersion: '2010-09-09'
    Resources:
      CPUUtilizationBreachCountAlarm:
        Type: AWS::CloudWatch::Alarm
        Properties:
          AlarmName: CPUUtilizationBreachCountAlarm
          AlarmDescription: "Alarm when CPUUtilization exceeds threshold multiple times in a period"
          ComparisonOperator: GreaterThanThreshold
          EvaluationPeriods: 60
          Threshold: 5  # 閾値例:60分間で5回以上閾値を超えたら通知
          TreatMissingData: notBreaching
          Metrics:
            - Id: m1
              MetricStat:
                Metric:
                  Namespace: AWS/EC2
                  MetricName: CPUUtilization
                  Dimensions:
                    - Name: InstanceId
                      Value: <--ここにインスタンスIDを入れる-->
                Period: 60  # 1分ごとのデータ
                Stat: Average
              ReturnData: false
            - Id: e1
              Expression: IF(m1 > <--ここに評価対象のアラームで設定されている閾値を入れる-->, 1, 0) 
              Label: BreachFlag
              ReturnData: false
            - Id: sumBreach
              Expression: SUM([e1])
              Label: BreachCountOverPeriod
              ReturnData: true

    おわりに

    このように CloudWatch Metric Math を使えばアイデア次第で有用な評価指標を設定することができます。 システム監視には欠かせない CloudWatch アラームですが、ただただ監視する項目を増やすだけでは観測できる範囲は広まるものの運用負荷が増加する一方です。 したがって、運用に適切な評価指標を設定することやアラームの見直しを定期的に行い、より負荷を軽減させられるようなカスタマイズをしていくことが大切です。 日々変化するシステム環境に合わせて、アラームも“育てていく”意識が、持続可能な運用の鍵となるでしょう。

    執筆者 : 山本将望
    食べることが生きがいのインフラエンジニア
    執筆記事一覧 : https://tech.nri-net.com/archive/author/m4-yamamoto