container_memory_working_set_bytes 和 process_resident_memory_bytes 和 total_rss 之间的关系

relationship between container_memory_working_set_bytes and process_resident_memory_bytes and total_rss

我希望了解

的关系

container_memory_working_set_bytes vs process_resident_memory_bytes vs total_rss (container_memory_rss) + file_mapped 以便更好地装备系统以提醒 OOM 可能性。

鉴于如果container/pod是运行执行用Go编写的编译程序的单个进程,这似乎违反了我的理解(这让我现在很困惑)。

为什么container_memory_working_set_bytes相对于process_resident_memory_bytes

相差这么大(将近10倍)

还有container_memory_working_set_bytescontainer_memory_rss + file_mapped之间的关系在这里很奇怪,这是我没有想到的,看完

The total amount of anonymous and swap cache memory (it includes transparent hugepages), and it equals to the value of total_rss from memory.status file. This should not be confused with the true resident set size or the amount of physical memory used by the cgroup. rss + file_mapped will give you the resident set size of cgroup. It does not include memory that is swapped out. It does include memory from shared libraries as long as the pages from those libraries are actually in memory. It does include all stack and heap memory.

所以 cgroup 总驻留集大小是 rss + file_mapped 对于给定 cgroup[=23] 中 运行 的容器,这个值如何小于 container_working_set_bytes =]

这让我觉得这个统计数据不正确。

以下是用于构建上图的 PROMQL

不是真正的答案,但仍然有两点。

是否有助于理解图表?

在我的 $dayjob 中,我们遇到了各种不同的问题,这些问题涉及 Go 运行时外部的不同工具 如何计算和显示执行 Go 编写的程序的进程的内存使用情况.
再加上 Go 在 Linux 上的 GC 实际上并没有将释放的内存页面释放给内核,而只是 madvise(2) 这些页面是 MADV_FREE,一个 GC 周期释放了相当多的内存内存量不会导致外部工具(通常是 cgroups 统计信息)获取的“进程 RSS”读数发生任何明显变化。

因此,我们正在导出我们自己的指标,这些指标是通过在任何用 Go 编写的主要服务中定期调用 runtime.ReadMemStats(和 runtime/debug.ReadGCStats)获得的——借助专门为此编写的简单包。这些读数反映了 Go 运行时关于其控制下的内存的真实想法。

顺便说一下,如果您为容器设置了内存限制,内存统计信息的 NextGC 字段非常有用,因为一旦读数达到或超过您的内存限制,容器中的进程注定最终会被oom_killer击落。

原来关系是这样的

container_working_set_in_bytes = container_memory_usage_bytes - total_inactive_file

container_memory_usage_bytes 顾名思义意味着容器使用的总内存(但由于它还包括文件缓存,即 inactive_file,OS 可以在内存压力下释放)减去inactive_file 给出 container_working_set_in_bytes

container_memory_rsscontainer_working_sets 之间的关系可以用下面的表达式来概括

container_memory_usage_bytes = container_memory_cache + container_memory_rss 

缓存反映存储在当前缓存在内存中的磁盘上的数据。它包含活动 + 非活动文件(如上所述)

这解释了为什么 container_working_set 更高。

参考 #1

参考 #2