“container_memory_working_set_bytes”和“container_memory_rss”度量标准在容器上有什么区别?

45

我需要监控在kubernetes集群上运行的容器的内存使用情况。阅读了一些文章后,有两个建议:“container_memory_rss”和“container_memory_working_set_bytes”。根据cAdvisor代码中所说,这两个指标的定义如下:

  • “container_memory_rss”:匿名和交换高速缓存内存的数量
  • “container_memory_working_set_bytes”:工作集内存的数量,包括最近访问的内存,脏内存和内核内存

我认为这两个指标都代表进程使用的物理内存字节数。但是从我的grafana仪表板上可以看出,这两个值之间存在一些差异。

我的问题是:

  • 这两个指标有什么区别?
  • 哪一个指标更适合监控内存使用情况?有些文章说两个指标都要监控,因为如果其中一个指标达到极限,那么容器就会被oom杀死。

1
我相信这个可以回答你的问题。https://github.com/google/cadvisor/issues/2582#issuecomment-644883028 - Olesya Bolobova
2个回答

53
你说得对。我会尝试更详细地回答你的问题。
“两个指标之间有什么区别?” container_memory_rss 等于 /sys/fs/cgroups/memory/memory.status 文件中 total_rss 的值:
// The amount of anonymous and swap cache memory (includes transparent
// hugepages).
// Units: Bytes.
RSS uint64 `json:"rss"`

匿名和swap缓存内存总量(包括透明大页),等于从memory.status文件中的total_rss值。这不应与cgroup使用的真实驻留集大小或物理内存量混淆。rss + file_mapped将给出cgroup的驻留集大小。它不包括被交换出的内存,但包括来自共享库的内存,只要这些库的页面实际上在内存中。它包括所有堆栈和堆内存。

container_memory_working_set_bytes(正如Olesya所提到的)是总使用量-非活动文件。它是无法被驱逐的内存估计:

// The amount of working set memory, this includes recently accessed memory,
// dirty memory, and kernel memory. Working set is <= "usage".
// Units: Bytes.
WorkingSet uint64 `json:"working_set"`

Working Set是进程当前的工作集大小,以字节为单位。工作集是进程中线程最近访问过的内存页面的集合。


如果您为pod 限制资源使用率, 那么应该同时监视这两个指标,因为它们会在达到特定资源限制时导致oom-kill。我还推荐这篇文章,其中展示了一个例子来解释以下断言:
您可能认为可以使用container_memory_usage_bytes轻松跟踪内存利用率,但是,此度量标准也包括可以在内存压力下被驱逐的缓存项目(请考虑文件系统缓存)。更好的指标是container_memory_working_set_bytes,因为这是OOM killer正在监视的内容。
编辑:
添加一些额外的来源作为补充:
- 深入了解Kubernetes度量 - 第3部分容器资源度量 - #1744 - 理解Kubernetes内存指标 - 在Kubernetes中Memory_working_set与Memory_rss,哪个应该监视? - 管理容器资源 - cAdvisor代码

我发布了另一个问题与此相关。你能不能也审核一下那个问题呢? - zeroFruit
我刚刚完成了。随便看看吧。 - Wytrzymały Wiktor
1
我有一个类似的问题,我觉得答案没有清楚地区分container_memory_rss和container_memory_working_set之间的关系,因为在我的情况下,working_set比container_memory_rss高10倍。此外,OP问题的评论中有一个GitHub链接,指出working_set不包括inactive_file(因此没有交换缓存?),这也没有解释为什么rss与working_set相比如此低,因为rss也包括交换缓存。 - Noobie
https://dev59.com/I8Hqa4cB1Zd3GeqPxlha - Noobie

6
实际上,这不是一个答案,而是对已接受答案的增强。以下评论适用于cgroup v1,可能不适用于cgroup v2。
"container_memory_working_set_bytes"(正如Olesya已经提到的)是“总使用量”减去“非活动文件”。它是无法被驱逐的内存的估计:
第一句话是正确的,但是“无法被驱逐”的评论是不正确的:至少,“container_memory_working_set_bytes”包括了由“total_active_file”所表示的值,该值可以被驱逐。
  1. 由于可用内存不足,系统自动回收
  2. echo 1/2/3 > drop_caches此问题中提到,并参考此链接了解值1/2/3的含义
  3. echo 0 > memory.force_emptycgroup文档的第5.1节中提到

因此,以下结论可能也不正确:

如果您限制了Pod的资源使用,则应同时监视两者,因为它们将在达到特定资源限制时导致oom-kill。

container_memory_working_set_bytes 达到限制实际上可能不会导致 oom-kill,至少在我们的环境中没有发生过 oom-kill。在我们的环境中,我们监控到 total_active_file 不断增加,因此 container_memory_working_set_bytes 也在增加,在 container_memory_working_set_bytes 达到限制后,由于内存回收,total_active_file 的值下降到较低值,因此 container_memory_working_set_bytes 也下降到较低值,Pod 一直在运行而没有被杀死。

实际上,关于 container_memory_working_set_bytes 指标已经有两个问题(thisthis),然而,这些问题都没有解决。在我们的环境中,由于上述虚警,我们现在监控的是 container_memory_rss 而不是 container_memory_working_set_bytes


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接