最近发现一台服务器的 swap 设置的太小了,总是因为 swap 写满了而宕机,找了一些资料优化一下 swap 的设置。
创建 swap 文件
dd if=/dev/zero of=/var/swap bs=8M count=1024
修改 swap 文件权限
chmod 600 /var/swap
设置交换分区
mkswap /var/swap
激活交换分区
swapon /var/swap
回收交换分区分区
swapoff /var/swap
开机自动挂载
vi /etc/fstab
1
/var/swap none swap sw 0 0
交换内存调优
vm.swapiness
swappiness 的值的大小对如何使用 swap 分区是有着很大的联系的。swappiness=0 的时候表示最大限度使用物理内存,然后才是 swap 空间, swappiness=100 的时候表示积极的使用 swap 分区,并且把内存上的数据及时的搬运到swap空间里面。
cat /proc/sys/vm/swappiness
sysctl vm.swappiness=90
vim /etc/sysctl.conf
1
vm.swappiness=90
vm.dirty_ratio:同步刷脏页,会阻塞应用程序
这个参数控制文件系统的同步写写缓冲区的大小,单位是百分比,表示当写缓冲使用到系统内存多少的时候(即指定了当文件系统缓存脏页数量达到系统内存百分之多少时(如 10% )),开始向磁盘写出数据。即系统不得不开始处理缓存脏页(因为此时脏页数量已经比较多,为了避免数据丢失需要将一定脏页刷入外存),在此过程中很多应用进程可能会因为系统转而处理文件IO而阻塞。
增大之会使用更多系统内存用于磁盘写缓冲,也可以极大提高系统的写性能。但是,当你需要持续、恒定的写入场合时,应该降低其数值,一般启动上缺省是 10。
cat /proc/sys/vm/dirty_ratio
sysctl vm.dirty_ratio=10
vim /etc/sysctl.conf
1
vm.dirty_ratio=10
vm.dirty_background_ratio:异步刷脏页,不会阻塞应用程序
这个参数控制文件系统的后台进程,在何时刷新磁盘,单位是百分比。表示系统内存的百分比,意思是当写缓冲使用到系统内存多少的时候,就会触发pdflush/flush/kdmflush
等后台回写进程运行,将一定缓存的脏页异步地刷入外存。增大之会使用更多系统内存用于磁盘写缓冲,也可以极大提高系统的写性能。但是,当你需要持续、恒定的写入场合时,应该降低其数值,一般启动上缺省是 5。
注意:如果 dirty_ratio 设置比 dirty_background_ratio 大,可能认为 dirty_ratio 的触发条件不可能达到,因为每次肯定会先达到vm.dirty_background_ratio 的条件。然而,确实是先达到vm.dirty_background_ratio 的条件然后触发flush
进程进行异步的回写操作,但是这一过程中应用进程仍然可以进行写操作,如果多个应用进程写入的量大于flush
进程刷出的量那自然会达到 vm.dirty_ratio 这个参数所设定的坎,此时操作系统会转入同步地处理脏页的过程,阻塞应用进程。
cat /proc/sys/vm/dirty_background_ratio
sysctl vm.dirty_background_ratio=5
vim /etc/sysctl.conf
1
vm.dirty_background_ratio=5
vm.dirty_expire_centisecs:
这个参数声明 Linux 内核写缓冲区里面的数据多“旧”了之后,pdflush
进程就开始考虑写到磁盘中去,单位是 1/100 秒。缺省是 3000 ,也就是 30 秒的数据就算旧了,将会刷新磁盘。对于特别重载的写操作来说,这个值适当缩小也是好的,但也不能缩小太多,因为缩小太多也会导致IO提高太快。建议设置为 1500 ,也就是 15 秒算旧。当然,如果你的系统内存比较大,并且写入模式是间歇式的,并且每次写入的数据不大(比如几十M),那么这个值还是大些的好。
cat /proc/sys/vm/dirty_expire_centisecs
sysctl vm.dirty_expire_centisecs=1000
vim /etc/sysctl.conf
1
vm.dirty_expire_centisecs=1000
vm.dirty_writeback_centisecs
这个参数控制内核的脏数据刷新进程pdflush
的运行间隔,单位是 1/100 秒。缺省数值是 500 ,也就是 5 秒。如果你的系统是持续地写入动作,那么实际上还是降低这个数值比较好,这样可以把尖峰的写操作削平成多次写操作。
如果你的系统是短期地尖峰式的写操作,并且写入数据不大(几十M/次)且内存有比较多富裕,那么应该增大此数值。
cat /proc/sys/vm/dirty_writeback_centisecs
sysctl vm.dirty_writeback_centisecs=1000
vim /etc/sysctl.conf
1
vm.dirty_writeback_centisecs=1000
vm.vfs_cache_pressure:
增大这个参数设置了虚拟内存回收 directory 和 inode 缓冲的倾向,这个值越大,越易回收。
该文件表示内核回收用于 directory 和 inode cache 内存的倾向,缺省值 100 表示内核将根据 pagecache 和 swapcache ,把 directory 和 inode cache 保持在一个合理的百分比;降低该值低于 100 ,将导致内核倾向于保留 directory 和 inode cache ;增加该值超过 100 ,将导致内核倾向于回收 directory 和 inode cache 。
cat /proc/sys/vm/vfs_cache_pressure
sysctl vm.vfs_cache_pressure=100
vim /etc/sysctl.conf
1
vm.vfs_cache_pressure=100
swap_tendency
1
swap_tendency = mapped_ratio / 2 + swappiness + distress
distress 值是内核在释放内存时遇到的问题数。当内核第一次决定收回内存页面时, distress 将为0;尝试次数越多,这个值也越大。
vm_swappiness 就是大家设定的 swappniness 值
mapped_ratio 值是 mapped page 与总 page 比例,即
mapped ratio = (nr mapped * 100) / total memory
nr_mapped 可以从下面的命令行获得
grep nr_mapped /proc/vmstat
swap_tendency < 100 ,内核会尽量的从 page cache 中做回收(写回 page cache )
swap_tendency >=100 ,内核会尽量交换匿名内存和共享内存。
总结
总结一下调优应该设置的一些参数,这个因不同机器而异,按照自己机器的配置和功能调整这些参数。
vim /etc/sysctl.conf
1
2
3
4
5
6
vm.swappiness = 90
vm.dirty_ratio = 10
vm.dirty_background_ratio = 5
vm.dirty_expire_centisecs = 1000
vm.dirty_writeback_centisecs = 100
vm.vfs_cache_pressure = 100