简介
Linux
将物理内存分为内存段,叫做页面。交换是指内存页面被复制到预先设定好的硬盘空间(叫做交换空间)的过程,目的是释放这份内存页面。物理内存和交换空间的总大小是可用的虚拟内存的总量。
什么是swap?
swap 空间是磁盘上的一块区域,可以是一个分区,也可以是一个文件。所以具体的实现可以是 swap 分区也可以是 swap 文件。当系统物理内存吃紧时,Linux 会将内存中不常访问的数据保存到 swap 上(换出),这样系统就有更多的物理内存为各个进程服务,而当系统需要访问 swap 上存储的内容时,再将 swap 上的数据加载到内存中(换入),这就是常说的换出(swap out)和换入(swap in)。
Swap 的优缺点
优点
1、对于小内存的服务器,可以提高服务器的稳定性!!!
交换空间可以在一定程度上缓解内存不足的情况,但是它需要读写磁盘数据,所以性能不是很高,但是却可以提高系统的稳定性。
- swap是Linux下的虚拟内存,设置适当的swap可增加服务器稳定性
- 建议swap容量在真实内存容量的1.5倍左右,若您的服务器内存大于4GB,可设1-2GB的固定值
2、暂存不常用的数据
对于一些大型的应用程序(如LibreOffice
等),在启动的过程中会使用大量的内存,但这些内存很多时候只是在启动的时候用一下,后面的运行过程中很少再用到这些内存。有了 swap
之后,系统就可以将这部分不怎么使用的内存数据保存到 swap
上去,从而释放出更多的物理内存供系统使用。
3、休眠功能需要使用swap
很多发行版(如ubuntu
)的休眠功能依赖于 swap
分区,当系统休眠的时候,会将内存中的数据保存到 swap
分区上,等下次系统启动的时候,再将数据加载到内存中,这样可以加快系统的启动速度,所以如果要使用休眠的功能,必须要配置 swap
分区,并且大小一定要大于等于物理内存在某些情况下,物理内存有限,但又想运行耗内存的程序怎么办?这时可以通过配置足够的 swap
空间来达到目标,虽然慢一点,但至少可以运行。
4、在某些情况下,物理内存有限,但又想运行耗内存的程序怎么办?这时可以通过配置足够的swap空间来达到目标,虽然慢一点,但至少可以运行。
5、虽然大部分情况下,物理内存都是够用的,但是总有一些意想不到的状况,比如某个进程需要的内存超过了预期,或者有进程存在内存泄漏等,当内存不够的时候,就会触发内核的OOM killer,根据OOM killer的配置,某些进程会被kill掉或者系统直接重启(默认情况是优先kill耗内存最多的那个进程),不过有了swap后,可以拿swap当内存用,虽然速度慢了点,但至少给了我们一个去debug、kill进程或者保存当前工作进度的机会。
6、如果看过Linux内存管理,就会知道系统会尽可能多的将空闲内存用于cache,以加快系统的I/O速度,所以如果能将不怎么常用的内存数据移动到swap上,就会有更多的物理内存用于cache,从而提高系统整体性能。
缺点
swap
是存放在磁盘上的,磁盘的速度和内存比较起来慢了好几个数量级,如果不停的读写 swap
,那么对系统的性能影响是非常大的,尤其是当系统内存很吃紧的时候,读写 swap
空间发生的频率会很高,导致系统运行很慢,像死了一样,这个时候添加物理内存是唯一的解决办法。
由于系统会自动将不常用的内存数据移到swap上,对桌面程序来说,有可能会导致最小化一个程序后,再打开时小卡一下,因为需要将swap上的数据重新加载到内存中来。
到底要不要swap?
上面介绍了什么是swap以及它们的优缺点,那么到底要不要配置swap呢?答案是:看情况。
下面分别讨论内存不够用、内存勉强够用和内存很充裕这三种情况下服务器和桌面环境对swap的选择。
本人提供Oracle(OCP、OCM)、MySQL(OCP)、PostgreSQL(PGCA、PGCE、PGCM)等数据库的培训和考证业务,私聊QQ646634621或微信db_bao,谢谢!
内存不够用
不管是桌面还是服务器,当物理内存明显不够用,而又想跑程序的话,添加swap是唯一的选择,慢点总比不能工作强。
内存勉强够用
建议配置swap,这样内核会将不常用的数据从内存移到swap上,从而有更多的物理内存供系统调用,提升系统性能,同时也避免因偶尔的物理内存不够造成进程异常退出,提升系统稳定性,但对服务器来说,一定要限制或者监控swap空间的使用情况,当出现swap空间使用超预期或者swap in/out频繁时,要及时采取措施,不然对性能影响很大
内存充裕
理论上来说,如果物理内存足够多并且不需要休眠功能,那swap就没什么用,可关键问题是我们很难保证物理内存在任何情况下都够用,因为总有意想不到的情况发生,比如某些进程耗内存超预期,服务器压力超预期,内存泄漏等。
在内存充裕的这种情况下,如果发生异常,swap能帮到我们吗?
桌面环境
一般不会开什么监控功能,所以也没法提前预知内存使用异常,当内存被用光的时候,分两种情况:
- 配置了swap:在系统变慢的时候能感觉到,可能还有机会杀掉一些进程和保存当前工作进度,当然也会出现慢的想砸电脑的情况,不过在磁盘如此廉价的情况下,浪费点磁盘空间换取这样的一个机会还是值得的。
- 没有配置swap:内核的OOM killer被触发,可能连保存工作进度的机会都没有。
服务器环境
服务器一般都会配置监控程序,当内存用量达到一个阈值的时候告警或者会自动重启异常的进程。但如果没有监控呢?当内存被用光的时候,分两种情况:
- 配置了swap:这时服务器还能提供服务,但性能会降低好几个档次,直到最终处于几乎死机状态,并且这一过程将持续很长一段时间,对服务器来说是个灾难;所以配置swap只能让服务再苟延残喘一会儿,然后就是长时间的服务中断(比如原来是每秒处理1000个请求的服务器,由于频繁使用swap,导致现在每秒只能处理50个请求,站在系统角度,进程还在运行,但是在业务角度服务已经几乎中断了)。
- 没配置swap:这时内核的OOM killer被触发,在默认配置下,耗内存的进程会被优先kill掉,这种进程一般就是我们的业务进程,这时守护进程就会自动重启该业务进程(没有守护进程?开什么玩笑),这种情况只会造成服务中断一会会儿(取决于进程重启的时间),不会出现上面因配置了swap而导致性能很差且服务持续中断的情况。就算OOM killer没有kill掉预期的进程,我们通过测试也能发现,然后将OOM killer配置成重启系统,那也比配置了swap在那里苟延残喘的好。
从上面可以看出,对服务器来说,似乎不配置swap更好,可以让有问题的进程尽快重启,缩短业务受影响的时间。
并且,就算没有配置监控程序,我们还有cgroups中的内存控制模块,可以控制一组进程所能使用的最大内存数,当超过这个数的时候,可以触发相应的行为,比如重启进程等。
总的来说,对于桌面环境来说,一般内存没有服务器端那么充裕,并且由于使用场景原因,会打开很多不同类型的GUI窗口,但前台的进程只有一个,大部分都是在后台待命,所以配置swap对提升性能还是有必要的;对于服务器来说,配置的内存都比较充裕,启动起来的进程也都是要干活的进程(不然就不应该被启动起来),并且也没有休眠的需求,再加上有了cgroups之后,可以更轻松的限制进程的内存使用,个人认为配置swap基本没什么必要了,看看coreos,默认就没有swap。
swap分类
Linux
下有两种类型的 swap
空间,swap
分区和 swap
文件,它们有各自的特点:
- swap 分区
swap
分区上面由于没有文件系统,所以相当于内核直接访问连续的磁盘空间,效率相对要高点,但由于 swap
分区一般安装系统时就分配好了,后期要缩减空间和扩容都很不方便。
- swap 文件
swap
文件放在指定分区的文件系统里面,所以有可能受文件系统性能的影响,但据说2.6
版本以后的内核可以直接访问swap
文件对应的物理磁盘地址,相当于跳过了文件系统直接访问磁盘。不过如果 swap
文件在磁盘上的物理位置不连续时,还是会对性能产生不利影响,但其优点就是灵活,随时可以增加和移除swap
文件。
交换分区在物理内存被填满时用来保持内存中的内容。当 RAM
被耗尽,Linux
会将内存中不活动的页移动到交换空间中,从而空出内存给系统使用。虽然如此,但交换空间不应被认为是物理内存的替代品。大多数情况下,建议交换内存的大小为物理内存的 1
到 2
倍。也就是说如果你有 8GB
内存, 那么交换空间大小应该介于 8-16GB
。
配置swap空间(扩展swap空间)
可以参考:https://support.huaweicloud.com/trouble-ecs/ecs_trouble_0322.html
方法一:swap 分区
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | # 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/sdb1 swap swap default 0 0 -- 或者可以使用整块盘来做swap分区 mkswap /dev/vde swapon /dev/vde echo "UUID=43a73cdb-4359-4141-a255-b86156d1f433 swap swap defaults 0 0" >> /etc/fstab free -h swapon -s -- 执行以下命令,可以查询swap分区UUID。 blkid |grep swap |awk '{print $2}' |
方法二:swap 文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | -- 主机设置,大小一般为内存的1.5倍 # dd if=/dev/zero of=/root/.swapfile bs=512M count=10 dd if=/dev/zero of=/root/.swapfile bs=1G count=10 -- 如果提示不安全的权限 0644,建议使用 0600 “swapon: /swapfile: insecure permissions 0644, 0600 suggested.” chmod -R 0600 /root/.swapfile -- 格式化为交换分区文件 mkswap /root/.swapfile -- 启用交换分区文件: swapon /root/.swapfile -- 使系统开机时自启用,在文件/etc/fstab中添加一行: # echo '/root/.swapfile swap swap defaults 0 0' >> /etc/fstab echo 'swapon /root/.swapfile' >> /etc/rc.local chmod +x /etc/rc.d/rc.local -- 查看swap状态 swapon -s |
关闭交换分区
| # 关闭交换分区 swapoff /root/.swapfile # 修改/etc/fstab # 将添加的Swap记录一并删除,否则下次重启后,系统又会重新挂载相应的swap分区和文件 |
如果swapoff
命令在尝试禁用交换文件时卡住了,可以使用swapon -s
命令来查看当前正在使用的交换文件列表,应该可以看到Used列一直在减小。
查看swap
查看大小和配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | # Filename: 类型是分区则显示分区路径,类型是文件则显示文件路径 # Type: partition代表是一个swap分区,file代表是一个swap文件 # Size: 显示swap的大小,默认单位是KB # Used: 已经被使用的大小,0表示还没有被使用到 # Priority: 优先级高将会被优先使用,同等优先级将会均匀使用(设置: swapon -p) [root@lhrblog ~]# swapon -s Filename Type Size Used Priority /data/.swapfile file 10485756 6534248 -1 /data1/.swapfile file 10485756 3246088 -2 [root@lhrblog ~]# cat /proc/swaps Filename Type Size Used Priority /root/swapfile file 6291452 31232 -2 [root@dbr710b ~]# swapon -s Filename Type Size Used Priority /dev/dm-1 partition 7340028 0 -2 /dev/vdc1 partition 209714172 0 -3 [root@dbr710b ~]# cat /proc/swaps Filename Type Size Used Priority /dev/dm-1 partition 7340028 0 -2 /dev/vdc1 partition 209714172 0 -3 [root@dbr710b ~]# |
查看使用情况
可以使用top和free命令查看,参考:https://www.xmmup.com/linux-free-minglingxiafreeheavailablequbie.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | [root@lhrblog ~]# top top - 09:52:33 up 1 day, 17:37, 1 user, load average: 0.00, 0.06, 0.12 Tasks: 82 total, 1 running, 80 sleeping, 0 stopped, 1 zombie %Cpu(s): 1.5 us, 0.5 sy, 0.0 ni, 98.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem : 3880196 total, 148048 free, 3030068 used, 702080 buff/cache KiB Swap: 6291452 total, 6260220 free, 31232 used. 535964 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 162 memcach+ 20 0 453020 40708 544 S 0.3 1.0 7:44.00 memcached 990 mysql 20 0 1999284 460048 8420 S 0.3 11.9 21:09.96 mysqld 。。。。 [root@lhrblog ~]# free -h total used free shared buff/cache available Mem: 3.7G 2.9G 147M 9.0M 662M 503M Swap: 6.0G 30M 6.0G |
查看swap in和out的频率
| # 并不是swap空间占用多就一定性能下降 # 真正影响性能是swap in和out的频率,频率越高对系统的性能影响越大 [root@lhrblog ~]# 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 |
swap(交换空间,单位:KB);内存够用的时候,这2个值都是0,如果这2个值长期大于0时,系统性能会受到影响,磁盘IO和CPU资源都会被消耗。有时我们看到空闲内存(free)很少的或接近于0时,就认为内存不够用了,不能光看这一点,还要结合si和so,如果free很少,但是si和so也很少(大多时候是0),那么不用担心,系统性能这时不会受到影响的;
一般在内存充足的情况下是不应有大量的 si,so的。
修改 swpapiness 参数
现在的机器一般都不太缺内存,如果系统默认还是使用了 swap 是不是会拖累系统的性能?理论上是的,但实际上可能性并不是很大。并且内核提供了一个叫做 swappiness 的参数,用于配置需要将内存中不常用的数据移到 swap 中去的紧迫程度。如果系统的内存不足,则需要根据物理内存的大小来设置交换空间的大小。
在 Linux 系统中,可以通过查看 /proc/sys/vm/swappiness
内容的值来确定系统对 SWAP 分区的使用原则。
| cat /proc/sys/vm/swappiness cat /etc/sysctl.conf | grep swappiness |
- 当 swappiness 内容的值为 0 时,表示最大限度地使用物理内存,物理内存使用完毕后,才会使用 SWAP 分区。
- 当 swappiness 内容的值为 100 时,表示积极地使用 SWAP 分区,并且把内存中的数据及时地置换到 SWAP 分区。
可以使用下述方法临时修改此参数,假设我们配置为空闲内存少于 10% 时才使用 SWAP 分区:
| echo 10 > /proc/sys/vm/swappiness |
若需要永久修改此配置,在系统重启之后也生效的话,可以修改 /etc/sysctl.conf
文件,并增加以下内容:
修改:
| echo 10 > /proc/sys/vm/swappiness echo 'vm.swappiness=10' >> /etc/sysctl.conf cat /proc/sys/vm/swappiness cat /etc/sysctl.conf | grep swappiness |
docker不限制swap
| docker update --memory 20g --memory-swap -1 96b14c546d98 |
优化 swap 性能
怎么配置 swap
可以让它的性能更好呢?
- 尽量使用
swap
分区,相对于 swap
文件来说,分区肯定是连续的物理磁盘空间,而 swap
文件有可能不是。 - 将
swap
分区和系统所在的分区放在不同的磁盘上,这样就不会和系统盘抢同一个磁盘的 I/O
带宽。 - 如果有多块磁盘的话,可以在每个盘上创建一个
swap
分区,并且将它们的优先级设置的一样,这样内核就会平均的访问这些 swap
分区,性能相当于原来的 N
倍(这里 N
是磁盘的数量)。
不过话又说回来了,如果频繁的访问 swap
的话,怎么优化 swap
都没用,跟内存比还是低几个数量级,性能还是下降的厉害,如果不频繁访问 swap
的话,优化 swap
又有啥意义呢?所以其实优化 swap
性能的实际意义不大,这里了解一下就好。
如何清除Linux的交换空间?
如果你想清除掉swap的空间,你可以运行下面的命令:
swap空间不能完全使用
内核参数vm.overcommit_memory不能配置为2,可以配置为1或0,默认为0
总结
1、尽量不要禁用swap,否则,一旦内存消耗完,就会导致OOM,随之数据库也会崩溃!!对于小内存的机器,尤其需要注意这个问题!
2、要想使用swap的所有空间,则内核参数vm.overcommit_memory不能配置为2,可以配置为1或0,默认为0
参考
https://www.escapelife.site/posts/df59491b.html
https://segmentfault.com/a/1190000008125116
http://blog.itpub.net/26736162/viewspace-2149754/
用了内存90%,就开始使用swap有什么好处?
好处就是不会发生OOM,程序不会蹦,系统稳定性高了,坏处就是可能会影响系统性能