获取 Linux 系统和 Docker 容器的内存使用情况

简介: 这是一段比我最初想象的更长的旅程。我的要点是:• Available Memory > Free Memory 即: 允许使用内存 > 空闲内存• 能用MemAvailable时,用MemAvailable• Docker 容器中的进程直接在主机操作系统中运行• 准确了解您正在测量的内容,尤其是在 Docker 容器中

最近,我开始监控我们一直在开发的 Node.js 应用程序。一段时间后,我发现它的内存使用率增长缓慢,3 天就增长了 20%。在以下 Node.js 代码中测量了内存使用情况。


const os = require("os");
const total = os.totalmem();
const free = os.freemem();
const usage = ((free - total) / total) * 100;

所以,它们基本上来自操作系统,在这种情况下是Docker 上的Alpine Linux。幸运的是,我还记录了应用程序进程的内存使用情况,但它们并没有增加。那么为什么操作系统内存使用量会增加呢?


缓冲区和缓存内存

我使用了top命令Shift+m(按内存使用情况排序)并比较了长时间运行的服务器上的进程和新部署的服务器上的进程。双方的流程几乎相同。唯一的区别是,buffers并且cached Mem在长期运行的情况下很高。

经过一些研究或谷歌搜索后,我得出结论,这不是问题。当应用程序进程要求更多内存时,大部分buffers和cached Mem被放弃。

其实free -m命令提供了一行used,并free采取缓冲区和缓存的考虑。

$ free -m
             total  used  free  shared  buffers cached
Mem:          3950   285  3665     183       12    188
-/+ buffers/cache:    84  3866
Swap:         1896     0  1896

那么,它们究竟是什么?根据的手册/proc/meminfo,这是一个伪文件和 的数据源free,top还有朋友:

Buffers %lu
       Relatively temporary storage for raw disk blocks that
       shouldn't get tremendously large (20MB or so).
Cached %lu
       In-memory cache for files read from the disk (the page
       cache).  Doesn't include SwapCached.

我仍然不确定到底Buffers包含什么,但它包含文件的元数据等,而且它的大小相对微不足道。Cached包含缓存的文件内容,称为页面缓存。操作系统保留页面缓存,而 RAM 有足够的可用空间。这就是为什么即使进程没有泄漏内存,内存使用量也在增加。

如果您有兴趣,/proc/meminfo 输出中的 Buffers 和 Cached 列有什么区别?在 Quora 上有关于Buffers和的更多详细信息Cached。


可用内存

那么,我们应该使用free + buffers + cached? /proc/meminfo有一个更好的指标,称为MemAvailable。

MemAvailable %lu (since Linux 3.14)
       An estimate of how much memory is available for
       starting new applications, without swapping.
$ cat /proc/meminfo
MemTotal:        4045572 kB
MemFree:         3753648 kB
MemAvailable:    3684028 kB
Buffers:           13048 kB
Cached:           193336 kB
...

它的背景在 Linux Kernel中的提交中得到了很好的解释,但本质上它排除了不可释放的页面缓存并包括可回收的平板内存。Linux v4.12-rc2 中的当前实现看起来仍然几乎相同。

free -m有available列的一些实现。例如,在 Boot2Docker 上:

$ free -m
       total  used  free  shared  buff/cache  available
Mem:    3950    59  3665     183         226       3597
Swap:   1896     0  1896

它也可以通过--mem-avail标志在 AWS CloudWatch 指标上使用。


关于 Docker 的一些背景

我的另一个问题是“Docker 中的这些指标是否相同?”。在深入探讨这个问题之前,让我们检查一下 docker 是如何工作的。

根据Docker 概述:底层技术,Docker 容器中的进程直接在其主机操作系统中运行,没有任何虚拟化,但由于这些 Linux 内核特性,它们与主机操作系统和其他容器有效隔离:

命名空间:隔离 PID、主机名、用户 ID、网络访问、IPC 等。

  • cgroups:限制资源使用
  • UnionFS : 隔离文件系统
    由于命名空间的原因,pscommand除了列出宿主操作系统中的其他进程外,还列出了Docker容器的进程,而它不能列出宿主操作系统或docker容器中其他容器的进程。

默认情况下,Docker 容器没有资源限制。所以,如果你在一台主机上运行一个容器,并且不限制容器的资源使用,这就是我的情况,容器的“空闲内存”与主机操作系统的“空闲内存”是一样的。


Docker 容器上的内存指标

如果您想从容器外部监控 Docker 容器的内存使用情况,这很容易。您可以使用docker stats.

$ docker stats
CONTAINER     CPU %  MEM USAGE / LIMIT  MEM %  NET I/O     BLOCK I/O  PIDS
fc015f31d9d1  0.00%  220KiB / 3.858GiB  0.01%  1.3kB / 0B  0B / 0B    2

但是,如果您想获取容器中的内存使用情况或获取更详细的指标,就变得复杂了。Linux 容器内的内存详细描述了困难。

/proc/meminfo和sysinfo,由Node.js使用os.totalmem()和使用os.freemem(),不是孤立的,如果您在 Docker 容器中使用top和等普通实用程序,您将获得主机操作系统的指标free。


要获取特定于 Docker 容器的指标,您可以在/sys/fs/cgroup/memory/. 不过,它们并未根据Linux 容器内的内存进行标准化。

$ cat /sys/fs/cgroup/memory/memory.usage_in_bytes
303104
$ cat /sys/fs/cgroup/memory/memory.limit_in_bytes
9223372036854771712

memory.limit_in_bytes如果没有限制,则返回一个非常大的数字。在这种情况下,您可以使用/proc/meminfo或使用它的命令找到主机操作系统的总内存。


结论


这是一段比我最初想象的更长的旅程。我的要点是:

  • Available Memory > Free Memory 即: 允许使用内存 > 空闲内存
  • 能用MemAvailable时,用MemAvailable
  • Docker 容器中的进程直接在主机操作系统中运行
  • 准确了解您正在测量的内容,尤其是在 Docker 容器中
相关文章
|
11月前
|
缓存 监控 Linux
CentOS系统如何查看当前内存容量。
以上方法都不需要特殊软件或者复杂配置即可执行,在CentOS或其他Linux发行版中都适合运行,并且它们各自透露出不同角度对待问题解答方式:从简单快速到深入详尽;从用户态到核心态;从操作层数到硬件层数;满足不同用户需求与偏好。
817 8
|
Cloud Native 中间件 调度
云原生信息提取系统:容器化流程与CI/CD集成实践
本文介绍如何通过工程化手段解决数据提取任务中的稳定性与部署难题。结合 Scrapy、Docker、代理中间件与 CI/CD 工具,构建可自动运行、持续迭代的云原生信息提取系统,实现结构化数据采集与标准化交付。
1335 1
云原生信息提取系统:容器化流程与CI/CD集成实践
|
存储 缓存 监控
手动清除Ubuntu系统中的内存缓存的步骤
此外,只有系统管理员或具有适当权限的用户才能执行这些命令,因为这涉及到系统级的操作。普通用户尝试执行这些操作会因权限不足而失败。
2121 22
|
监控 Linux Python
Linux系统资源管理:多角度查看内存使用情况。
要知道,透过内存管理的窗口,我们可以洞察到Linux系统运行的真实身姿,如同解剖学家透过微观镜,洞察生命的奥秘。记住,不要惧怕那些高深的命令和参数,他们只是你掌握系统"魔法棒"的钥匙,熟练掌握后,你就可以骄傲地说:Linux,我来了!
514 27
|
监控 关系型数据库 MySQL
zabbix7.0.9安装-以宝塔安装形式-非docker容器安装方法-系统采用AlmaLinux9系统-最佳匹配操作系统提供稳定运行环境-安装教程完整版本-优雅草卓伊凡
zabbix7.0.9安装-以宝塔安装形式-非docker容器安装方法-系统采用AlmaLinux9系统-最佳匹配操作系统提供稳定运行环境-安装教程完整版本-优雅草卓伊凡
1148 30
|
Ubuntu 关系型数据库 MySQL
在Ubuntu系统的Docker上安装MySQL的方法
以上的步骤就是在Ubuntu系统的Docker上安装MySQL的详细方法,希望对你有所帮助!
1423 12
|
监控 Java Android开发
深入探索Android系统的内存管理机制
本文旨在全面解析Android系统的内存管理机制,包括其工作原理、常见问题及其解决方案。通过对Android内存模型的深入分析,本文将帮助开发者更好地理解内存分配、回收以及优化策略,从而提高应用性能和用户体验。
1231 38
|
Ubuntu Linux Docker
如何在Ubuntu 20.04系统中安装Docker
安装 Docker 引擎的步骤如下:首先更新系统包索引 (`sudo apt update`),安装必要依赖包 (`apt-transport-https` 等),添加 Docker 官方 GPG 密钥及 APT 仓库。接着再次更新包索引并安装 Docker 引擎及相关工具 (`docker-ce` 等)。最后启动 Docker 服务并设置开机自启,通过 `docker --version` 和运行测试容器 (`sudo docker run hello-world`) 验证安装是否成功。
5435 0
|
机器学习/深度学习 人工智能 缓存
【AI系统】推理内存布局
本文介绍了CPU和GPU的基础内存知识,NCHWX内存排布格式,以及MNN推理引擎如何通过数据内存重新排布进行内核优化,特别是针对WinoGrad卷积计算的优化方法,通过NC4HW4数据格式重排,有效利用了SIMD指令集特性,减少了cache miss,提高了计算效率。
756 3
|
12月前
|
存储
阿里云轻量应用服务器收费标准价格表:200Mbps带宽、CPU内存及存储配置详解
阿里云香港轻量应用服务器,200Mbps带宽,免备案,支持多IP及国际线路,月租25元起,年付享8.5折优惠,适用于网站、应用等多种场景。
3371 0