[ Content contribution] 一文说清swap,zram,zswap,交换空间和内存压缩方案
Tofloor
poster avatar
AMZ
deepin
2024-04-14 12:27
Author

先说结论:

zram就只是内存压缩技术,关机无法保存数据,如果你不希望使用休眠功能,你都不需要设置什么swap分区,直接设置zram,以zstd 1:4的压缩率来看,你设置一个你内存空间(8G)两倍的zram(16G)实际上用满了也就占用50%的物理内存(也就是4G),因此你可以认为你具有了4+16=20个G的内存来使用。
swap这个东西叫交换空间,一般有两种形态,交换分区和交换文件,只用它的话平时打开大文件也有可能写入硬盘交换空间,也可以用来休眠,断电保存工作进度。
zswapzswap是一个内核功能,它为交换页提供了一个压缩的内存缓存。原本会交换到磁盘的页被压缩并存储到内存中的存储池中。与zram 相比的区别在于,zswap与swap 设备协同工作,而zram是内存中的交换设备,不需要后备交换设备。你既要休眠就的有swap,通过调整交换率可以做到,平时别老往swap写入数据,内存压缩解决了平时开机使用的需求,只在休眠的时候数据要存到硬盘里,简直是个完美的方案。

我的终极方案是:采用btrfs+swapfile+zswap结合的方式。

注意:zswap和zram二者不可共存,使用zram时一定要关闭zswap

一.btrfs的swapfile启用:

从内核版本5.0开始支持在btrfs分区使用交换文件作为swap形态
从btrfs-progs 6.0版本之后才能通过自身磁盘工具命令来快速创建交换文件

从systemd 255版本才支持休眠到btrfs下的交换文件,可用 systemctl --version查看,因此uos专业版版本为241不可以

对于对硬盘使用没有过多要求的人实际上可以使用交换分区即可,因为即使是交换文件它也是固定占用空间的,只是具有一点灵活性,可以后期调整文件的大小。所以使用交换分区可以适应更多场景。
否则参照从前的方法来创建:https://bbs.deepin.org/post/270299

查询btrfs版本可以通过btrfs version 来查询,目前deepin23beta3是v6.3.2

btrfs version
btrfs-progs v6.3.2

这里需要注意btrfs磁盘工具在创建和使用交换文件时,存在一些局限性:

filesystem - 只能是单个硬件分区中创建
filesystem - 必须只有单个数据配置文件
subvolume - 如果包含任何活动交换文件,则无法创建快照
swapfile - 必须预先分配(即没有漏洞)
swapfile - 必须是 NODATACOW(即也是 NODATASUM,无压缩)

创建交换文件:
这个过程在系统启动状态下即可配置,无需进入live环境,@swap为独立子卷,不可用于快照
挂载父卷
sudo mount /dev/sda2 /mnt
创建 @swap子卷
sudo btrfs subvolume create /mnt/@swap
创建交换文件
sudo btrfs filesystem mkswapfile --size 8G /mnt/@swap/swapfile
输出:create swapfile /mnt/@swap/swapfile size 8.00GiB (8589934592)
启用交换文件:
sudo swapon /mnt/@swap/swapfile
激活后,该文件将出现在 /proc/swaps 中:

$ cat /proc/swaps
Filename                 Type    Size       Used      Priority
/mnt/@swap/swapfile      file    8388604    0         -2

前面的设置是临时性启用交换文件,可以通过fstab永久启用
编辑:sudo nano /etc/fstab 增加以下内容,uuid换成你的

#将子卷@swap挂载到/swap,进一步把/swap/swapfile这个文件挂载到swap,这里的处理很多资料都没写具体
UUID=0a79ef53-4ea9-4cdb-9b5e-5b7fb8ff0c64 /swap btrfs subvol=@swap 0 0
/swap/swapfile none swap sw 0 0

启用休眠到交换文件:
启用交换文件后,交换文件可用于休眠,不过这可不简单,你即使看到deepin重启界面有休眠按钮了,但任然会出错,无法正常休眠,这里需要进一步设置
在休眠之前,必须将恢复偏移量写入文件 /sys/power/resume_offset 该值是设备上的物理偏移量
Btrfs文件系统使用逻辑和物理之间的映射地址,但在这里,物理仍然可以映射到一个或多个特定设备的物理块地址。这是特定设备的物理偏移量,适合作为恢复偏移。
从btrfs-progs 6.1 版开始,有一个命令可以直接查询该偏移量,你说有些发行版不更新btrfs-progs像话吗?

$ sudo btrfs inspect-internal map-swapfile /mnt/@swap/swapfile
Physical start: 183341248512
Resume offset:      44761047

为了编写一些脚本和方便起见,选项 -r 将只打印偏移量,获得一个唯一输出:

$ sudo btrfs inspect-internal map-swapfile -r /mnt/@swap/swapfile
44761047

sudo nano /sys/power/resume_offset
写入:44761047这个值保存即可

非btrfs文件系统的情形可以使用如下命令获得偏移量值,btrfs使用该命令是不准确的:

sudo filefrag -v /swap/swapfile

取图中这个位置的值即可
image.png

但是上面这个文件重启就会失效,如何永久固化呢?

重点来了,使将以下参数加入到两个地方

sudo nano /etc/initramfs-tools/conf.d/resume
写入:resume=UUID=0a79ef53-4ea9-4cdb-9b5e-5b7fb8ff0c64 resume_offset=44761047
刷新配置 
sudo update-initramfs -c -k all
sudo nano /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="splash quiet resume=UUID=0a79ef53-4ea9-4cdb-9b5e-5b7fb8ff0c64 resume_offset=44761047"
刷新配置
sudo update-grub

二.zswap的应用:

关闭 zswap
sudo echo 0 > /sys/module/zswap/parameters/enabled
开启 zswap
sudo echo 1 > /sys/module/zswap/parameters/enabled

zswap参数设置:
zswap 有几个可自定义的参数。可以使用以下方式显示实时设置

$ grep -R . /sys/module/zswap/parameters
/sys/module/zswap/parameters/same_filled_pages_enabled:Y
/sys/module/zswap/parameters/enabled:Y
/sys/module/zswap/parameters/max_pool_percent:20
/sys/module/zswap/parameters/compressor:zstd
/sys/module/zswap/parameters/zpool:z3fold
/sys/module/zswap/parameters/accept_threshold_percent:90

其它参数参考 https://docs.kernel.org/admin-guide/mm/zswap.html

每个设置都可以在运行时通过 sysfs 接口进行更改。作为示例,要更改 compressor 参数

sudo echo zstd > /sys/module/zswap/parameters/compressor

使用内核引导参数持久化更改:

zswap.enabled=1 zswap.compressor=zstd zswap.max_pool_percent=20 zswap.zpool=z3fold

比较简单的方式是通过grub引导时传递内核参数:

sudo nano /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="splash quiet 跟着加到这里面 zswap.compressor=zstd zswap.enabled=1"

之后 sudo update-grub即可

同时我们还需要把压缩工具等放到内核模块里写入

sudo nano /etc/initramfs-tools/modules

#写入
zstd
zatd_compress
z3fold

执行 sudo update-initramfs -c -k all

三.内存压缩的启用

我的终极方案说完了,下面说说zram在debian系里的启用

zram-tools 或者 systemd-zram-generator 软件包可用于自动设置 zram 设备,uos专业版本有zram-tools而deepin有后者systemd-zram-generator

uos的方式:
安装zram-tools并启动相应服务:
sudo apt install zram-tools
默认情况下,zRAM使用的压缩算法是lzo,如果想使用其他算法或修改zRAM的大小,我们可以修改配置文件/etc/default/zramswap
sudo nano /etc/default/zramswap

#压缩算法选择,注意系统必须安装这些压缩工具
#压缩速度:lz4 > zstd > lzo
#压缩率:zstd > lzo > lz4
ALGO=zstd
#指定用于zram的RAM量,基于可用内存总量的百分比,这优先并覆盖下面的SIZE
SIZEPERCENT=70
#指定应该用于的静态RAM量单位MiB中,如果上面设置了百分比,这条将不生效,也可以注释掉
SIZE=8192
#指定交换设备的优先级,数字越大=优先级越高,这应该高于硬盘swaps的优先级
PRIORITY=100
#建立几个zram设备,默认cpu内核几个就创建几个,以此控制数量
#CORES=1

配置好以上参数启用服务即可:
sudo service zramswap reload

可以通过以下命令查看当前用于swap的zram
swapon -s

deepin的方式:
先安装
sudo apt install systemd-zram-generator
修改配置文件
/etc/systemd/zram-generator.conf
写入:

[zram0]
compression-algorithm = zstd
zram-size = ram / 2
swap-priority = 100

这里创建了一个使用zstd压缩、大小为所有可用内存容量一半的zram swap 设备(ram/2表示大小为 RAM大小的1/2;也可以设置为4G、512M这样的值)

详细扩展参数看:https://github.com/systemd/zram-generator

启用服务:

systemctl daemon-reload
systemctl start /dev/zram0

调用 zramctl 或 swapon 以确认设备已创建并正在使用中。

$zramct
lNAME       ALGORITHM DISKSIZE DATA COMPR TOTAL STREAMS MOUNTPOINT
/dev/zram0 lzo-rle       4.8G   4K   80B   12K       4[SWAP]

注意:在动完磁盘和相关操作重启之前一定要更新一下initramfs

sudo update-initramfs -c -k all

截图_gpartedbin_20240414124544.png

截图_deepin-system-monitor_20240414134910.png

  • 本文带来了一个最简单的分区方案EFI+BTRFS全局两个分区;
  • 本文真实实现了内存压缩的可用性,交换文件的可用性,平时几乎不用交换文件,休眠时做到真真的保存工作还能恢复原样
  • 对于使用虚拟机,使用同时打开20个以上标签的浏览器来说,无疑是好的选择,你可以获得流畅的体验。

以上代表了我个人对此方案的最终理解,不使用btrfs的伙伴也一样可以搞起,举一反三!

完结!

Reply Favorite View the author
All Replies
1 / 2
To page
磨剪子戗菜刀
deepin
2024-04-14 12:41
#1

内容太硬,收藏了慢慢消化

Reply View the author
阿尼樱奈奈
Moderator
2024-04-14 12:50
#2

135349106551284.jpg

Reply View the author
阿尼樱奈奈
Moderator
2024-04-14 12:52
#3

等等,sudo update-geub?
IMG_20240414_125236.jpg

Reply View the author
花雨落逝
deepin
2024-04-14 12:53
#4

好好好,你噎到我了,你负责!(doge

Reply View the author
waittingsummer
deepin
2024-04-14 12:56
#5
插个眼,等有长点的时间再用电脑看
Reply View the author
AMZ
deepin
2024-04-14 12:56
#6
阿尼樱奈奈

等等,sudo update-geub?
IMG_20240414_125236.jpg

奶奶的我正改的了

Reply View the author
buyike
Moderator
2024-04-14 13:05
#7

这个必须点个赞了。

Reply View the author
AMZ
deepin
2024-04-14 13:06
#8
buyike

这个必须点个赞了。

加精应该

Reply View the author
忘记、过去
Moderator
2024-04-14 13:20
#9

sweat 后排提醒,btrfs 文件系统玩儿 swapfile,如果还想用 timeshift 或者 snapper 备份快照,就必须把 swap 文件放到不需要备份的子卷里面(比如帖子里创建了 @swap 子卷)。


不然的话,如果直接放在需要快照的子卷,会在创建快照的时候失败(提示设备正在被写入啥的)......要是像我一样,哪天需要恢复快照了,突然发现一个快照都没建出来就搞笑了......

Reply View the author
AMZ
deepin
2024-04-14 13:57
#10
忘记、过去

sweat 后排提醒,btrfs 文件系统玩儿 swapfile,如果还想用 timeshift 或者 snapper 备份快照,就必须把 swap 文件放到不需要备份的子卷里面(比如帖子里创建了 @swap 子卷)。


不然的话,如果直接放在需要快照的子卷,会在创建快照的时候失败(提示设备正在被写入啥的)......要是像我一样,哪天需要恢复快照了,突然发现一个快照都没建出来就搞笑了......

没错,版主提醒的对,我在文中两处提及,希望伙伴们看得到

Reply View the author
TXOS-C.User
deepin
2024-04-14 15:08
#11

大师级教程啊,like

Reply View the author
AMZ
deepin
2024-04-14 16:56
#12
TXOS-C.User

大师级教程啊,like

过誉了

Reply View the author
andot
deepin
2024-04-14 22:11
#13

楼主写的非常详细,应该加个精。

请教楼主个问题,我物理内存是 64G,如果需要休眠的话,使用 zswap + swapfile 的方式,是否需要将 swapfile 设置为大于 64G。我之前觉得 swap 分区和 swapfile 太占磁盘空间了,所以直接用了 zram 做 SWAP,优点是省磁盘空间,缺点是失去了休眠功能,现在电脑不用了只能直接选择待机或关机。

Reply View the author
AMZ
deepin
2024-04-15 00:23
#14
andot

楼主写的非常详细,应该加个精。

请教楼主个问题,我物理内存是 64G,如果需要休眠的话,使用 zswap + swapfile 的方式,是否需要将 swapfile 设置为大于 64G。我之前觉得 swap 分区和 swapfile 太占磁盘空间了,所以直接用了 zram 做 SWAP,优点是省磁盘空间,缺点是失去了休眠功能,现在电脑不用了只能直接选择待机或关机。

不需要相等

Reply View the author
Tent
deepin
2024-04-15 00:27
#15

mark,学习了like

Reply View the author
andot
deepin
2024-04-15 22:59
#16
AMZ

不需要相等

64G 内存,swap 分配多大空间才能支持休眠?

Reply View the author
兆兆嘟嘟嘟
deepin
2024-04-15 23:46
#17

感谢分享。

Reply View the author
AMZ
deepin
2024-04-16 07:48
#18
andot

64G 内存,swap 分配多大空间才能支持休眠?

看你平时真实内存使用率,你比如说你平时真实内存使用率达到了32个g,那你最起码得设置比他更多,最好是设置64,如果你开虚拟机或者浏览器网页开的多的话,你会发现它是往swap存数据的,因此,根据需求,你应该设置更大的,也不能单单只考虑休眠的问题

Reply View the author
AMZ
deepin
2024-04-16 07:48
#19
兆兆嘟嘟嘟

感谢分享。

搞起来好用,流畅

Reply View the author
AMZ
deepin
2024-04-16 07:51
#20
Tent

mark,学习了like

搞起搞起

Reply View the author
1 / 2
To page