====== 为 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 在文件中找到对应的一行并删除。