每次安装Linux都会要求配置swap分区,那么这个分区是做什么用的呢?不设置这个分区会有什么后果?如果一定要设置,设置多大合适?本文将尝试回答这些问题,并尝试涵盖所有与交换相关的知识。以下所有示例均在ubuntu-server-x86_6416.04下执行。什么是掉期?交换空间是磁盘上的一个区域,可以是分区、文件或它们的组合。简单的说,当系统的物理内存紧张时,Linux会把内存中不常访问的数据保存到swap中,让系统有更多的物理内存来服务于各个进程,当系统需要访问swap上存储的内容,然后将swap上的数据加载到内存中,也就是我们常说的swapout和swapin。为什么需要swap呢?要回答这个问题,我们需要回答交换给我们带来了什么好处。对于一些大型的应用程序(如LibreOffice、视频编辑器等),在启动过程中会使用大量的内存,但是这部分内存往往只在启动时使用,后续运行中很少使用进程内存。通过swap,系统可以将这部分没有被使用的内存数据通过这种方式保存到swap中,从而释放出更多的物理内存供系统使用。很多发行版(比如ubuntu)的休眠功能都依赖于swap分区。当系统休眠时,内存中的数据会被保存到swap分区中,下次系统启动时数据会加载到内存中。它可以加快系统的启动速度,所以如果要使用休眠功能,就必须配置swap分区,而且大小必须大于等于物理内存。在某些情况下,物理内存是有限的,但是如果要运行耗内存的程序怎么办呢?这时候配置足够的swap空间就可以达到目的。虽然慢了点,但至少能跑起来。虽然在大多数情况下,物理内存是足够的,但是总会出现一些意想不到的情况,比如某个进程需要的内存比预期的多,或者某个进程发生了内存泄漏等。当内存不够时,就会触发内核的OOM杀手。根据OOMkiller的配置,会杀掉一些进程或者直接重启系统(默认是先杀掉内存消耗最多的进程),但是有了swap,就可以把swap当作内存使用。虽然速度有点慢,但至少给了我们调试、杀掉进程或者保存当前工作进度的机会。如果你看过Linux的内存管理,你就会知道,系统会尽可能多的使用空闲内存作为缓存,以加快系统的I/O速度,所以如果能把不常用的内存数据移到swap,有将更多的物理内存用于缓存,从而提高整体系统性能。交换的缺点?上面介绍了swap的优点,那么swap的缺点呢?swap存储在磁盘上,磁盘的速度比内存慢几个数量级。如果一直读写swap,那么系统性能肯定会受到影响,尤其是在系统内存很紧张的时候,读写swap空间的频率会很高,导致系统运行很慢,就好像死了一样.这时,增加物理内存是唯一的解决办法。由于系统会自动将不经常使用的内存数据移动到swap中,对于桌面程序来说,最小化后打开程序时可能会造成小卡顿,因为swap上的数据需要重新加载到内存中来。你需要交换吗?以上介绍了什么是swap以及它们的优缺点。那么你应该配置交换吗?答案是:视情况而定。下面分别讨论内存不足、内存勉强、内存充足三种情况下服务器和桌面环境swap的选择。内存不足无论是台式机还是服务器,当物理内存明显不足又要运行程序时,加swap是唯一的选择。慢下来总比不工作好。内存勉强够用。建议配置swap,这样内核会把不常用的数据从内存中移到swap中,这样系统调用就会有更多的物理内存,提高系统性能,避免偶尔物理内存不足导致进程异常。退出以提高系统稳定性,但对于服务器来说,需要限制或监控swap空间的使用。当swap空间使用超出预期或频繁swapin/out时,必须及时采取措施,否则对性能影响很大内存充足从理论上讲,如果物理内存充足且不需要sleep功能,那么swap就没有用了,但是关键问题是我们很难保证物理内存在任何情况下都是足够的,因为总会有意想不到的情况出现,比如某些进程消耗的内存超出预期,服务器压力超出预期,内存泄露等等。在内存充足的情况下,如果出现异常,swap能帮到我们吗?桌面环境一般没有任何监控功能,所以无法提前预知内存使用异常。当内存用完后,分为两种第一种情况:配置了Swap:当系统变慢时,可以感觉到,可能有机会杀掉一些进程,保存当前的工作进度。当然也会有电脑慢,想砸电脑的情况,但是在这么便宜的磁盘情况下,浪费一些磁盘空间来换取这样的机会也是值得的。Noswapconfigured:内核的OOMkiller被触发,可能连保存工作进度的机会都没有。服务器环境服务器一般都会配置监控程序,当内存使用率达到阈值时,会发出警报或自动重启异常进程。但是如果没有监控呢?当内存用完后,有两种情况:Configuredswap:此时服务器仍然可以提供服务,但是性能会下降好几个等级,直到快死掉,而且这个过程会持续很长时间时间,这对服务器来说是一场灾难;所以配置swap只能让服务逗留一段时间,之后会出现很长时间的服务中断(比如原本每秒处理1000个请求的服务器,由于频繁使用swap,结果只有50个请求每秒可以处理(从系统的角度来看,进程还在运行,但从业务的角度来看,服务已经几乎中断了)。无swap配置:此时内核的OOMkiller被触发。默认配置下,会先杀死消耗内存的进程。这种流程一般就是我们的业务流程。这时守护进程会自动重启业务进程(Nodaemonprocess?你在开玩笑),这种情况只会导致服务中断一段时间(取决于进程重启的时间),并且有不会出现因为上面swap的配置导致性能不佳,服务不断中断的情况。即使OOMkiller没有杀死预期的进程,我们也可以通过测试发现,然后配置OOMkiller重启系统,这比配置swap在那里逗留要好。从上面可以看出,对于服务器来说,好像最好不要配置swap,这样可以尽快重启有问题的进程,缩短业务受到影响的时间。而且,即使没有配置监控程序,我们在cgroups中还是有一个内存控制模块,可以控制一组进程可以使用的最大内存量。当超过这个数量时,可以触发相应的动作,比如重启进程等。一般来说,对于桌面环境来说,一般内存没有服务器端那么充裕,而且由于使用场景的原因,会打开很多不同类型的GUI窗口,但是前台只有一个进程,而且大部分它们都在后台待命,所以还是需要配置swap来提高性能;对于服务器来说,配置的内存是比较充足的,启动的进程也是需要工作的进程(否则不应该启动),不需要休眠,另外,有了cgroups,就是更容易限制进程的内存使用。个人认为配置swap基本没必要。看看coreos,默认是没有swap的。多少交换大小合适?既然配置swap对桌面系统有帮助,那么多大的swap合适呢?以下是ubuntu给出的建议:当物理内存小于1G且不需要sleep时,设置与内存大小相同的swap空间就足够了;当需要休眠时,建议配置物理内存大小的两倍,但最大值不要超过内存大小的两倍。当物理内存大于1G且不需要休眠时,推荐大小为round(sqrt(RAM)),其中RAM为物理内存大小;需要休眠时,建议大小为RAM+round(sqrt(RAM)),但最大值不要超过内存大小的两倍,如果两倍物理内存大小的swap空间不够用,建议增加内存而不是增加交换。以下是针对不同物理内存情况的详细建议。***列是物理内存的大小。第二列和第三列是在不需要和需要睡眠的情况下推荐的Size,第四列是最大值不超过Physicalmemory(MB)不需要睡眠,需要睡眠***值256256512512512512102410241024102420482048物理内存(GB)不需要休眠,需要休眠***值1122213432564268527106281283111612315241642032245294832638646487212812811139256如何配置交换?我们确定了配置多少swap空间之后,应该怎么配置呢?当然我们可以在安装系统的时候分配,但是如果我们对安装时分配的大小不满意,后面也可以调整,这里就不介绍安装时怎么配置了,只介绍怎么加交换空间到系统。Linux下有两种交换空间,交换分区和交换文件。它们各有特点:由于交换分区上没有文件系统,相当于内核直接访问连续的磁盘空间,效率比较高。但是,由于swap分区一般是在安装系统时分配的,后期缩减空间和扩容非常不方便。swap文件是放在指定分区的文件系统中,所以可能会受到文件系统性能的影响,但是据说2.6版本以后的内核可以直接访问swap文件对应的物理磁盘地址,相当于跳过文件系统,直接访问磁盘。但是,如果交换文件在磁盘上的物理位置不连续,仍然会对性能产生不利影响,但它的优点是灵活,可以随时添加和删除交换文件。查看系统中配置的swap,使用命令swapon-s查看swapdev@dev:~$swapon-sFilenameTypeSizeUsedPriority/dev/dm-1partition5242840-1如果配置了多个swap分区或文件,这里会有可以是多行,每一行代表系统正在使用的交换分区或文件。下面是各个字段的含义:Filename:如果交换类型是分区,这将是分区的路径。如果swap类型是文件,这里会是文件的路径Type:swap的类型,partition表示这是一个swap分区,file表示这是一个swap文件Size:swap的大小,单位是k,这里524284表示差不多512MUsed:已经使用过的大小,这里0表示还没有使用(round-robin算法),优先级可以通过“swapon-p”命令来设置和查看系统中swapin/out的情况,并不是swap空间太大会降低性能。对性能的真正影响是换入和换出的频率。频率越高,对系统性能的影响越大。我们可以通过vmstat命令查看swapin/out的频率#parameter2表示每两秒统计一次,si等两列是每秒swapinout的次数#parameter2表示每两秒统计一次,这两个列si和so是每秒swapin和out的次数dev@ubuntu:~$vmstat2procs------------memory------------swap----io-----system-----------cpu-----rbswpdfreebuffcachesisobiboincsussyidwast00702327562079402094760000111180019900007023275620794020947600001161861199000070228756207940209476202012019311981000702287562079402094760000117186001000000702287562079402094760000113184019900添加交换分区在添加交换分区之前,您必须先有一个空闲分区。如果是新磁盘,可以使用fdisk新建一个分区进行swap注意:操作磁盘分区时要小心。这将导致数据丢失和系统挂起。磁盘分区操作不是本文要介绍的,所以这里不讨论如何使用fdisk。#本文使用的测试环境是虚拟机,/dev/sdb是新添加的硬盘,已经用fdisk创建了分区#本例中将使用分区/dev/sdb1dev@dev:~$sudofdisk-l/dev/sdbDeviceBootStartEndSectorsSizeIdType/dev/sdb12048419430341922562G83Linux#创建swap分区dev@dev:~$sudomkswap/dev/sdb1Settingupswapspaceversion1,size=2GiB(2146430976bytes)nolabel,UUID=d69621de-618a-4bea-9a96-b8e8b0d0ea40#查看系统中现在正在使用的swap是为了与addition进行比较dev@dev:~$swapon-sFilenameTypeSizeUsedPriority/dev/dm-1partition5242840-1#添加新分区到系统dev@dev:~$sudoswapon/dev/sdb1#This可以看到系统已经添加了新的swap分区,优先级低于原来的dev@dev:~$swapon-sFilenameTypeSizeUsedPriority/dev/dm-1partition5242840-1/dev/sdb1partition20961240-2#为了确保系统重启后,我们新的swap分区会自动加载,需要修改/etc/fstab文件fieddev@dev:~$sudosh-c'echo"/dev/sdb1noneswapsw00">>/etc/fstab'#查看一下,确定写成功了,这里第一个入口是原来系统的swap分区,第二个条目是我们刚刚添加的dev@dev:~$grepswap/etc/fstab/dev/mapper/dev--vg-swap_1noneswapsw00/dev/sdb1noneswapsw00添加交换文件添加交换文件比分区。#先新建一个512M的文件,用作交换文件,文件路径可以任意可以用dd来达到同样的效果:#sudoddif=/dev/zeroof=/mnt/512MiB.swapbs=1024count=524288#fallocate和dd的区别是:#fallocate先声明这么多,然后再使用文件系统实际使用的时候分配真实的物理磁盘空间就是分配一点点,#anddd实际上一开始就往物理磁盘空间写入了512m的数据。#所以作为测试,fallocate比较方便,因为一开始不需要写任何数据,需要速度快dev@dev:~$sudofallocate-l512m/mnt/512MiB.swap#修改权限文件防止其他用户误操作此文件dev@dev:~$sudochmod600/mnt/512MiB.swap#格式化为交换文件dev@dev:~$sudomkswap/mnt/512MiB.swap#添加新文件到系统dev@dev:~$sudoswapon/mnt/512MiB.swap#此时可以看到系统中已经添加了新的swap文件,类型为file#这里可以看到由于优先级***、***swap分区/dev/dm-1已经24Kdev@dev:~$swapon-sFilenameTypeSizeUsedPriority/dev/dm-1partition52428424-1/dev/sdb1partition20961240-2/mnt/512MiB.swapfile5242840-3#即可从free命令的输出结果看,前两轮添加swap分区和文件后,#现在系统的swap空间变成了3G(3144692K)dev@dev:~$freetotalusedfreesharedbuff/cacheavailableMem:5001923911295641996451516430820Swap:3144692243144668#另外为了保证我们新建的/swap文件在系统重启后自动加载,我们需要修改etc/fstab文件dev@dev:~$sudosh-c'echo"/mnt/512MiB.swapnoneswapsw00">>/etc/fstab'注意:并不是所有的文件系统都支持创建交换文件,比如btrfs,在btrfs分区创建交换文件会失败。取消所有swap如果经过慎重考虑,确定不再需要swap,那么可以将所有swap分区和文件从系统中移除,步骤与上面正好相反#Stopallswapdev@dev:~$说明系统正在使用sudoswapoff-a#swapon-s命令无输出,free命令显示swapspace为0,说明swapoff成功。/etc/fstab,否则下次重启后,系统会重新挂载相应的swap分区和文件#用你喜欢的编辑器删除/etc/fstab中与swap相关的三行(本例中间有三行,请根据实际情况调整)如何优化swap性能?如何配置swap使其性能更好?尝试使用交换分区。与swap文件相比,分区必须是连续的物理磁盘空间,并且swap文件不能将swap分区和系统分区放在不同的磁盘上,这样就不会和系统盘争抢同一磁盘的I/O带宽磁盘。如果有多个磁盘,您可以在每个磁盘上创建它们。一个交换分区,并设置它们的优先级相同,这样内核会平均访问这些交换分区,性能相当于原来的N倍(这里N是磁盘数)。不过话又说回来,如果频繁访问swap的话,优化swap也没用。还是比内存低了好几个数量级,性能还是有所下降。如果不经常访问swap,那么优化swap有什么意义呢?所以其实优化swap性能的实际意义并不大,看这里就知道了。配置swappiness有时我们的桌面环境确实有足够的内存和交换空间。这时,我们希望尽量减少交换空间的使用,以免影响系统性能。Linux已经为我们考虑到了这种情况,在2.6内核中,增加了一个参数,叫做swappiness,用来配置将内存中不常用的数据移动到swap的紧急程度。这个参数的取值范围是0到100,0告诉内核尽量不要移动内存数据到swap,也就是只有在绝对必要的时候才这样做,100告诉内核尽量移动内存数据越多越好。不经常访问的数据被移动到交换区。Ubuntu的桌面和服务器的默认配置是60(可能随版本不同而不同)。对于桌面环境,界面的响应速度直接关系到系统的流畅度。如果内存足够,这个值可以设置的小一些,这样数据就尽量保留在内存中,这样唤醒后台接口程序会比较快。Ubuntu桌面建议将该值设置为10。当然,您可以根据交换空间的实际使用情况任意调整该参数,直到您满意为止。对于服务器来说,主要的性能衡量标准是整体的处理能力,而不是具体的响应速度。为I/O缓存使用更多内存可能更好,因此Ubuntu服务器建议保留默认值60。查看当前系统中swappiness的值dev@dev:~$cat/proc/sys/vm/swappiness60修改当前系统中swappiness的值dev@dev:~$sudosysctlvm.swappiness=10vm.swappiness=10dev@dev:~$cat/proc/sys/vm/swappiness10上面sysctl修改的swappiness值,系统重启后会失效。重启后要继续生效,需要修改配置文件/etc/sysctl.conf,将下面一行改为10,如果文件中找不到这一行,就在最后添加这一行的文件。vm.swappiness=10
