RDS for SQL Server に CloudWatch の推奨事項に従ったアラームと閾値を設計してみた

2024.06.20

いわさです。

Amazon CloudWatch のアラーム機能を使うことで、リソースメトリクスを監視し、通知やアクションを発生させることが出来ます。
今回 Amazon RDS の SQL Server インスタンスに対して監視アラートの設定を行う機会があったのですが、運用前ということもありまずは何かしらの基準でしきい値を決めてスタートし、運用しながら調整するパターンを取りたいと考えていました。

そこで、半年程前に登場した CloudWatch の推奨アラームという機能を活用することにしました。

RDS for SQL Server を対象に「アラームに関する推奨事項」を ON にしてみると次の 9 個の項目が表示されます。

今回はこちらをベースに、AWS 公式ドキュメントにも記載されている推奨事項や、あるいは推奨アラームに関しても閾値についてすべて固定ではなくワークロードの条件にあわせて調整しなければいけない部分があるので、そのあたりを少し検討してみましたので、その過程的なところを紹介したいと思います。

Amazon RDS の監視推奨項目(公式ドキュメント)はこれ

まず、次の公式ドキュメントに「ベストプラクティスアラーム」という形でサービスごとの推奨項目が列挙されています。

CloudWatch メトリクスの監視や AWS WAF のルールなどは、ワークロードに最適なものを最初から決めるのは非常に難易度が高いと思ってまして、標準から初めて運用開始しながら閾値やルールを調整・運用しなければいけない部分だと思っています。

その、まず開始するための「標準」にこの推奨事項を使わせてもらいましょう。
上記ドキュメントから Amazon RDS の推奨事項を抜粋したものが以下となります。

アラーム 推奨対象 目的
CPUUtilization 全般 このアラームは、非常に高い応答時間とタイムアウトを防ぐために、一貫して高い CPU 使用率を検出するために使用されます。CPU 使用率のマイクロバーストをチェックする場合は、アラーム評価時間を短く設定できます。
DatabaseConnections 全般 このアラームは、最大数のDB接続に達したときに接続が拒否されるのを防ぐために使用されます。DB インスタンスクラスを頻繁に変更する場合は、このアラームをお勧めしません。
EBSByteBalance% Aurora PostgreSQL以外 このアラームは、バースト バケットのスループット クレジットの残量が少ないことを検出するために使用されます。バイト残高パーセンテージが低いと、スループットのボトルネック問題が発生する可能性があります。Aurora PostgreSQL インスタンスには、このアラームをお勧めしません。
EBSIOBalance% Aurora以外 このアラームは、バースト バケットの I/O クレジットの残量が少ないことを検出するために使用されます。IOPS 残高パーセンテージが低いと、IOPS のボトルネック問題が発生する可能性があります。Aurora インスタンスには、このアラームをお勧めしません。
FreeableMemory 全般 このアラームは、メモリ不足による接続の拒否を防ぐために使用されます。
FreeLocalStorage Aurora このアラームは、Aurora DB インスタンスがローカルストレージの制限に達する寸前を検出するために使用されます(Aurora Serverless v2 以降を使用していない場合)。一時テーブルやログファイルなどの非永続データをローカルストレージに格納すると、ローカルストレージが容量に達する可能性があります。このアラームは、DB インスタンスがローカルストレージ不足でエラーが発生するのを防ぐことができます。
FreeStorageSpace 全般 このアラームは、ストレージ不足の問題を防ぐために使用されます。これにより、データベースインスタンスがストレージ容量を使い切ったときに発生するダウンタイムを防ぐことができます。ストレージの自動スケーリングが有効になっている場合や、データベースインスタンスのストレージ容量を頻繁に変更する場合は、このアラームを使用しないことをお勧めします。
MaximumUsedTransactionIDs PostgreSQL このアラームは、PostgreSQL のトランザクション ID の巻き戻しを防ぐために使用されます。
ReadLatency 全般 このアラームは、読み取りレイテンシが高いことを検出するために使用されます。通常、データベースのディスクは低い読み書きレイテンシを持ちますが、高レイテンシの操作を引き起こす問題が発生する可能性があります。
ReplicaLag PostgreSQL このアラームは、プライマリインスタンスの障害時に発生する可能性のあるデータ損失を検出するために使用できます。レプリカがプライマリから大幅に遅れている場合、プライマリが障害を起こすと、レプリカにはプライマリインスタンスにあった情報が欠落する可能性があります。
WriteLatency 全般 このアラームは、書き込みレイテンシが高いことを検出するために使用されます。データベースのディスクは通常、低い読み取り/書き込みレイテンシを持ちますが、高レイテンシ操作を引き起こす問題が発生する可能性があります。これを監視することで、ディスクのレイテンシが期待どおりに低いことを確認できます。
DBLoad 全般 このアラームは、高い DB ロードを検出するために使用されます。高い DB ロードは、DB インスタンスのパフォーマンス問題を引き起こす可能性があります。このアラームはサーバーレス DB インスタンスには適用されません。
AuroraVolumeBytesLeftTotal Aurora MySQL このアラームは、Aurora クラスターがボリュームサイズ制限に近づいていることを検出するために使用されます。このアラームは、クラスターがストレージを使い果たしたときに発生するスペース不足のエラーを防ぐことができます。このアラームは Aurora MySQL にのみ推奨されます。
AuroraBinlogReplicaLag Aurora MySQL(ライターのみ) このアラームは、ライター インスタンスがエラー状態にあり、ソースをレプリケートできないことを検出するために使用されます。このアラームは Aurora MySQL にのみ推奨されます。
BlockedTransactions Aurora MySQL このアラームは、Aurora DB インスタンスでブロックされたトランザクションの数が多いことを検出するために使用されます。これにより、トランザクションのロールバックとパフォーマンスの低下を防ぐことができます。
BufferCacheHitRatio Aurora このアラームは、Aurora インスタンスの一貫した低いキャッシュ ヒット率を検出するために使用されます。これにより、Aurora インスタンスの持続的なパフォーマンス低下を防ぐことができます。
EngineUptime Aurora(ライターのみ) このアラームは、Aurora ライター DB インスタンスがダウンしていることを検出するために使用されます。これにより、クラッシュやフェイルオーバーによって発生する、ライター インスタンスの長期的な障害を防ぐことができます。
RollbackSegmentHistoryListLength Aurora MySQL このアラームは、一貫して高いロールバック セグメント履歴の長さを検出するために使用されます。これにより、Aurora インスタンスの持続的なパフォーマンス低下と高 CPU 使用率を防ぐことができます。このアラームは Aurora MySQL にのみ推奨されます。
StorageNetworkThroughput Aurora(ライター) このアラームは、ストレージネットワークスループットが高いことを検出するために使用されます。高スループットを検出することで、ネットワークパケットのドロップとパフォーマンスの低下を防ぐことができます。

19個もありますね!
CloudWatch の推奨事項アラーム機能の9個よりも増えてしまった。なぜ。

その中で SQL Server が対象になるものはこれ

上記項目はよく説明文などを見て頂くと、「Aurora MySQL だけ」「PostgreSQL のみ」など、特にデータベースエンジンによって要不要が変わる部分があります。なるほど。

この中から SQL Server が対象となるであろう項目でさらにフィルターをかけると次の9個になりました。

アラーム 推奨対象 目的 統計 推奨しきい値 しきい値の決め方 期間 アラームを発するデータポイント 比較演算子
CPUUtilization 全般 このアラームは、非常に高い応答時間とタイムアウトを防ぐために、一貫して高い CPU 使用率を検出するために使用されます。CPU 使用率のマイクロバーストをチェックする場合は、アラーム評価時間を短く設定できます。 平均値 90 CPU の消費スパイクはデータベースのパフォーマンスを阻害しない可能性がありますが、持続的に高い CPU は今後のデータベースリクエストを妨げる可能性があります。全体的なデータベースワークロードに応じて、RDS/Aurora インスタンスの高い CPU はオーバーオールのパフォーマンスを低下させる可能性があります。 1分 5/5 より大きい
DatabaseConnections 全般 このアラームは、最大数のDB接続に達したときに接続が拒否されるのを防ぐために使用されます。DB インスタンスクラスを頻繁に変更する場合は、このアラームをお勧めしません。 平均値 ワークロードに依存 許可される接続数は、DB インスタンスクラスのサイズとデータベースエンジン固有のパラメータ(プロセス/接続に関連するもの)にワークロードに依存。最大接続数の 90-95% の値を計算し、それをしきい値として使用することをお勧めします。 1分 5/5 より大きい
EBSByteBalance% Aurora PostgreSQL以外 このアラームは、バースト バケットのスループット クレジットの残量が少ないことを検出するために使用されます。バイト残高パーセンテージが低いと、スループットのボトルネック問題が発生する可能性があります。Aurora PostgreSQL インスタンスには、このアラームをお勧めしません。 平均値 10 10% 未満のスループット クレジット残高は良くないと考えられ、それに応じてしきい値を設定する必要があります。ワークロードに低いスループットを許容できる場合は、さらに低いしきい値を設定することもできます。 1分 3/3 より低い
EBSIOBalance% Aurora以外 このアラームは、バースト バケットの I/O クレジットの残量が少ないことを検出するために使用されます。IOPS 残高パーセンテージが低いと、IOPS のボトルネック問題が発生する可能性があります。Aurora インスタンスには、このアラームをお勧めしません。 平均値 10 10% 未満の IOPS クレジット残高は良くないと考えられ、それに応じてしきい値を設定する必要があります。ワークロードに低い IOPS を許容できる場合は、さらに低いしきい値を設定することもできます。 1分 3/3 より低い
FreeableMemory 全般 このアラームは、メモリ不足による接続の拒否を防ぐために使用されます。 平均値 ワークロードに依存 ワークロードやインスタンスクラスによって、しきい値に適切な値が異なります。理想的には、利用可能なメモリが総メモリの 25% 以下にならないようにする必要があります。Aurora の場合は、しきい値を 5% 近くに設定できます。このメトリックの履歴動作を分析して、適切なしきい値レベルを決定することをお勧めします。 1分 15/15 より低い
FreeStorageSpace 全般 このアラームは、ストレージ不足の問題を防ぐために使用されます。これにより、データベースインスタンスがストレージ容量を使い切ったときに発生するダウンタイムを防ぐことができます。ストレージの自動スケーリングが有効になっている場合や、データベースインスタンスのストレージ容量を頻繁に変更する場合は、このアラームを使用しないことをお勧めします。 最大 ワークロードに依存 割り当てられたストレージ容量の 10% 程度を計算し、その結果をしきい値として使用することをお勧めします。 1分 5/5 より低い
ReadLatency 全般 このアラームは、読み取りレイテンシが高いことを検出するために使用されます。通常、データベースのディスクは低い読み書きレイテンシを持ちますが、高レイテンシの操作を引き起こす問題が発生する可能性があります。 p90 ワークロードに依存 このアラームのための推奨しきい値は、ユースケースによって大きく異なります。20 ミリ秒を超える読み取りレイテンシは調査の対象となる可能性があります。読み取りレイテンシの重要性と要件を確認し、このメトリックの履歴動作を分析して、適切なしきい値レベルを決定することができます。 1分 5/5 より大きい
WriteLatency 全般 このアラームは、書き込みレイテンシが高いことを検出するために使用されます。データベースのディスクは通常、低い読み取り/書き込みレイテンシを持ちますが、高レイテンシ操作を引き起こす問題が発生する可能性があります。これを監視することで、ディスクのレイテンシが期待どおりに低いことを確認できます。 p90 ワークロードに依存 このアラームのおすすめのしきい値は、ユースケースによって大きく異なります。書き込みレイテンシが 20 ミリ秒を超える場合は、調査する必要があります。書き込みレイテンシの重要性と要件を確認し、このメトリックの過去の動作を分析して、適切なしきい値レベルを決定できます。 1分 5/5 より大きい
DBLoad 全般 このアラームは、高い DB ロードを検出するために使用されます。高い DB ロードは、DB インスタンスのパフォーマンス問題を引き起こす可能性があります。このアラームはサーバーレス DB インスタンスには適用されません。 平均値 ワークロードに依存 最大 vCPU 値は、DB インスタンスの vCPU (仮想 CPU) コアの数によって決まります。最大 vCPU に応じて、しきい値に適切な値が異なります。理想的には、DB ロードが vCPU ラインを超えないようにする必要があります。 1分 15/15 より大きい

この9個は冒頭の CloudWatch コンソール上で表示された推奨事項と一致しています。
良さそうですね。

では後はこのままこのアラートで使い始めてみようかな...と思ったのですが、上記項目のいくつかの閾値は固定ではなくてワークロードごとに値を決める必要があります。

ワークロードに依存したしきい値を検討してみた

上記の中でさらに閾値が「ワークロードに依存」となっているものは RDS インスタンスごとにどういう閾値にすべきか考える必要があります。
上記の中で次の6つはワークロードにあわせてしきい値を決める必要があります。

  • DatabaseConnections
  • FreeableMemory
  • FreeStorageSpace
  • ReadLatency
  • WriteLatency
  • DBLoad

決めていきましょう!

なお、今回の RDS インスタンスは SQL Server 2022 Standard Edition の db.m6i.large あたりを使おうかなと考えていましたので、この記事ではこちらを元に項目ごとに考えてみます。

DatabaseConnections

各項目はドキュメントあるいは CloudWatch 推奨事項にて閾値を決める際の考え方が記載されていますので、そちらに従っていきたいと思います。

許可される接続数は、DB インスタンスクラスのサイズとデータベースエンジン固有のパラメータ(プロセス/接続に関連するもの)に依存しま。す最大接続数の 90-95% の値を計算し、それをしきい値として使用することをお勧めします。

DatabaseConnectionsは最大接続数の 9 割くらいをまずは閾値として設定するのが良さそうです。
そして、RDS の最大接続数はデータベースエンジン毎に完全に考え方がバラバラです。次の公式ドキュメントに記載されています。

他のデータベースエンジンの場合はパラメータに従うことが多いのですが、RDS for SQL Server の場合は 32,767 が最大接続数となります。

そこから 9 割で計算したところ、しきい値は約 29,490 となりました。

FreeableMemory

ワークロードやインスタンスクラスによって、しきい値に適切な値が異なります。理想的には、利用可能なメモリが総メモリの 25% 以下にならないようにする必要があります。Aurora の場合は、しきい値を 5% 近くに設定できます。このメトリックの履歴動作を分析して、適切なしきい値レベルを決定することをお勧めします。

FreeableMemoryは Aurora の場合は 5%、Aurora 以外は総メモリの 25 % 程度にしておくのが良さそうです。
さらに実際に運用が開始された後は実績値を参考に閾値の調整が必要になりそうなことも記載されています。わかりやすい。

db.m6i.largeの場合は 8 GB となります。
なので、25 % だと約 2,147,483,648 B くらいになりそうです。ここを閾値としてみましょう。

FreeStorageSpace

割り当てられたストレージ容量の 10% 程度を計算し、その結果をしきい値として使用することをお勧めします。

これは 10 % 程度とのことで、今回は GP3 を 50 GiB 割り当てていましたので、約 5,370,689,280 B としたいと思います。

ReadLatency と WriteLatency

このアラームのための推奨しきい値は、ユースケースによって大きく異なります。20 ミリ秒を超える読み取り(書き込み)レイテンシは調査の対象となる可能性があります。読み取り(書き込み)レイテンシの重要性と要件を確認し、このメトリックの履歴動作を分析して、適切なしきい値レベルを決定することができます。

ReadLatency と WriteLatency は最終的に決める場合は許容可能なラインを決めるためにはアプリケーション上でのパフォーマンステストが必要かなという感じがします。

が、「20 ミリ秒を超える場合は」という指標が一応案内されているので、調整が必要だという前提ではありますが一旦 20 ミリ秒を閾値とするのは良さそうです。

DBLoad

最後はDBLoadです。

最大 vCPU 値は、DB インスタンスの vCPU (仮想 CPU) コアの数によって決まります。最大 vCPU に応じて、しきい値に適切な値が異なります。理想的には、DB ロードが vCPU ラインを超えないようにする必要があります。

このメトリクスは Performance Insight でも参照されている方が多いと思います。
上記によると vCPU ラインを超えないようにする必要があるとのことで、Performance Insights でも確かに vCPU ラインが表示されていましたね。

今回のインスタンスサイズだと vCPU 数が 2 となりますので、閾値は2にしてみます。

最終的にこうした

上記を踏まえてまずは次の CloudWatch アラームを作成するのが良さそうということで決めました。
公式ドキュメントや推奨事項コンソールには期間やデータポイント数、比較演算子や統計方法についても推奨されているものがありますので、迷ったらまずはこのあたりから始めてみるのは良いのではないでしょうか。

アラーム 統計 推奨しきい値 期間 アラームを発するデータポイント 比較演算子
CPUUtilization 平均値 90 1分 5/5 より大きい
DatabaseConnections 平均値 29,490 1分 5/5 より大きい
EBSByteBalance% 平均値 10 1分 3/3 より低い
EBSIOBalance% 平均値 10 1分 3/3 より低い
FreeableMemory 平均値 2,147,483,648 1分 15/15 より低い
FreeStorageSpace 最大 5,370,689,280 1分 5/5 より低い
ReadLatency p90 20 1分 5/5 より大きい
WriteLatency p90 20 1分 5/5 より大きい
DBLoad 平均値 2 1分 15/15 より大きい

なお、CloudWatch コンソールでアラームを作成する際には、推奨事項の詳細表示からアラーム作成を行うか、アラームソースをダウンロードして IaC でデプロイする形となりますので、作成の流れも簡単で良いですね。

さいごに

本日は RDS for SQL Server に CloudWatch の推奨事項に従ったアラームと閾値を設計してみました。

これを設定して終わりではなく、実際に記録されたメトリクスやアラームの履歴から見直しが必要になりそうな項目はいくつかあります。
それでも何もないところから「決めろ」と言われるより検討しやすいのでないでしょうか。