纸上得来终觉浅,绝知此事要躬行。
Linux
将物理内存分为内存段,叫做页面。交换是指内存页面被复制到预先设定好的硬盘空间(叫做交换空间)的过程,目的是释放这份内存页面。物理内存和交换空间的总大小是可用的虚拟内存的总量。
1. 什么是 Swap
理解 Swap 在 Linux 操作系统上面的作用!
我们知道 swap space
是磁盘上的一块区域,可以是一个分区,也可以是一个文件,或者以它们的组合方式出现。简单点说,当系统物理内存吃紧时,Linux
系统会将内存中不常访问的数据保存到 swap
上,这样系统就有更多的物理内存为其他进程服务,而当系统需要访问 swap
上存储的内容时,系统会再将 swap
上的数据加载到内存中,这就是我们常说的 swap out
和 swap in
了。
2. Swap 的优缺点
我们应当在适合的时候,灵活的使用 Swap 分区!
- [1] 主要优点如下所示
对于一些大型的应用程序(如LibreOffice
等),在启动的过程中会使用大量的内存,但这些内存很多时候只是在启动的时候用一下,后面的运行过程中很少再用到这些内存。有了 swap
之后,系统就可以将这部分不这么使用的内存数据保存到 swap
上去,从而释放出更多的物理内存供系统使用。
很多发行版(如ubuntu
)的休眠功能依赖于 swap
分区,当系统休眠的时候,会将内存中的数据保存到 swap
分区上,等下次系统启动的时候,再将数据加载到内存中,这样可以加快系统的启动速度,所以如果要使用休眠的功能,必须要配置 swap
分区,并且大小一定要大于等于物理内存在某些情况下,物理内存有限,但又想运行耗内存的程序怎么办?这时可以通过配置足够的 swap
空间来达到目标,虽然慢一点,但至少可以运行。
- [2] 主要缺点如下所示
swap
是存放在磁盘上的,磁盘的速度和内存比较起来慢了好几个数量级,如果不停的读写 swap
,那么对系统的性能肯定有影响,尤其是当系统内存很吃紧的时候,读写 swap
空间发生的频率会很高,导致系统运行很慢,像死了一样,这个时候添加物理内存是唯一的解决办法。
3. Swap 的大小配置
介绍了日常使用时,配置多大的 Swap 比较合适!
既然配置 swap
对桌面系统有帮助,那么配置多少大小的 swap
比较合适呢?下面是 ubuntu
给出的建议:
当物理内存小于
1G
且不需要休眠时,设置和内存同样大小的swap
空间即可;当需要休眠时,建议配置两倍物理内存的大小,但最大值不要超过两倍内存大小。当物理内存大于
1G
且不需要休眠时,建议大小为sqrt(RAM)
,其中RAM
为物理内存大小;当需要休眠时,建议大小是RAM+round(sqrt(RAM))
,但最大值不要超过两倍内存大小。如果两倍物理内存大小的
swap
空间还不够用,建议增加内存而不是增加swap
。
下面是详细的不同物理内存情况下的建议,第一列是物理内存的大小,第二列和第三列是不需要和需要休眠两种情况下推荐的大小,第四列是不要超过的最大值。
物理内存(MB) 不需要休眠 需要休眠 最大值
256 256 512 512
512 512 1024 1024
1024 1024 2048 2048
物理内存(GB) 不需要休眠 需要休眠 最大值
1 1 2 2
2 1 3 4
3 2 5 6
4 2 6 8
5 2 7 10
6 2 8 12
8 3 11 16
12 3 15 24
16 4 20 32
24 5 29 48
32 6 38 64
64 8 72 128
128 11 139 256
4. Swap 常用操作
介绍了日常使用时,增删的相关操作!
当我们确定好配置多大的 swap
空间后,具体应该怎么配置呢?Linux
下有两种类型的 swap
空间,swap
分区和 swap
文件,它们有各自的特点:
swap 分区
swap
分区上面由于没有文件系统,所以相当于内核直接访问连续的磁盘空间,效率相对要高点,但由于swap
分区一般安装系统时就分配好了,后期要缩减空间和扩容都很不方便。
swap 文件
swap
文件放在指定分区的文件系统里面,所以有可能受文件系统性能的影响,但据说2.6
版本以后的内核可以直接访问swap
文件对应的物理磁盘地址,相当于跳过了文件系统直接访问磁盘。不过如果swap
文件在磁盘上的物理位置不连续时,还是会对性能产生不利影响,但其优点就是灵活,随时可以增加和移除swap
文件。
交换分区在物理内存被填满时用来保持内存中的内容。当 RAM
被耗尽,Linux
会将内存中不活动的页移动到交换空间中,从而空出内存给系统使用。虽然如此,但交换空间不应被认为是物理内存的替代品。大多数情况下,建议交换内存的大小为物理内存的 1
到 2
倍。也就是说如果你有 8GB
内存, 那么交换空间大小应该介于 8-16GB
。
- [1] 查看系统中已经配置的 swap 分配情况
# Filename: 类型是分区则显示分区路径,类型是文件则显示文件路径
# Type: partition代表是一个swap分区,file代表是一个swap文件
# Size: 显示swap的大小,默认单位是KB
# Used: 已经被使用的大小,0表示还没有被使用到
# Priority: 优先级高将会被优先使用,同等优先级将会均匀使用(设置: swapon -p)
escape@app:~$ swapon -s
Filename Type Size Used Priority
/data/.swapfile file 10485756 6534248 -1
/data1/.swapfile file 10485756 3246088 -2
# 指定交换区的优先顺序
$ sudo swapon -p xxx
# 启动某个交换swap
$ sudo swapon /dev/sda2
# 启动所有系统配置的swap
$ sudo swapon -a
# 关闭某个交换swap
$ sudo swapoff /dev/sda2
# 关闭所有系统配置的swap
$ sduo swapoff -a
- [2] 固定使永久生效
# 写入磁盘配置文件
# <file system> <mount point> <type> <options> <dump> <pass>
$ cat /etc/fstab
/data1/.swapfile none swap sw 0 0
/data1/.swapfile2 none swap sw 0 0
- [3] 查看系统中 swap in/out 的情况
# 并不是swap空间占用多就一定性能下降
# 真正影响性能是swap in和out的频率,频率越高对系统的性能影响越大
escape@app:~$ vmstat 2
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
3 1 9795592 2037192 282460 14034552 8 8 51 46 0 0 10 1 88 0 0
3 0 9795592 2025832 282472 14044688 0 0 68279 270 5416 6425 35 6 54 5 0
- [4] 查看系统内存使用情况
# 查看系统内存的实际使用参数
$ free
总计物理内存 已使用 可使用 共享内存 磁盘缓存的大小
total used free shared buff/cache available
Mem: 32887700 15661764 13404800 585080 3821136 15865296
交换分区
Swap: 31457272 10461216 20996056
5. 配置 Swap 缓存
操作系统使用 ZFS 文件系统
- [1] 添加 swap 分区
# 1.创建逻辑卷
$ sudo zpool create -V 2G rpool/swap
# 2.使用mkswap命令来格式化交换分区
$ sudo mkswap -f rpool/swap
# 3.激活新建的交换分区
swapon -a /dev/zvol/dsk/rpool/swap2
# 4.永久生效
$ sudo vi /etc/fstab
/dev/zvol/dsk/rpool/swap2 swap swap default 0 0
- [2] 取消 swap 配置
# 1.关闭某个交换swap
$ sudo swapoff /dev/zvol/dsk/rpool/swap2
# 2.删除逻辑卷
$ sudo zpool destroy rpool/swap
# 3.修改/etc/fstab
将添加的Swap记录一并删除,否则下次重启后,系统又会重新挂载相应的swap分区和文件
操作系统使用其他文件系统
- [1] 添加 swap 分区
# 1.新加的硬盘
$ sudo fdisk -l /dev/sdb
Device Boot Start End Sectors Size Id Type
/dev/sdb1 2048 4194303 4192256 2G 83 Linux
# 2.使用mkswap命令来格式化交换分区
$ sudo mkswap /dev/sdb1
Setting up swapspace version 1, size = 2 GiB (2146430976 bytes)
no label, UUID=d69621de-618a-4bea-9a96-b8e8b0d0ea40
# 3.激活新建的交换分区
$ sudo swapon /dev/sdb1
# 4.swap分区已经被加入到系统中
$ swapon -s
Filename Type Size Used Priority
/dev/sdb1 partition 2096124 0 -1
# 5.永久生效
$ sudo vi /etc/fstab
/dev/sda3 swap swap default 0 0
- [2] 添加 swap 文件
# 1.创建swap文件
$ sudo fallocate -l 512m /data/512M.swap
$ sudo fallocate -l 20G /data/20G.swap
# 有些系统应为是fallocate创建的磁盘再启用时会失败
# 所以,当遇到提示命令参数异常的时候问题,可以使用dd命令创建
# 提示报错信息: swapon failed: Invalid argument
$ sudo dd if=/dev/zero of=/data/20G.swap bs=1G count=20
# 2.修改文件的权限,避免其他用户对这个文件进行误操作
$ sudo chmod 600 /data/512M.swap
$ sudo chmod 600 /data/20G.swap
# 3.格式化为swap文件
$ sudo mkswap /data/512M.swap
$ sudo mkswap /data/20G.swap
# 4.启用交换空间
$ sudo swapon /data/512M.swap
$ sudo swapon /data/20G.swap
# 5.查看swap状态
$ swapon -s
Filename Type Size Used Priority
/data/512M.swap file 524284 0 -1
/data/20G.swap file 20971360 0 -2
# 6.永久生效
$ sudo vi /etc/fstab
/dev/sda3 swap swap defaults 0 0
- [3] 取消 swap 配置
# 1.停掉所有系统正在使用的swap
$ sudo swapoff /data/20G.swap
# 2.查看swap状态
$ swapon -s
Filename Type Size Used Priority
/data/512M.swap file 524284 0 -1
# 3.修改/etc/fstab
将添加的Swap记录一并删除,否则下次重启后,系统又会重新挂载相应的swap分区和文件
7. 优化 swap 性能
使用和配置 Swap 的相关经验总结!
怎么配置 swap
可以让它的性能更好呢?
尽量使用
swap
分区,相对于swap
文件来说,分区肯定是连续的物理磁盘空间,而swap
文件有可能不是。将
swap
分区和系统所在的分区放在不同的磁盘上,这样就不会和系统盘抢同一个磁盘的I/O
带宽。如果有多块磁盘的话,可以在每个盘上创建一个
swap
分区,并且将它们的优先级设置的一样,这样内核就会平均的访问这些swap
分区,性能相当于原来的N
倍(这里N
是磁盘的数量)。
不过话又说回来了,如果频繁的访问 swap
的话,怎么优化 swap
都没用,跟内存比还是低几个数量级,性能还是下降的厉害,如果不频繁访问 swap
的话,优化 swap
又有啥意义呢?所以其实优化 swap
性能的实际意义不大,这里了解一下就好。
8. 配置 swappiness 特性
配置希望尽量减少 Swap 空间的使用!
有时我们桌面环境确实配置了比较充裕的内存,并且也配置了 swap
空间,这个时候就希望尽量减少 swap
空间的使用,避免对系统性能造成影响。Linux
早就帮我们考虑到这种情况了,在 2.6
内核中,增加了一个叫做 swappiness
的参数,用于配置需要将内存中不常用的数据移到 swap
中去的紧迫程度。这个参数的取值范围是 0~100
,0
告诉内核尽可能的不要将内存数据移到 swap
中,也即只有在迫不得已的情况下才这么做,而 100
告诉内核只要有可能,尽量的将内存中不常访问的数据移到 swap
中。
Ubuntu
的 desktop
和 server
的默认配置都是 60
(可能会随着版本变化),对于桌面环境来说,界面的响应速度直接关系到系统的流畅程度,如果内存比较充裕的话,可以将这个值设置的小一点,这样就尽可能的把数据留在内存中,从而唤醒后台界面程序会更快一些,Ubuntu desktop
建议将该值设置为 10
,当然大家可以根据 swap
空间的实际使用情况,任意调整这个参数,直到自己满意的水平为止。对于服务器来说,主要性能衡量标准是整体的处理能力,而不是具体某一次的响应速度,能把更多的内存用来做 I/O cache
可能效果更好,所以 Ubuntu server
建议保持 60
的默认值。
# 修改当前系统中swappiness的值
$ sudo sysctl vm.swappiness=10
vm.swappiness = 10
# 查看当前系统中swappiness的值
$ sudo cat /proc/sys/vm/swappiness
10
# 生效配置 => /etc/sysctl.conf
$ sudo /sbin/sysctl -p
# 修改当前系统中vfs_cache_pressure的值
$ sudo sysctl vm.vfs_cache_pressure=50
vm.vfs_cache_pressure=50
# 查看当前系统中vfs_cache_pressure的值
$ sudo cat /proc/sys/vm/vfs_cache_pressure
50
# 生效配置 => /etc/sysctl.conf
$ sudo /sbin/sysctl -p
上面通过 sysctl
修改的 swappiness
值在系统重启后会失效,要想重启后继续生效,需要修改配置文件 /etc/sysctl.conf
,将下面这行修改成 10
,如果文件中找不到这行的话,在文件末位加上这行就可以了。
vm.swappiness=10
9. 参考文档地址
送人玫瑰,手有余香!