1. はじめに
EC2のメモリ使用率は監視していても、RDSのメモリ使用率まではちゃんと見れていない……というケースは意外と多いのではないでしょうか。
自分もお客様から「RDSのメモリ使用率も監視したい」と依頼されて、「確かにやってなかったな、どうやればいいんだろうう」となりました。
じゃあNew Relicで取れる既存のメトリクスだけでどうにかできないか?ということで検証してみました。
監視する必要があるかどうかは一旦置いておいて、「RDSのメモリ使用率ってどうやって出すの?」というところを検討されている方の参考になればと思います。
2. 課題
RDSのメモリ使用率を出したいとき、CloudWatchから取れるメトリクスには FreeableMemory(空きメモリ量)はあるのですが、メモリ使用率そのものは提供されていません。
なので、自分で計算する必要があります。考え方はシンプルです。
メモリ使用率(%) = (1 - 空きメモリ / メモリ総量) × 100
これをNRQLで書くとこうなります。
SELECT (1 - (average(aws.rds.FreeableMemory) / 1024 / 1024 / 1024) / 4) * 100 AS 'Memory Utilization(%)'
FROM Metric
WHERE aws.rds.DBInstanceIdentifier IN ('aurora-lookup-verify-writer','aurora-lookup-verify-reader')
FACET aws.rds.DBInstanceIdentifier
FreeableMemory はバイト単位なので / 1024 / 1024 / 1024 でGBに変換しています。
ここで問題になるのが、分母の メモリ総量を 4(GB)で固定している 点です。
RDSが1台だけ、あるいは全台同じインスタンスタイプならこれでOKです。
ただ、複数台いてインスタンスタイプがバラバラとなると、固定値では対応しきれません。
インスタンスタイプごとにアラートコンディションを分ければ一応いけますが、台数やタイプが増えてくると管理がどんどんつらくなります。
3. 解決アプローチ
New Relicには Lookup Table という機能があります。CSVファイルをアップロードしておいて、NRQL内でJOINして参照できるというものです。
参考:Upload CSV-format lookup tables | New Relic Documentation
これを使えば、インスタンスクラスごとのメモリ総量をLookup Tableに持たせておいて、NRQLの分母を動的に切り替えられるのでは?と考えました。
4. 構成
今回の検証で使ったAurora環境はこちらです。
| 項目 | 値 |
|---|---|
| エンジンタイプ | PostgreSQL |
| クラスタ名 | aurora-lookup-verify-cluster |
| インスタンス名 | ロール | インスタンスクラス(変更前) | インスタンスクラス(変更後) |
|---|---|---|---|
| aurora-lookup-verify-writer | Writer | db.t3.medium(4GB) | db.t3.medium(4GB)※変更なし |
| aurora-lookup-verify-reader | Reader | db.t3.medium(4GB) | db.t3.large(8GB) |
検証ではReaderインスタンスだけ db.t3.medium → db.t3.large に変更して、Lookup Tableを使った計算がちゃんと追従するかを確認します。
5. 事前準備
検証の前に、2つほど準備が必要です。
5-1. Lookup Tableの作成
インスタンスクラスごとのメモリ総量を定義したCSVファイルを用意します。
これをNew Relicの管理画面(Logs > Lookup tables)からアップロードして登録します。
今回はテーブル名を rds_instance_specs にしました。
5-2. インスタンスクラスのメトリクス取得
Lookup TableとJOINするには、New Relic側でRDSのインスタンスクラス(dbInstanceClass)が取れている必要があります。
ここでちょっとハマったのですが、AWSインテグレーションには Metric Streams と API Polling の2種類があり、Metric Streamsだけだとインスタンスクラスの属性が取れません。
Metric Streamsの環境でインスタンスクラスを取るには、AWS側で AWS Config を有効にしておく必要があります。
MetricStreamのインテグレーション設定の一部として、PollingによるMetadata取得のための設定も行われています。AWS環境でAWS Configが有効になっていると、このPollingにより定期的にAWS ConfigからMetadataが取得され、Metric Stream経由で転送されたデータにインスタンスクラスなどの属性が付与されるようになります。
ちなみに、API Pollingでインテグレーションしている場合は DatastoreSample イベントとしてデータが来るので、インスタンスクラスも普通に取れます。
6. 検証
ここからが本題です。Lookup Tableを使ったメモリ使用率の計算が、インスタンスクラスの変更にちゃんと追従するかを見ていきます。
6-1. NRQLの作成
Lookup Table rds_instance_specs をJOINして、インスタンスクラスに応じたメモリ総量を動的に引っ張ってくるNRQLを書きます。
AWSインテグレーションの方式によって参照するイベントが違うので、2パターン用意しました。
SELECT (1 - (average(aws.rds.FreeableMemory) / 1024 / 1024 / 1024) / latest(totalMemoryGB)) * 100 AS 'Memory Utilization(%)'
FROM Metric
JOIN (FROM lookup(rds_instance_specs) SELECT totalMemoryGB, instanceClass)
ON aws.rds.dbInstanceClass = instanceClass
WHERE aws.rds.DBInstanceIdentifier IN ('aurora-lookup-verify-writer','aurora-lookup-verify-reader')
FACET aws.rds.DBInstanceIdentifier
SELECT (1 - (average(provider.freeableMemoryBytes.Average) / 1024 / 1024 / 1024) / latest(totalMemoryGB)) * 100 AS 'Memory Utilization(%)'
FROM DatastoreSample
JOIN (
FROM lookup(rds_instance_specs)
SELECT totalMemoryGB, instanceClass
) ON provider.dbInstanceClass = instanceClass
WHERE provider = 'RdsDbInstance' AND provider.dbInstanceIdentifier IN ('aurora-lookup-verify-writer','aurora-lookup-verify-reader')
FACET displayName
課題セクションのNRQLと見比べると、固定値だった分母が latest(totalMemoryGB) に変わっているのがわかると思います。
JOIN でLookup Tableの instanceClass とメトリクスの dbInstanceClass を紐づけて、インスタンスごとに正しいメモリ総量を引いてくる仕組みです。
6-2. 変更前の確認
まずはインスタンスクラス変更前の状態です。
| インスタンス | インスタンスクラス | メモリ総量 |
|---|---|---|
| aurora-lookup-verify-writer | db.t3.medium | 4GB |
| aurora-lookup-verify-reader | db.t3.medium | 4GB |
この時点でのメモリ使用率は、Readerが約 48.1% でした。
6-3. インスタンスクラスの変更
Readerインスタンスだけ、インスタンスクラスを変更しました。
| インスタンス | 変更前 | 変更後 |
|---|---|---|
| aurora-lookup-verify-reader | db.t3.medium(4GB) | db.t3.large(8GB) |
Writerは db.t3.medium のままです。
6-4. 変更後の確認
変更後、New Relic側でもちゃんとメモリ総量が 8GB として認識されています。
メモリ総量が4GB→8GBに増えたので、空きメモリ量が同じでも使用率としては下がりますね。
タイムシリーズで見ても、変更したタイミングである程度下がった水準で推移していることが確認できます。
Billboardでも数値がしっかり変わっていました。
メモリ使用率の変化はこちら。
| インスタンス | 変更前 | 変更後 |
|---|---|---|
| aurora-lookup-verify-reader | 約 48.1% | 約 29.6% |
ということで、Lookup Tableを使った計算はインスタンスクラスの変更にちゃんと追従しており、固定値なしで動的にメモリ使用率を出せることが確認できました。
6-5. いざ監視設定へ!
コンディションの設定で「Save」を押下した直後エラーがでてきてしまいました。。。

7. おわりに
Lookup Tableを使うことで、インスタンスタイプがバラバラなRDSが複数台あっても、固定値を使わずにメモリ使用率を出せることがわかりました。
ただ、注意点がいくつかあります。
- Lookup Tableはインスタンスクラスの追加・変更があったら手動で更新が必要
- Metric Streams環境ではAWS Configを有効にしておかないとインスタンスクラスが取得不可
- Lookup TableのデータはNRQLアラートコンディションでは使用できない
特に3つ目が痛くて、今回の方法だとダッシュボードでの可視化はできるのですが、アラートによる監視には使えませんでした。アラートでメモリ使用率を監視したい場合は、結局インスタンスクラスごとにコンディションを分けて固定値で設定する必要がありそうです。
とはいえ、ダッシュボードでパッと見れるようにしておくだけでも十分価値はあると思うので、同じようなことで困っている方の参考になれば幸いです。












