前言

随着云服务的普及,很多人都购买了云主机来部署一些简单的服务,但通常出于成本的考虑,不会购买特别大型的机器,在有限的硬件资源下,如何让服务器响应更快?如何避免应用出现内存不足的错误?最简单的方法就是增加交换空间(Swap)。

Swap是存储盘上的一块自留地,操作系统可以在这里暂存一些内存里放不下的东西。这从某种程度上相当于增加了服务器的可用内存。虽然从swap读写比内存慢,但总比没有好,算是内存不够时的安全网。如果没有swap,则服务器一旦内存不足,就会开始终止应用以释放内存,甚至会崩溃,这会让你丢失一些还没来得及保存的数据,或者造成当机。有些应用明确要求系统配置swap以确保数据访问的可靠性。

在Windows系统中,这种交换空间叫做虚拟内存,可以在系统->高级->性能->虚拟内存中进行配置。Linux系统下的交换空间配置略为不方便。因此,本文参考了网上的多篇博文,总结记录了在CentOS 7系统的云服务器上创建并启用swap文件的过程中的命令和注意事项。

注:swap通常在传统机械硬盘上表现更好,在SSD上使用swap可能会造成问题,尤其是硬件老化之后。所以,对于DigitalOcean以及其他使用基于SSD的云主机服务的用户,我们不推荐启用swap。这甚至会影响到跟你的虚拟机共用宿主机的其他用户。对于DigitalOcean用户,提升性能的最佳方法就是更新Droplet。通常来说,升级后的主机表现都会有所提升,并且更不容易受到硬件问题的影响。

准备工作

首先,你需要能够登录CentOS服务器的root用户,或者配置过具备sudo权限的非root用户。准备就绪后,以该用户名SSH到你的CentOS服务器上,准备安装swap文件。

检查系统的Swap信息

首先我们需要检查系统的存储,看看是否已经配置过swap。一个系统可以设置多个swap文件或分区,不过一般来说一个就够了。

使用swapon命令可以检查系统是否已经配置过swap,这是一个通用的swap工具。使用-s标签可列出当前存储设备上的swap使用情况:

$swapon -s

如果该命令没有返回出结果,则代表该系统尚未配置过swap。或者,我们也可以使用free工具来查看系统的整体内存使用情况,这里可以看到内存和swap的使用状态(显示单位为MB):

$free -m
              total        used        free      shared  buff/cache   available
Mem:           1838         946          63           0         828         712
Swap:          1023           0        1023

这里可以看到我们这个系统的total swap空间为0,即没有配置过swap。这与我们在swapon里看到的结果相符合。

检查可用的存储空间

通常,我们建立一个单独的分区作为swap。然而有时候由于硬件或软件的限制,新建分区的方式无法实现,这种情况下就可以建立一个swap文件来实现同样的功能。开始之前,先检查一下磁盘的可用空间。输入如下指令:

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1        40G   22G   16G  60% /
devtmpfs        909M     0  909M   0% /dev
tmpfs           920M     0  920M   0% /dev/shm
tmpfs           920M  704K  919M   1% /run
tmpfs           920M     0  920M   0% /sys/fs/cgroup
tmpfs           184M     0  184M   0% /run/user/1000

这里的-h标记是为了告诉dh将信息输出为对人类友好的格式,比如以MB或GB为单位输出空间使用和空余情况,而不是直接输出内存块的个数。从第一行可以看到我们的存储分区上还有16GB的空间剩余,这足够我们操作了。(我这是一台微型的新建云主机,每个人的情况可能有很大不同。)

合适的swap空间是多大?关于这个问题有很多种选择,这取决于你的应用需求和你个人的偏好。一般来说,内存容量的一到两倍就是个不错的选择。Redhat官方推荐的swap大小设置如下:

我们系统有1G内存,我们首先设置1G的swap空间。

创建Swap文件

接下来我们将在文件系统上创建swap文件。我们要在根目录(/)下创建一个名叫swapfile的文件,当然你也可以选择你喜欢的文件名。该文件分配的空间将等于我们需要的swap空间。

最快捷的创建方式是fallocate命令,该命令能够创建一个预分配指定大小空间的文件。输入如下指令创建一个1GB的文件,我们可以用ls命令检查文件大小::

$ sudo fallocate -l 1G /swapfile

$ ls -lh /swapfile
-rw-r--r-- 1 root root 1.0G Sep 21 10:36 /swapfile

至此,我们的swap文件就创建完毕了。

启用Swap文件

现在我们已经有了swap文件,但系统还不知道应该使用该文件作为swap,这就需要我们告知系统将该文件格式化为swap并启用起来。

首先我们需要更改swap文件的权限,确保只有root才可读,否则会有很大的安全隐患。然后执行下面的命令启用swap文件。

#更改swap文件权限
$ sudo chmod 600 /swapfile

#基于该文件用于创建swap
$ sudo mkswap /swapfile
Setting up swapspace version 1, size = 1048572 KiB
no label, UUID=a15f0afc-e767-4971-bcdd-35939ed5d09a

#开始使用该swap
$sudo swapon /swapfile

#确认是否生效
$ swapon -s
Filename				Type		Size	Used	Priority
/swapfile                              	file	1048572	0	-1

#查看内存
$ free
              total        used        free      shared  buff/cache   available
Mem:        1882740      951540       79076         728      852124      747740
Swap:       1048572           0     1048572

至此,我们的swap已经设置完毕,操作系统会在需要的时候使用它。

扩展swap大小

若使用过程中需要扩展swap空间,可以动态扩展swap的大小。

#关闭所有swap
$sudo swapoff -a

#增大swapfile大小,bs=block size指每个块的大小,count是块数,
#count=2048表示新的swapfile的大小是2G
$sudo dd if=/dev/zero of=/swapfile bs=1M count=2048

#设置swap
$sudo mkswap /swapfile

#打开swap
$sudo swapon /swapfile

至此,我们的swap已经设置完毕,操作系统会在需要的时候使用它。

使swap配置永久生效

至此我们已经在系统中启用了swap文件,然而一旦系统重启后,服务器还不能自动启用该文件。要让系统在重启后自动生效swap,我们可以通过修改fstab文件来实现(这是一个管理文件系统和分区的表)。用sudo权限打开该文件编辑:

$ sudo vim fstab

#在文件末尾加入
/swapfile   swap    swap    sw  0   0

添加完毕后,保存退出。以后服务器每次重启都会检查该文件并自动启用swap

优化swap

有几个涉及swap的选项可能会影响到系统的性能表现。大部分情况下这些选项是可选的,具体要修改成什么样则取决于你的应用需求以及个人偏好。

Swappiness

swappiness参数决定了系统将数据从内存交换到swap空间的频率,数值设置在0到100之间,代表系统将数据从内存交换到swap空间的力度。

该数值越接近于0,系统越倾向于不进行swap,仅在必要的时候进行swap操作。由于swap要比内存慢很多,因此减少对swap的依赖意味着更高的系统性能。

该数值越接近于100,系统越倾向于多进行swap。有些应用的内存使用习惯更适合于这种情况,这也于服务器的用途有关。输入如下命令查看当前的swappiness数值:

$cat /proc/sys/vm/swappiness

CentOS 7默认设置了30的swappiness,这对于大部分桌面系统和本地服务器是比较中庸的数值。对于VPS系统而言,可能接近于0的值是更加合适的。使用sysctl命令可以修改swappiness。比如将swappiness设为10:

$sudo sysctl vm.swappiness=10

本次修改将一直生效到下次重启前。如果希望永久修改该数值,则需要编辑sysctl配置文件:

$sudo vim /etc/sysctl.conf

#修改配置项vm.swappiness,若果没有,则将其添加到末尾
vm.swappiness=10

编辑完成后,保存退出,之后服务器每次重启的时候会将swappiness设置为该值。

缓存压力(Cache Pressure )

另一个可以考虑更改的配置项是vfs_cache_pressure,该配置项涉及特殊文件系统元文件条目的存储。对此类信息的频繁读取是非常消耗性能的,所以延长其在缓存的保存时间可以提升系统的性能。通过proc文件系统查看缓存压力的当前设定值:

$cat /proc/sys/vm/vfs_cache_pressure

这个数值是比较高的,意味着系统从缓存中移除inode信息的速度比较快。一个保守一些的数值是50,使用sysctl命令进行设置:

$sudo sysctl vm.vfs_cache_pressure=50

这条命令仅在重启前有效。要让该设置永久有效,需要编辑sysctl配置文件:

$sudo vim /etc/sysctl.conf

#修改配置项vm.vfs_cache_pressure,若果没有,则将其添加到末尾
vm.vfs_cache_pressure=50

保存退出,服务器就会在每次重启后都自动将缓存压力设置为50了。

总结

至此,我们的系统内存就获得了一些喘气的空间。有了swap空间可以有效避免一些常见的问题。

如果你仍然会遇到内存不足(OOM,out of memory)的错误信息,或者你的系统不能运行你需要的应用,那么最好的方法是优化你的应用配置或者升级你的服务器,不过配置swap空间也不失为一个灵活的节省方案。

参考:

https://blog.csdn.net/zstack_org/article/details/53258588

https://www.jianshu.com/p/455ea0af98af

https://blog.csdn.net/dogfish/article/details/68958959