swappiness参数和swap空间

-- TOC --

操作系统配置swap分区是为了不让系统在内存不够的时候卡死,特别是个人桌面环境,服务器为了保持高性能,也许可以不配置swap分区。有一个叫swappiness参数,与swap分区的使用密切相关。

Linux系统的内存使用

Linux的内存使用的一个宗旨是尽可能使用内存。

在文件被读写的时候,文件的cache会一直保留在系统内存中,一直到内存不够时候,再次之前没有主动释放这部分内存的逻辑。这样在下次读写被缓存的文件时候可以直接从内存读取,不必从磁盘进行IO操作,这样文件读写速度会更加快速。

此逻辑造成的结果是,其实available的内存还很多,但仍然会内存不够,系统触发Memory Reclaim逻辑,将一部分内存交换到Swap分区,或将缓存的文件写入硬盘。

Linux的进程使用的内存分为2种:

  1. file-backed pages(有文件背景的页面,比如代码段、比如read/write方法读写的文件、比如mmap读写的文件,它们有对应的硬盘文件,因此如果要交换,可以直接和硬盘对应的文件进行交换;比如读取一个文件,没有关闭,也没有修改,交换时,就可以将这个文件直接放回硬盘,代码处理其实就是删除这部分内容,只保留一个索引,让系统知道这个文件还处于打开状态,只是它的内容不在内存,在硬盘上),此部分页面叫做page cache;
  2. anonymous pages(匿名页,如stack,heap,CoW后的数据段等;他们没有对应的硬盘文件,因此如果要交换,只能交换到swap分区),此部分页面,如果系统内存不充分,可以被swap到swapfile或者硬盘的swap分区。

第(1)种内存是Linux系统更prefer的reclaim区域,它的 IO cost 相对较低;第(2)种swap的 IO cost 相对较高。

swappiness参数的含义

swappiness是Linux的一个内核参数,控制系统在进行内存swap时,使用swap分区或filesystem page cache的权重。它跟使用了多少百分比的系统内存后才开发swap没有关系,这是网络上很多文章的一个错误。

swappiness参数值可设置范围在0到200之间,中间值是100。

swappiness

This control is used to define the rough relative IO cost of swapping and filesystem paging, as a value between 0 and 200. At 100, the VM assumes equal IO cost and will thus apply memory pressure to the page cache and swap-backed pages equally; lower values signify more expensive swap IO, higher values indicates cheaper.(cost高的IO设置lower vale,cost低的IO设置high value,谁会反过来呢...)

Keep in mind that filesystem IO patterns under memory pressure tend to be more efficient than swap's random IO. An optimal value will require experimentation and will also be workload-dependent.

The default value is 60. (anonymous内存为60,它cost高;file-backed内存就是200-60,它cost低)

For in-memory swap, like zram or zswap, as well as hybrid setups that have swap on faster devices than the filesystem, values beyond 100 can be considered. For example, if the random IO against the swap device is on average 2x faster than IO from the filesystem, swappiness should be 133 (x + 2x = 200, 2x = 133.33).

At 0, the kernel will not initiate swap until the amount of free and file-backed pages is less than the high watermark in a zone.

一般桌面Linux系统swappiness默认值为60,与kernel默认值一致。CentOS系统此参数的默认值是30。在阿里云上主机安装的镜像,默认swappiness都是0,也没有配置swap空间,可查看/etc/sysctl.conf文件。

swappiness=0究竟意味着什么

Linux在进行内存回收(memory reclaim)的时候,实际上可以从1类和2类这两种页面里面进行回收,而swappiness值就决定了回收这2类页面的优先级。swappiness越大,越倾向于回收匿名页;swappiness越小,越倾向于回收file-backed的页面。当然,它们的回收方法都是一样的LRU算法

在Linux的早期版本(2012年以前的版本,kernel 3.5-rc1),哪怕swappiness被设置为0,其实匿名页仍然有被交换出去的机会。

2012年开始,这个细节有了变化。https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=fe35004fbf9eaf67482b074a2e032abb9c89b1dd

如果swappiness=0,除非系统的内存过小(nr_free + nr_filebacked < high watermark)这种恶劣情况发生,都只是考虑交换file-backed的pages,就不会考虑交换匿名页了。

于是乎,现在的swappiness如果等于0的话,意味着哪怕匿名页占据的内存很大,哪怕swap分区还有很多的剩余空间,除非恶劣情况发生,都不会交换匿名页,因此这可能造成更大的OOM(Out Of Memory)压力。不像以前,平时会一直兼顾着回收page cache和匿名页。所以,现在如果想将swappiness设置为0,那是要好好想想的了。

查询修改系统swappiness值

$ cat /proc/sys/vm/swappiness 10 如何配置swappiness值

临时性修改,使用sysctl命令

$ sudo sysctl vm.swappiness=10

永久性修改:

在/etc/sysctl.conf 文件里添加如下参数:

vm.swappiness=10

然后重启系统。

查看系统的swap空间

$ free -h
              total        used        free      shared  buff/cache   available
Mem:          3.8Gi       907Mi       222Mi       1.0Mi       2.7Gi       2.7Gi
Swap:         1.8Gi       0.0Ki       1.8Gi
$ cat /proc/swaps
Filename                Type        Size        Used        Priority
/swapfile                               file        1918356     524     -2

创建swap空间

在硬盘上创建swapfile,一般大小为内存的2倍:

$ sudo dd if=/dev/zero of=/swapfile bs=1M count=2048 status=progress
2080374784 bytes (2.1 GB, 1.9 GiB) copied, 23 s, 90.4 MB/s
2048+0 records in
2048+0 records out
2147483648 bytes (2.1 GB, 2.0 GiB) copied, 23.8378 s, 90.1 MB/s
$ ll -h swapfile
-rw-r--r-- 1 root root 2.0G Apr 19 09:21 swapfile

然后将其格式化,修改访问权限为0600

$ sudo mkswap swapfile
mkswap: swapfile: insecure permissions 0644, fix with: chmod 0600 swapfile
Setting up swapspace version 1, size = 2 GiB (2147479552 bytes)
no label, UUID=53f4d94c-a8da-4bb5-a739-47e477d1285a
$ sudo chmod 0600 swapfile

修改内核swappiness参数:

$ sudo sysctl -p
vm.swappiness = 40

挂载swapfile,swapon

$ sudo swapon /swapfile
$ free -h
               total        used        free      shared  buff/cache   available
Mem:           958Mi       140Mi        62Mi       2.0Mi       755Mi       661Mi
Swap:          2.0Gi          0B       2.0Gi

卸载swapfile的命令:swapoff

到这里还差一步,开机启动:

$ cat /etc/fstab
# ...
UUID=7cb7360e-00bf-4bf2-919a-493a145b09d7 /                       xfs     defaults        0 0
/swapfile /swapfile swap defaults 0 0

成功!

本文链接:https://cs.pynote.net/sf/linux/sys/202204173/

-- EOF --

-- MORE --