====== 为 VPS 添加 swap ======
本篇为 [[https://www.digitalocean.com/community/tutorials/how-to-add-swap-space-on-ubuntu-20-04|How To Add Swap Space on Ubuntu 20.04 - by Brian Boucheron]] 的翻译。原文以 [[https://creativecommons.org/licenses/by-nc-sa/4.0/|Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License]] 发布,本文沿用相同协议发布。
翻得较为随意。翻译中注意到的一些问题会以__注__的方式给出。
===== 太长不看 / TL;DR =====
这部分是本篇文章命令的总结,不在原文中。
1. 查看系统内存状态以及 swap 信息:
free -h
2. 检查硬盘可用空间:
df -h
3. 在根目录下 ''/'' 创建 1G 的名为 ''swapfile'' 的 swap 文件:
(ext4 文件系统的情况,更快速)
sudo fallocate -l 1G /swapfile
(更保险)
sudo dd if=/dev/zero of=/swapfile bs=1M count=1024 status=progress
4. 设置安全的权限:
sudo chmod 600 /swapfile
5. 初始化 swap 文件:
sudo mkswap /swapfile
6. 启用 swap 文件:
sudo swapon /swapfile
7. 备份 ''/etc/fstab'' 文件:
sudo cp /etc/fstab /etc/fstab.bak
使用 ''/etc/fstab'' 文件来使 swap 开机自动开启:
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
8. 配置 ''swappiness'':
sudo sysctl vm.swappiness=10
配置 ''/etc/sysctl.conf'' 使 ''swappiness'' 开机自动设置(也可以使用 ''nano'' 编辑器):
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf
9. 若想删除 swap,可以拉到页面最下方。
===== 引言 =====
解决应用程序内存不足的一种方法是在您的服务器上添加 swap 空间。在本教程中,我们会阐述在 Ubuntu 20.04 服务器上添加 swap 文件的方法。
**警告**:虽然在使用传统的机械硬盘的系统上 swap 一般是推荐的配置,但是在固态硬盘上放置 swap 可能导致硬件老化而造成问题。因此,我们不推荐在 DigitalOcean 或是其它使用 SSD 储存的提供商上使用 swap。
__注__:
* 在 VPS 描述里,机械硬盘一般为 HDD,固态硬盘一般为 SSD。这句警告是 DigitalOcean 原文教程里有的。但是,因为这种硬件老化的问题应该在 VPS 提供商维护的范围之内,所以一般也不用太担心,平时做好备份即可。
* 在另外一个教程 [[https://www.digitalocean.com/community/tutorials/how-to-add-swap-space-on-debian-10|How To Add Swap Space on Debian 10 - by Brian Boucheron - CC-BY-NC-SA]] 提到了另一点:因为大多时候 VPS 的硬盘是与其它用户共享的,所以如果其它用户“过度”使用使硬件老化了,那么该坏还是会坏。
===== swap 是什么? =====
swap 是操作系统划分出来的硬盘上的一部分储存空间,这部分空间可以临时储存内存中过多的数据。忽略一些限制,这就相当于增加了服务器上的内存大小。硬盘上的 swap 空间主要会在内存不足的情况下使用。
硬盘会比内存慢很多,但操作系统也会倾向于把数据保存在内存中,而把更老的数据放到 swap 中。总体上,swap 可以作为内存耗尽时的后备手段,用于在非 SSD 系统上避免内存不足的错误。
__注__:
* “非 SSD 系统”也是原文有的。与上面的注释相同,还请根据自身情况决定是否在 SSD 机器上使用 swap。
* swap 是硬盘上的储存空间,这部分空间可以是某个文件,即下文所说的 swap 文件,也可以是某个硬盘分区,即 swap 分区。本教程使用的是 swap 文件。
===== 第一步:检查系统的 swap 信息 =====
在我们开始前,我们可以检查系统是否已经有 swap 了。我们可以拥有多个 swap 文件或是 swap 分区,但总体上一个应该就够了。
我们可以使用以下命令查看系统是否已经配置有 swap:
sudo swapon --show
如果您没有得到任何输出,那这就意味着您的系统还没有 swap 空间。
您可以使用 ''free'' 工具来验证没有 swap 被开启:
free -h
输出:
total used free shared buff/cache available
Mem: 981Mi 122Mi 647Mi 0.0Ki 211Mi 714Mi
Swap: 0B 0B 0B
您可以在输出的 Swap 一行上看到系统中没有开启的 swap。
===== 第二步:查看硬盘的可用空间 =====
在我们创建 swap 文件前,我们需要检查硬盘的使用情况来确保硬盘有足够空间。使用下面的命令来进行:
df -h
输出:
Filesystem Size Used Avail Use% Mounted on
udev 474M 0 474M 0% /dev
tmpfs 99M 932K 98M 1% /run
/dev/vda1 25G 1.4G 23G 7% /
tmpfs 491M 0 491M 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 491M 0 491M 0% /sys/fs/cgroup
/dev/vda15 105M 3.9M 101M 4% /boot/efi
/dev/loop0 55M 55M 0 100% /snap/core18/1705
/dev/loop1 69M 69M 0 100% /snap/lxd/14804
/dev/loop2 28M 28M 0 100% /snap/snapd/7264
tmpfs 99M 0 99M 0% /run/user/1000
在本例中,''Mounted on'' 一列是 ''/'' 的一行就是我们的硬盘。例中我们有很多可用的空间(只使用了 1.4G,有 23G 可用)。您的使用情况很可能会不同。
虽然在 swap 空间的适当大小上有许多不同的观点,但这其实非常依赖于您个人的偏好以及您的应用程序的需求。一般来说,与系统内存大小相同或是内存大小的两倍的大小是比较好的起点。另外一个好的经验规则是,如果您只是把 swap 用于内存的备用手段的话,所有大于 4G 的 swap 大概都是不必要的。
__注__:
* 对想要安装 Mastodon 或是 Misskey 的朋友们:您的教程里大概已经有推荐的 swap 大小了。如果没有其实也不用太担心,因为如上面提到的,swap 可以有很多个,在编译时如果发现 swap 不够了,我们完全是可以临时再添加另一个 swap 来苟活过去的。
* 编译时查看 swap 够不够:可以另外开一个 ssh 窗口,稍微利用一下上面的 ''free -h'' 命令即可看到 swap 的剩余量。使用 ''while true; do free -h; sleep 3; done'' 可以自动每三秒输出一次 swap 情况,按 ''Ctrl+C'' 退出。
===== 第三步:创建 swap 文件 =====
既然我们知道了硬盘的可用空间,我们可以在文件系统上创建一个 swap 文件了。我们会在根目录(''/'')下创建一个叫做 ''swapfile'' 的、我们想要的大小的文件。
==== 检查文件系统 ====
__注__:检查文件系统这段原文没有。但是保险起见还是增加这一段说明一下。
创建文件的方式不同文件系统可能有不同。使用一下命令查看您的文件系统:
mount | grep -w /
输出:
/dev/vda1 on / type ext4 (rw,relatime,errors=remount-ro)
紧跟在 ''type'' 后的即为文件系统类型(例中为 ''ext4'')。其实我不认为您会遇到不是 ''ext4'' 的情况。
若的确为 ''ext4'',您可以直接使用 ''fallocate 途径''(见下),这种方法会快一些。
若为 ''brtfs'',请跟随这里 ArchWiki 的英文教程 [[https://wiki.archlinux.org/index.php/Btrfs#Swap_file|Btrfs#Swap_file]] 。
若为非 ''ext4'' 的文件系统或是 ''fallocate 途径'' 出现错误,因为我不清楚该文件系统的支持情况,请尝试 ''dd 途径''(见下)。这个途径会慢一些,但最稳定。
==== fallocate 途径 ====
创建 swap 文件的最好方式是使用 ''fallocate'' 程序。这个命令即时创建一个指定大小的文件。
因为我们例中的服务器有 1G 的内存,我们在本教程中会创建 1G 的 swap 文件。请根据您服务器的需要调整:
sudo fallocate -l 1G /swapfile
我们可以使用以下命令确认我们分配了正确大小的空间:
ls -lh /swapfile
输出:
-rw-r--r-- 1 root root 1.0G Apr 25 11:14 /swapfile
我们的文件已经用正确的大小的空间创建了。
==== dd 途径 ====
__注__:这段原文没有。但是保险起见还是增加这一段说明一下。
创建 swap 文件的最保险的方式是使用 ''dd'' 程序。我们使用这个命令往文件中写入一定大小的空白数据,从而使文件变为我们想要的大小。
因为我们例中的服务器有 1G 的内存,我们在本教程中会创建 1G 的 swap 文件。请根据您服务器的需要调整:
sudo dd if=/dev/zero of=/swapfile bs=1M count=1024 status=progress
注意这里您需要做一定的换算:命令里的 ''1024'' 单位为 MB,若您需要创建例如 2G 的文件,则应乘 1024 换算为 ''2048'',将命令中的 ''1024'' 改为 ''2048'' 命令变为:
sudo dd if=/dev/zero of=/swapfile bs=1M count=2048 status=progress
我们可以使用以下命令确认我们分配了正确大小的空间:
ls -lh /swapfile
输出:
-rw-r--r-- 1 root root 1.0G Apr 25 11:14 /swapfile
我们的文件已经用正确的大小的空间创建了。
===== 第四步:启用 swap 文件 =====
既然我们已经有了一个正确大小的文件,我们需要把这个文件真正变为 swap 空间。
首先,我们需要锁定文件的权限,使得只有 root 权限的用户可以读到里面的内容。这阻止了普通用户访问这个文件,不然会有很大的安全问题。
使用以下命令使文件只能被 root 访问:
sudo chmod 600 /swapfile
使用以下命令验证权限的改变:
ls -lh /swapfile
输出:
-rw------- 1 root root 1.0G Apr 25 11:14 /swapfile
''-rw------- 1 root root'':您可以看到,只有 root 用户对应着开启的读写标记。
我们现在可以使用以下命令标记这个文件为 swap 空间:
sudo mkswap /swapfile
输出:
Setting up swapspace version 1, size = 1024 MiB (1073737728 bytes)
no label, UUID=6e965805-2ab9-450f-aed6-577e74089dbf
在标记后,我们可以启用 swap 文件,让我们的系统可以开始使用它:
sudo swapon /swapfile
验证 swap 已经可用:
sudo swapon --show
输出:
NAME TYPE SIZE USED PRIO
/swapfile file 1024M 0B -2
我们可以检查 ''free'' 工具的输出来再次验证:
free -h
输出:
total used free shared buff/cache available
Mem: 981Mi 123Mi 644Mi 0.0Ki 213Mi 714Mi
Swap: 1.0Gi 0B 1.0Gi
我们的 swap 已经成功建立,我们的系统会在必要时开始使用它。
===== 第五步:使 swap 变永久 =====
我们上面的改变开启了 swap 文件。但是,如果我们重启,服务器不会自动保持 swap 的设置。我们可以将 swap 文件添加到 ''/etc/fstab'' 中来改变这一点。
备份 ''/etc/fstab'' 文件,以免出错:
sudo cp /etc/fstab /etc/fstab.bak
添加 swap 文件的信息到 ''/etc/fstab'' 文件的尾部:
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
接下来我们会复查一些我们可以优化的 swap 空间的设置。
===== 第六步:优化 swap 设置 =====
您可以配置一些选项来影响您系统与 swap 有关的性能。
==== 设置 swappiness ====
''swappiness'' 参数配置了系统在内存与 swap 空间之间交换的频率。''swappiness'' 可以是 0 到 100 之间的值。
在 ''swappiness'' 接近 0 时,除非绝对需要,系统不会把数据交换到硬盘上。要记住:swap 文件的操作很“昂贵”,因为比起操作内存来,swap 的操作时间长很多,而这会导致显著的性能下降。让系统尽可能不依赖 swap 总体来说会使系统更快。
''swappiness'' 接近 100 时,系统会尽可能把数据放到 swap 里,使内存更多空余。看应用程序的内存使用状况以及服务器的用途,这也有可能在某些情况下更好一些。
我们可以使用以下命令查看当前的 ''swappiness'':
cat /proc/sys/vm/swappiness
输出:
60
对于桌面电脑,60 的 ''swappiness'' 并不坏。对于服务器,您可能想要把它改到接近于 0.
我们可以使用 ''sysctl'' 命令来将 ''swappiness'' 更改至不同的值。
例如,将 ''swappiness'' 更改到 10,我们可以使用命令:
sudo sysctl vm.swappiness=10
输出:
vm.swappiness = 10
这一设置在重启后会消失。我们可以在 ''/etc/sysctl.conf'' 中加入一行来在重启后自动设置 ''swappiness''。使用 ''nano'' 来编辑:
sudo nano /etc/sysctl.conf
在文件最底部,加入一行设定您选定的 ''swappiness'' 值:
vm.swappiness=10
在完成后,保存并关闭文件。
==== 调整缓存压力设定 ====
您可能会想更改另一相关的值 ''vfs_cache_pressure''。这项设定配置系统回收 inode 和 dentry 信息缓存的偏好程度。
基本上,这些是文件系统的访问数据。一般上,这些信息查找的花销大,而使用的频率又极高,所以系统缓存这些数据是极好的。你可以访问 ''proc''文件系统来查看当前设定值:
cat /proc/sys/vm/vfs_cache_pressure
__注__:此值范围为 0 到 500,100 是默认值,一般认为是比较中庸的一个值。这个值的推荐范围我在网上也暂时没有找到另外的依据,所以对下文的“移除的速度太快”的说法不予置评。基本上不要设到太接近于 0 应该都还行,或者也可以直接保留默认值。
在这样的设定来看,我们的系统将 inode 信息移除的速度太快了。我们可以使用以下命令设置为一个更保守的值:
sudo sysctl vm.vfs_cache_pressure=50
输出:
vm.vfs_cache_pressure = 50
同样,这个值设置重启就会消失。和 ''swappiness'' 的操作一样,我们可以在配置文件里加入这个设定使重启后自动设置。''nano'' 编辑器打开文件:
sudo nano /etc/sysctl.conf
在文件底部加入一行设定您选定的值:
vm.vfs_cache_pressure=50
修改完成后保存并关闭文件。
===== 总结 =====
(没什么东西,不译了。)
===== 删除 swap =====
若想删除一个在根目录 ''/'' 下的名为 ''swapfile'' 的 swap 空间,先让系统停止使用该 swap:
sudo swapoff /swapfile
之后直接删除该文件:
sudo rm -f /swapfile
如果设置了 ''/etc/fstab'' 不要忘了从 ''/etc/fstab'' 中删去有关该 swap 的一行。使用 ''nano'' 编辑器编辑:
sudo nano /etc/fstab
在文件中找到对应的一行并删除。