返回目录

改了 swappiness 却不生效:sysctl 配置的加载顺序

起因

一台 2 核、不到 2 GB 内存的云服务器,上面要跑好几个容器,内存很紧。先加了 2 GB 的交换文件(内存不够时,把暂时不用的数据挪到磁盘上的一块空间):

fallocate -l 2G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab   # 开机自动挂上

接着想把 vm.swappiness 设成 10。这个值在 0 到 100 之间,越小越不愿意用交换空间,设成 10 的意思是内存快用完了才用。于是新建了 /etc/sysctl.d/99-zz-swap.conf,写上 vm.swappiness = 10,再执行 sysctl --system。

结果一查,还是 0:

$ cat /proc/sys/vm/swappiness
0

原因

sysctl --system 会把输出里每个读到的文件都打印出来,看一眼就明白了:它先读 /etc/sysctl.d/ 等几个目录里的文件,最后再读一遍 /etc/sysctl.conf。同一个参数写了好几次,以最后读到的为准。

这台机器的系统镜像在 /etc/sysctl.conf 第一行就写了 vm.swappiness = 0,所以我在 sysctl.d 里写的 10 刚生效就被盖回去了。

开机时的情况又不一样:开机由 systemd-sysctl 处理,它只按文件名排序读 /etc/sysctl.d/,而 Ubuntu 在那里放了一个 99-sysctl.conf,它其实是指向 /etc/sysctl.conf 的链接。也就是说,开机和手动执行 sysctl --system 两种情况,读文件的顺序不同。文件名起成 99-zz 能保证开机时排在后面,手动执行时照样被盖掉。

解决

  1. 先备份:cp /etc/sysctl.conf /etc/sysctl.conf.bak-日期。
  2. 直接把 /etc/sysctl.conf 里那一行改成 vm.swappiness = 10,上面加一行注释写明为什么改。
  3. 删掉 sysctl.d 里自己加的那个文件,免得以后两处的值对不上。
  4. 执行 sysctl --system,再看 /proc/sys/vm/swappiness,变成 10 了。

记住