サマリ
- Linuxにおいて使用メモリの情報はだいたい/proc/meminfoの情報から計算されるが、計算式にゆらぎがあって異なるツールやSaaSエージェントを使うと結果が異なることがあるので故あって調べた
- ダッシュボードの表示とfree(1)の結果が異なるなど
- 2023現在使用メモリはだいたいMemTotal-MemAvailableということでOK
- free(1)などprocps依存なコマンドもMemTotal-MemAvailableをUsedとして扱うようになる
- 稀に計算式が異なるケースもあるのでおかしいな、と思うことがあれば一応まだ気にしたほうがよいことがあるかもしれない
- ツールをまたぐ時は特に
各種SaaSやツールの状況
procps
- v4.0.1からMemTotal - MemAvailable、それ以前はMemTotal - MemFree - Buffers - Cached - SReclaimable
- 変更の経緯としてはコミットログからリンクされているが最終的にカーネルが推定する使用可能なメモリ以外をUsedとして扱うことになった
- v4.0.1のリリースは2022/10/20でubuntuの現行LTSであるjammyで入ってくるバージョンはまだ3.3.17であり、将来的にバージョンアップが進んで4.0.1が取り込まれるとfree、top、vmstatなどprocpsを利用するツールも計算式が変わると思われる
Datadog
- MemTotal - MemAvailableを出している
- datadog-agentの実装をみるとAvailableの計算はshirou/gopsutilに依存していて、カーネル3.14より古い場合はこのアルゴリズムをベースに計算されているっぽい
Mackerel
- MemAvailableを使える場合はMemTotal - MemAvailable、使えない場合はMemTotal - MemFree - Buffers - Cached(SReclaimableは含まれない)
node_exporter + Grafana Dashboard
- node_exporterは/proc/meminfoをそのまま出力するのでダッシュボードの作り方に依存する
- Node Exporter Fullの現在のバージョン(Revison29)においてはmemory basicの方はnode_memory_SReclaimable_bytesを考慮するようになっていてRAM Usedはtotal-availableになっている
- 細かいバージョンは不明だが過去のバージョンではmemory basicの計算はSReclaimableを考慮しないMemTotal - MemFree - Buffers - Cachedだった
GCP(Ops エージェント)
この VM が使用したメモリの割合(ディスク キャッシュを除く)。Linux VM の場合はカーネルメモリも除外されるため、ユーザー空間のみの使用量になります。
- メモリ使用率が上記の説明でMemory Usageにはusedというメトリクスがあるが、procpsの仕様とは違ってMemTotal-MemAvailableよりは低く、MemTotal - MemFree - Buffers - Cached - SReclaimableよりは高い値が出てるっぽい
- 気が向いて時間があれば調べる
余談1 SReclaimableを入れるか入れないのかについて
- procpsの実装はfreeのマニュアルにもある通りcachedが/proc/meminfoでいうところのCached+SReclaimableなので、Availableを使う計算式以前にMemTotal - MemFree - Buffers - Cachedという計算式がダッシュボードでよく採用されていた経緯が気になる(freeやtopの結果の結果と異なることになるので混乱があったのではと思うが)(単に読み違えたのか他に理由があったのか)
- SReclaimableが含まれる場合、slab cacheは長期的に増えるので、生存期間の長いサーバでUsedが増えているように見えてユーザーが実行しているアプリケーションでリークが疑われるケースなどがあった(世の中的にもあったんじゃなかろうか
- かつてあったこれとかもUsedに含まれて表示されると混乱したんじゃないかとか
余談2 Mackerelのめちゃ細かい話
- Mackerelのグラフで表示される数値とfree -mの結果が微妙にずれるのだけどどうもこれはよくあるMB、MiBの違いっぽい
- グラフ表示画面のリクエストみるとメトリクスはbyte単位で返しているのだけどグラフ描画時に単位ごとに/1000して表示してる模様
- 単位はMB、GB等で表示されてるので間違いではないのだけど個人的にはMiB/GiBにしてくれると良いなあと思っている