Open17

Aurora PostgreSQLのメモリ内訳

ピン留めされたアイテム
hirenhiren

拡張メトリクスの、①使用中の容量と②,③キャッシュやバッファ、④未使用容量を足すとだいたい32GBくらいあるのでこれが正解っぽそう

①DB使用中の容量(Active Memory)+ OSカーネル(Slab Memory, Page Tables)
②OSキャッシュ/バッファ(Cached Memory, Buffered Memory)
③Hugeページ(Huge Pages Total × Huge Pages Size)
④本当に何にも使われていない容量(Free Memory)

hirenhiren

RDSでは、高速化のためにメモリはあればあるだけ使うため、使用率が高いのは問題ではないというのは知っているが、具体的に何で使用されているのか知らないので、詳しく調べてみる

例えばインスタンスクラスが db.r6g.xlarge のインスタンスではDBを全然使って無いのにメモリ使用率が常に80%弱で一定になっている

hirenhiren

空きメモリ容量 FreeableMemory は 8 GB でほぼ一定
db.r6g.xlarge はメモリ 32 GiB(≒34.3597GB)なので、(Total - Free ) / Total ≒ 75%
使用率に差異があるのは何故か?

hirenhiren

CloudWatch の FreeableMemory は拡張モニタリングの Cached Memory + Active Memory + Free Memory らしいが、6.6GB + 1GB + 1.1GB = 8.7GBになる。謎

CloudWatch と拡張モニタリングの測定値に違いが生じる場合があります。
https://zenn.dev/link/comments/8da2cabaf38b46

hirenhiren

拡張モニタリングのメモリ関係のOSメトリクス

メトリクス コンソール名 説明
active アクティブなメモリ 割り当てられたメモリの量 (キロバイト単位)。
buffers バッファ済みメモリ ストレージデバイスへの書き込み前に I/O バッファリングリクエストに使用されたメモリの量 (キロバイト単位)。
cached キャッシュ済みメモリ ファイルシステムベースの I/O のキャッシュに使用されたメモリの量。
dirty ダーティメモリ 変更されたがストレージ内のその関連データブロックに書き込まれなかった RAM 内のメモリページの量 (キロバイト単位)。
free 空きメモリ 未割り当てのメモリの量 (キロバイト単位)。
hugePagesFree huge ページ (空き) 空き huge ページの数。huge ページは Linux カーネルの機能です。
hugePagesRsvd huge ページ (予約) コミットされた huge ページの数。
hugePagesSize huge ページサイズ 各 huge ページユニットのサイズ (キロバイト単位)。
hugePagesSurp huge ページ (余剰) 使用可能な huge ページの余剰数/合計数。
hugePagesTotal huge ページ (合計) huge ページの合計数。
inactive 非アクティブメモリ 最も使用されていないメモリページの量 (キロバイト単位)。
mapped マップ済みメモリ プロセスアドレス空間内でメモリマップされているファイルシステムの内容の合計量 (キロバイト単位)。
pageTables ページテーブル ページテーブルが使用中のメモリの量 (キロバイト単位)。
slab スラブメモリ 再利用可能なカーネルデータ構造体の量 (キロバイト単位)。
total 合計メモリ メモリの合計量 (キロバイト単位)。
writeback 書き戻しメモリ バックアップストレージにまだ書き込み中の RAM 内のダーティページの量 (キロバイト単位)。

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_Monitoring-Available-OS-Metrics.html#USER_Monitoring-Available-OS-Metrics-RDS

hirenhiren

AIに要約して貰った

項目 役割
Free Memory 完全に未使用で、誰にも使われていない「空き地」です。
Active Memory アプリケーションが現在進行形で読み書きしている「作業中の机」です。
Inactive Memory 少し前まで使われていたが、現在は使われていない「待機中のデータ」です。
Cached Memory ディスクから読み込んだ内容をOSが保管しておく「一時保管庫」です。
Buffers ディスクへ書き込むデータを一時的に溜めておく「発送前の荷物置き場」です。
Slab Linuxカーネル自身が頻繁に使うデータ構造を保持する「OSの道具箱」です。
Huge Pages データベースが予約している「専用のVIPルーム」です。
hirenhiren

FreeableMemory – システムが使用していない物理メモリの量と、空いていて使用可能なバッファまたはページキャッシュメモリの総量。データベースのワークロードを最適に設定し、1 つ以上の不良クエリが原因で FreeableMemory が低くなっているのではない場合、低い FreeableMemory のパターンから、Amazon RDS インスタンスクラスをより高いメモリ割り当てレベルにスケールアップする必要があることを示しています。FreeableMemory に基づいて意思決定を行う場合、特に FreeCached のように、拡張モニタリングメトリクスを確認することが重要です。詳細については、「拡張モニタリング」を参照してください。

https://aws.amazon.com/jp/blogs/news/making-better-decisions-about-amazon-rds-with-amazon-cloudwatch-metrics/#:~:text=FreeableMemory – システムが使用し,ページキャッシュメモリの総量。

使用可能な RAM の容量。Aurora MySQL および Aurora PostgreSQL データベースの場合、このメトリクスは、MemAvailable の /proc/meminfo フィールドの値を報告します。

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/Aurora.AuroraMonitoring.Metrics.html

hirenhiren

SwapUsage は 500KB なのでほぼ無いようなもの

hirenhiren

SwapUsage – DB インスタンスで使用されるスワップ領域の量。Linux でホストされるデータベースでは、SwapUsage の値が高い場合、通常、インスタンスのメモリが不足していることを示しています。

https://aws.amazon.com/jp/blogs/news/making-better-decisions-about-amazon-rds-with-amazon-cloudwatch-metrics

使用したスワップ領域の量。このメトリクスは、以下の DB インスタンスクラスでは使用できません。
db.r3.、db.r4.、db.r7g.* (Aurora MySQL)
db.r7g.* (Aurora PostgreSQL)

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/Aurora.AuroraMonitoring.Metrics.html

hirenhiren

CloudWatch と拡張モニタリングの違い CloudWatch は、DB インスタンスのハイパーバイザーから CPU 使用率のメトリクスを収集します。一方、拡張モニタリングは DB インスタンス上のエージェントからメトリクスを収集します。ハイパーバイザーは仮想マシン (VM) を作成して実行します。ハイパーバイザーを使用することで、インスタンスはメモリと CPU を仮想的に共有して複数のゲスト VM をサポートできます。ハイパーバイザーレイヤーが少量の作業を実行するため、CloudWatch と拡張モニタリングの測定値に違いが生じる場合があります。DB インスタンスがより小さなインスタンスクラスを使用している場合、この違いはより大きくなる可能性があります。このシナリオでは、1 つの物理インスタンス上でハイパーバイザーレイヤーがより多くの仮想マシン (VM) を管理している可能性があります。

https://aws-observability.github.io/observability-best-practices/ja/guides/databases/rds-and-aurora/#performance-insights-とオペレーティングシステムのメトリクス

hirenhiren

1GB以上のRAMを搭載した専用データベースサーバーをご利用の場合、 の初期値はshared_buffersシステムメモリの25%が妥当です。 をさらに大きな値に設定すると効果的なワークロードもありますが、 PostgreSQLはshared_buffersオペレーティングシステムのキャッシュにも依存するため、 にRAMの40%以上を割り当てても、それより少ない値よりも効果が出る可能性は低いでしょう。

https://www.postgresql.org/docs/current/runtime-config-resource.html

PostgreSQL公式ではこうだが、Auroraはアーキテクチャが異なるので、↓

Aurora DB インスタンスの場合、DB パラメータグループのデフォルト値は、インスタンスクラスに応じて 50% から 75% の間で設定されます。Aurora PostgreSQL はダブルバッファリングを排除し、ファイルシステムキャッシュを利用しないため、Aurora DB インスタンスのデフォルト値は高くなっています。つまり、Aurora PostgreSQL では shared_buffers を大きくして、パフォーマンスを改善できます。Aurora PostgreSQL を使用する場合は、shared_buffers DB パラメータのデフォルト値には、75% を設定することがベストプラクティスです。この値が小さいと、データページが使用可能なメモリが少なくなるため、Aurora ストレージサブシステムの I/O が増加したときに、パフォーマンスの低下が生じる可能性があります。

https://repost.aws/ja/knowledge-center/rds-aurora-postgresql-shared-buffers

hirenhiren

HugeページはDBクラスターパラメータグループのデフォルトでON

Huge pages はメモリ管理機能です。DB インスタンスが、共有バッファで使用されるような、大きく連続したメモリチャンクで動作しているときのオーバーヘッドを軽減します。
RDS for PostgreSQL では、4 KB と 2 MB の両方のページサイズがサポートされています。

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/PostgreSQL.Concepts.General.FeatureSupport.HugePages.html

Huge_pages パラメータは、t3.medium,db.t3.large,db.t4g.medium,db.t4g.large インスタンスクラス以外のすべての DB インスタンスクラスについて、デフォルトでオンになっています。サポートされている Aurora PostgreSQL のインスタンスクラスでは、huge_pages パラメータ値を変更したり、この機能をオフにしたりすることはできません。

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.Managing.html#AuroraPostgreSQL.Managing.HugePages

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.Reference.ParameterGroups.html

hirenhiren

CloudWatchLogsに吐かれてるRDSOSMetrics(memory項目のみ)

RDSOSMetrics
    "memory": {
        "writeback": 0,
        "hugePagesFree": 31,
        "hugePagesRsvd": 25,
        "hugePagesSurp": 0,
        "cached": 6776976,
        "hugePagesSize": 2048,
        "free": 841416,
        "hugePagesTotal": 10840,
        "inactive": 7074604,
        "pageTables": 14544,
        "dirty": 1484,
        "mapped": 413500,
        "active": 1076680,
        "total": 32512004,
        "slab": 1192568,
        "buffers": 527864
    },
hirenhiren

どの項目をどう足してもtotalにならない...

hirenhiren

/proc/meminfoのあっちの値とこっちの値を足したら、なんでそっちの値と同じにならないの・・・・
と悩んだことありますよね?
/proc/meminfoは、カーネルが内部的に管理している枠組みでのメモリ情報をそのまま出しているので、残念ながらユーザ視点で知りたいメモリ情報とは一致しません。

https://enakai00.hatenablog.com/entry/20110906/1315315488


図は https://nopipi.hatenablog.com/entry/2015/09/13/181026 より引用