如何获取 k8s Pod 运行 Node JS 应用程序的当前和准确内存使用情况

How to get Current and accurate Memory Usage of k8s Pod running Node JS application

我在 k8s pod 上有一个 NodeJS 应用程序 运行。 pod 的实际大小为 2GB,但在环境变量中,我们将此值设置为 4GB --max-old-space-size=4096(在我的情况下这不是真的 - 对于某些租户,我们确实分配了 4GB 但大多数 pods 2GB).

现在我尝试了两种方法来检测内存使用情况和总内存,两者都提供不同的统计信息。

  1. 我正在从这个系统文件中获取内存使用情况:/sys/fs/cgroup/memory/memory.usage_in_bytes 以及从这个文件中获取总内存:/sys/fs/cgroup/memory/memory.limit_in_bytes

limit_in_bytes 正确地 returning 2GB,但 usage_in_bytes 的值波动太大,几分钟后约为 1GB,下一分钟飙升至 2GB,尽管什么都没有在那一分钟改变了(系统没有压力)。

进程的统计数据

Memory Usage POD: 2145124352
shlog - memLimit 214748364
  1. 我尝试的第二个选项是使用 V8 内置的节点 js 库来获取堆统计信息:https://nodejs.org/api/v8.html#v8getheapstatistics。 用法:

     const initialStats = v8.getHeapStatistics();
     console.log("heap_size_limit: ", (initialStats.heap_size_limit)); // total memory
     console.log("total_heap_size: ", (initialStats.total_heap_size)); // current usage
    

现在总内存是 return 4G,这对我来说是不对的。但这里的当前用法似乎很正确。

同一进程的统计数据

total_heap_size: 126312448,
heap_size_limit: 4320133120,

v8 getHeapStatistics 方法的完整响应:

HeapStats:  {
    total_heap_size: 126312448,
    total_heap_size_executable: 1097728,
    total_physical_size: 124876920,
    total_available_size: 4198923736,
    used_heap_size: 121633632,
    heap_size_limit: 4320133120,
    malloced_memory: 73784,
    peak_malloced_memory: 9831240,
    does_zap_garbage: 0,
    number_of_native_contexts: 1,
    number_of_detached_contexts: 0
}

我的目标是根据pod的总内存来检测内存使用情况,当内存消耗达到85%时进行一些节流。我愿意使用第一种方法,但请告诉我为什么内存使用量差异如此之大,以及如何获取 pod 的准确内存使用量。

真的很期待在这方面得到一些帮助。谢谢。

要了解进程的总体内存消耗,请查看(并信任)操作系统的设施。

Node 的 v8.getHeapStatistics 告诉您所有 JavaScript 对象所在的托管(a.k.a。垃圾收集)堆。但是在这个过程中可能会有相当多的其他非垃圾收集内存,例如节点缓冲区和某些字符串,以及不在托管堆上的各种通用基础设施。在平均 Chrome 渲染器进程中,JavaScript 堆往往占总内存消耗的三分之一左右,但在两个方向上都有明显的异常值;对于 Node 应用程序,这在很大程度上取决于您的应用程序在做什么。

将 V8 的最大堆大小(同样,这只是进程整体内存使用的垃圾收集部分)设置为大于可用内存量的值没有多大意义:它引发可避免的崩溃,因为当 V8 认为还有很多可用内存时,它不会花那么多时间在垃圾回收上,但是 OS/pod 作为一个整体可能已经面临内存不足的情况了.这就是为什么我链接了另一个答案:您很可能希望将最大堆大小设置为比可用内存小一点的值,以便为垃圾收集器提供正确的提示,告诉他们何时更努力地工作以保持在限制以下。