细节篇(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 的容器就可以在同一个宿主机上同时运行

相关推荐
io无心40 分钟前
Docker绑定端口报错
运维·docker·容器
zxnbmk1 小时前
pod内部共享命名空间与k8s命名空间是一个东西吗?
云原生·容器·kubernetes·namespaces
cherishSpring3 小时前
在windows使用docker打包springboot项目镜像并上传到阿里云
spring boot·docker·容器
LKAI.3 小时前
k8s存储动态供给StorageClass
docker·微服务·云原生·容器·kubernetes
你可以叫我仔哥呀4 小时前
k8s学习记录(五):Pod亲和性详解
学习·容器·kubernetes
马武寨山的猴子5 小时前
【MinerU】:一款将PDF转化为机器可读格式的工具——RAG加强(Docker版本)
人工智能·docker·容器·pdf·rag
高峰君主6 小时前
「Docker已死?」:基于Wasm容器的新型交付体系如何颠覆十二因素应用宣言
docker·容器·wasm
晓柏9 小时前
Docker 部署 ELK 日志收集系统
docker
liang89999 小时前
Docker(二):docker常用命令
spring cloud·docker·容器
启明真纳11 小时前
统信操作系统使用默认yum源安装 Docker 的踩坑
运维·docker·容器