细节篇(9):容器使用swap空间

Swap 空间是一块磁盘空间。当内存写满时可以把不常用的数据暂时写到 Swap 空间。这样内存空间就可以释放。

好处是可以应对瞬时突发的内存增大需求,不至于因为内存一时不够而触发 OOM Killer。

那么容器可以使用 Swap 空间吗?可以的

swappiness 参数

如果你使用过 Swap 空间,那么你可能配置过 proc 文件系统下的 swappiness 参数 (/proc/sys/vm/swappiness)。它可以决定系统将会有多频繁地使用交换分区。

较高的值会使得内核更频繁地使用交换分区,。swappiness 的取值范围是 0--100,缺省值 60。

在有磁盘文件访问时,Linux 会尽量把系统的空闲内存用作 Page Cache 来提高文件的读写性能。在没有打开 Swap 空间的情况下,一旦内存不够,就只能把 Page Cache 释放,而 RSS 内存是不能释放的。

RSS 里的内存大部分都是没有对应磁盘文件的内存,比如用 malloc() 申请到的内存,这种内存也被称为匿名内存。可以写入 Swap 空间的就是这些匿名内存。

在内存紧张时,Linux 怎么决定是先释放 Page Cache,还是先把匿名内存释放并写入到 Swap 空间里呢?

  1. 如果系统先把 Page Cache 都释放了,那么一旦节点里有频繁的文件读写操作,系统的性能就会下降。
  2. 如果 Linux 系统先把匿名内存都释放并写入到 Swap,一旦这些被释放的匿名内存马上需要使用,又需要从 Swap 空间读回到内存中,这样又会让 Swap(其实也是磁盘)的读写频繁,导致系统性能下降。

我们需要平衡 Page Cache 的释放和匿名内存的释放,而 swappiness就是用来定义这个平衡的参数。

swappiness 的范围是 0 到 100,但它不是一个百分比,更像是一个权重。用来定义 Page Cache 内存和匿名内存的释放的一个比例。

这个比例是 anon_prio: file_prio,这里 anon_prio 的值就等于 swappiness。下面我们分三个情况做讨论:

  1. 当 swappiness 的值是 100 时,匿名内存和 Page Cache 内存的释放比 例就是 100: 100,也就是等比例释放了。
  2. swappiness 缺省值是 60 时,匿名内存和 Page Cache 内存的释放比例就是 60 : 140,Page Cache 内存的释放要优先于匿名内存。
  3. swappiness 的值是 0 时,Linux 是不允许匿名内存写入 Swap 空间了吗?

当空闲内存少于内存一个 zone 的"high water mark"中的值时,Linux 还是会做内存交换,也就是把匿名内存写入到 Swap 空间后释放内存。

zone 是 Linux 划分物理内存的一个区域,里面有 3 个水位线(water mark),水位线可以用来警示空闲内存的紧张程度。

memory group和swappiness

运行容器,使用了 Memory Cgroup 后,swappiness 怎么工作呢?

Memory Cgroup 控制组下有一个 memory.swappiness 参数。可以控制这个控制组下面匿名内存和 page cache 的回收,取值的范围和工作方式和全局的 swappiness 差不多。在 Memory Cgorup 的控制组里,如果设置了 memory.swappiness 参数,它就会覆盖全局的 swappiness。

不过有一点不同:当 memory.swappiness = 0 时,对匿名页的回收是始终禁止的,始终不使用 Swap 空间,而当容器申请的内存超过 memory.limit_in_bytes 之后,就发生了 OOM Kill。

有了"memory.swappiness = 0"的配置和功能,就可以在同一个宿主机上,容器 A 上运行着需要使用 Swap 空间的应用,而别的容器不需要使用 Swap 空间。

重点总结

只要在宿主机节点上打开 Swap 空间,容器就可以用到 Swap 的。但同一个宿主机上,对于不需要使用 swap 的容器,它的 Memory Cgroups 的限制也失去了作用。

针对这个问题,我们学习了 swappiness 参数。当系统需要回收内存时,是优先释放 Page Cache 中的内存,还是优先释放匿名内存(写入 Swap)。

swappiness 的取值范围在 0 到 100 之间:

值为 100, 释放 Page Cache 和匿名内存是同等优先级的。

值为 60,缺省值,Page Cache 的释放优先级高于匿名内存的释放。

值为 0,当系统中空闲内存低于一个临界值时,仍然会释放匿名内存并把页面写入 Swap 空间。

swappiness 参数除了在 proc 文件系统下有个全局的值外,在每个 Memory Cgroup 控制组里也有一个 memory.swappiness

控制组里的 swappiness 参数值为 0 时,可以让控制组里的内存停止写入 Swap。这样需要使用 Swap 和不需要 Swap 的容器就可以在同一个宿主机上同时运行

相关推荐
花和满楼31 分钟前
K8s 1.36 ImageVolume GA:OCI 镜像不再只能跑容器
java·容器·kubernetes
hj2862513 小时前
Docker 核心知识点整理(网络 + Dockerfile + 原理 + 命令)
网络·docker·容器
梦想的颜色10 小时前
【Docker原理】Docker 容器一文打尽:生命周期、环境管控、迁移备份、日志进程排查、垃圾清理
运维·docker·容器·容器生命周期·容器日志排查·容器迁移备份·容器进程管理
万里侯14 小时前
GitOps 漂移检测:集群里改了配置,Git 还以为一切正常
微服务·容器·k8s
极客先躯18 小时前
高级java每日一道面试题-2026年03月30日-实战篇[Docker]-如何监控容器的网络流量?
java·运维·docker·容器·prometheus·高级面试
Waay19 小时前
Linux 三个核心环境变量配置文件、作用域、生效方式完整梳理
linux·运维·学习·云原生·容器
大E帝国子民120 小时前
Docker 部署 RocketMQ 5
docker·容器·rocketmq
江湖有缘21 小时前
【保姆级教程】使用Docker Compose一键搭建Picsur私有图床服务
java·docker·容器
java_logo1 天前
5 分钟共享打印机:用 Docker 一键部署 CUPS
运维·docker·容器·cups·网络打印机·共享打印机·docker部署cups
fen_fen1 天前
Docker部署PostgreSQL10 开启SSL和证书安装文档
docker·容器·ssl