AWS CloudWatchでRDSのディスク容量の監視

AWS RDSのディスク残り容量をCloudWatchで監視し、しきい値を超えたSNSでアラームを飛ばす仕組みをCloudFormationで作成してみました。

前提

CloudFormationのテンプレート

CloudWatchのAlarmの設定をCloudFormationで作成しています。

ついでにCPU使用率も監視しています。

AWSTemplateFormatVersion: 2010-09-09

Parameters:
  SnsTopicName:
    Type: String
  DBInstanceIdentifier:
    Type: String
  FreeStorageSpaceThreshold:
    Type: Number
    Default: 18000000000 # 残り容量のしきい値。単位: byte
  CPUThreshold:
    Type: Number
    Default: 80

Resources:
  RDSDiskUsage:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmName: !Sub ALERT RDS ${DBInstanceIdentifier} - Free Storage Space
      Namespace: AWS/RDS
      Dimensions:
        - Name: DBInstanceIdentifier
          Value: !Ref DBInstanceIdentifier
      MetricName: FreeStorageSpace
      Statistic: Minimum # Average | Maximum | Minimum | SampleCount | Sum
      Period: 60
      EvaluationPeriods: 1 # 複数の連続するデータポイントがしきい値を超過することを条件としたい場合に2以上とする
      Threshold: !Ref FreeStorageSpaceThreshold
      ComparisonOperator: LessThanThreshold
      AlarmActions:
        - !Sub arn:aws:sns:${AWS::Region}:${AWS::AccountId}:${SnsTopicName}
      OKActions:
        - !Sub arn:aws:sns:${AWS::Region}:${AWS::AccountId}:${SnsTopicName}
  RDSCpuUtilization:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmName: !Sub ALERT RDS ${DBInstanceIdentifier} - CPU Utilization
      Namespace: AWS/RDS
      Dimensions:
        - Name: DBInstanceIdentifier
          Value: !Ref DBInstanceIdentifier
      MetricName: CPUUtilization
      Statistic: Average
      Period: 600
      EvaluationPeriods: 1
      Threshold: !Ref CPUThreshold
      ComparisonOperator: GreaterThanOrEqualToThreshold
      AlarmActions:
        - !Sub arn:aws:sns:${AWS::Region}:${AWS::AccountId}:${SnsTopicName}
      OKActions:
        - !Sub arn:aws:sns:${AWS::Region}:${AWS::AccountId}:${SnsTopicName}

CloudFormation実行例

$ aws cloudformation deploy --template-file template.yaml --stack-name rds-alarm --parameter-overrides SnsTopicName=xxxx DBInstanceIdentifier=xxxx

負荷をかけてアラームを飛ばしてみる

大量のレコードをインサートしまくる方法でPostgreSQLに負荷をかけてみました。IOがネックになりCPUの負荷は大きくは上がりませんので、CPUのしきい値は小さめの30などにしておきます。

$ aws cloudformation deploy --template-file template.yaml --stack-name rds-alarm --parameter-overrides SnsTopicName=xxxx DBInstanceIdentifier=xxxx CPUThreshold=30

※CloudFormationのテンプレートファイルのデフォルト値を書き換えただけだと更新できないことに注意。

大量のレコードとしては12万件の郵便番号のデータを使いました。

$ wget https://www.post.japanpost.jp/zipcode/dl/kogaki/zip/ken_all.zip
$ unzip ken_all.zip
$ nkf -Sw KEN_ALL.CSV > KEN_ALL_UTF8.csv

PostgreSQLに以下のテーブルを作成します。

create table sample1 (
    col01 text,
    col02 text,
    col03 text,
    col04 text,
    col05 text,
    col06 text,
    col07 text,
    col08 text,
    col09 text,
    col10 text,
    col11 text,
    col12 text,
    col13 text,
    col14 text,
    col15 text
);

以下のコマンドを複数のターミナルから4並列で動かしてみました。

$ for i in $(seq 1000); do echo $i; PGPASSWORD='xxxx' psql -h xxxx.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -U postgres -c '\copy sample1 from KEN_ALL_UTF8.csv with csv'; done

これでアラームが飛ぶはずです。

以下のスクリーンショットはCloudWatch Metricsでのグラフです。

f:id:suzuki-navi:20201031154434p:plain

f:id:suzuki-navi:20201031154451p:plain