NixOS 上的 Swap、ZRAM、Zswap 和休眠
摘要
本文介绍了如何在 NixOS 中配置 Swap、ZRAM、Zswap 和休眠功能,适用于桌面和笔记本电脑,包含实际示例和优化设置的建议。
暂无内容
查看缓存全文
缓存时间: 2026/09/23 22:01
# 在 NixOS 上配置 Swap、ZRAM、Zswap 和休眠功能
来源:https://blog.matthewbrunelle.com/swap-zram-zswap-and-hibernate-on-nixos/
我从之前那篇关于 NixOS 非显而易见的配置的博文(https://blog.matthewbrunelle.com/non-obvious-nix-options/)中提取了这部分内容,作为独立文章发布。注意:我将参加 2026 年的 NixCon 大会 (https://2026.nixcon.org/?ref=blog.matthewbrunelle.com),如果您也参加,请打个招呼!
## 哦不,我要开始聊 swap、zram、zswap 了...
关于是否要使用 swap,网上一直争论不休。当人们将服务器环境的建议与工作站环境的建议混为一谈时,讨论常常变得混乱。在我这里,我将专注于桌面和笔记本电脑的配置。
我使用 swap 是因为我喜欢“挂起后休眠”功能(在 KDE 设置中称为“待机,然后休眠”):![[Pasted image 20260917120542.png]]
这个流程会先通过 ACPI S3 状态挂起到内存,经过一段延迟后再进入 S4 休眠状态。我认为这是一个很好的平衡点:如果我短暂离开,不需要等待系统重新启动;但又不必担心忘记完全关机。
要使用休眠功能,你需要 swap 空间来将系统状态保存到磁盘。
---
## 让我们再添加一些争论点
关于使用 swap 文件还是 swap 分区 (https://news.ycombinator.com/item?id=49618087&ref=blog.matthewbrunelle.com) 也一直存在争议。我主要想指出的是,使用 swap 文件可能会使休眠功能变得复杂。这是因为当从休眠状态恢复时,initramfs 需要在文件系统挂载**之前**就知道 swap 空间的位置。在 UEFI 系统上,这些详细信息会在启动休眠时保存到一个 EFI 变量中。
我为我的桌面配置了一个简单的 swap 分区:
```
swapDevices = [
{device = "/dev/disk/by-uuid/f2fc399a-9703-450b-88df-5671b776fc71";}
];
```
我为我的笔记本配置了 LUKS 加密和一个 swap 文件:
```
fileSystems."/.swapvol" = {
device = "/dev/disk/by-uuid/33682d1d-87c4-4166-8d3b-66d900387e42";
fsType = "btrfs";
options = ["subvol=swap"];
};
...
swapDevices = [
{
device = "/.swapvol/swapfile";
size = 32 * 1024;
}
];
```
这个配置基于 disko 的 luks-btrfs-subvolumes 模板 (https://github.com/nix-community/disko/blob/master/example/luks-btrfs-subvolumes.nix?ref=blog.matthewbrunelle.com)。
好消息是,NixOS 早已理解了在 swap 文件上实现休眠的细微差别,并能自动处理偏移量的计算。
---
## 我目前使用的配置
既然要使用 swap,我就想确保配置正确。Chris Down 的文章《In Defence of Swap》(《为 Swap 辩护》)(https://chrisdown.name/2018/01/02/in-defence-of-swap.html?ref=blog.matthewbrunelle.com) 和后续的《Debunking zswap and zram myths》(《揭穿 zswap 和 zram 的迷思》)(https://chrisdown.name/2026/03/24/zswap-vs-zram-when-to-use-what.html?ref=blog.matthewbrunelle.com) 提供了大量重要的背景信息。作为起点,Chris Down 推荐使用带有磁盘后端 swap 的 zswap。
所以,我目前的配置很简单:
```
boot.zswap.enable = true;
boot.kernel.sysctl."vm.swappiness" = 100;
```
没错,真的就这么多。我喜欢这个配置既不冗长也不复杂。行数少并不意味着它不重要。
为什么选择这个特定的 swappiness 值?Swappiness(交换倾向性)控制着交换内存和文件系统分页的相对开销,因此它取决于你特定的硬件。Chris 建议 swappiness 设为 100 在 SSD 系统上效果很好,但他也指出“仅凭直觉来调整这个值是不太可靠的”,你应该测试不同的值。内核文档 (https://docs.kernel.org/admin-guide/sysctl/vm.html?ref=blog.matthewbrunelle.com#swappiness) 同意这一观点,并表示在 SSD 上甚至可以设置更高的值。
然而,我还没有在任何地方找到明确的指导,说明如何测试和比较不同的 swappiness 值,特别是对于工作站使用场景。如果你有任何建议,我很乐意听取。目前,对于我的 SSD 系统来说,100 这个值运行良好。
---
## 我曾经犯过的错误
在读到 Chris 的第二篇文章之前,我一直在使用 `zramSwap.enable` (https://search.nixos.org/options?channel=unstable&query=zramSwap.enable&type=options&ref=blog.matthewbrunelle.com#show=option%253AzramSwap.enable),因为我以为这是他推荐的方式。然而,我搞错了,实际情况恰恰相反。直到今年四月 (https://github.com/NixOS/nixpkgs/pull/470366?ref=blog.matthewbrunelle.com) `boot.zswap` (https://search.nixos.org/options?channel=unstable&query=boot.zswap&type=options&ref=blog.matthewbrunelle.com#show=option%253Aboot.zswap.enable) 被添加进来时,我才意识到这一点。所以需要澄清的是,`zramSwap` 通常就是指 `zram`。当你使用基于磁盘的 swap 时,这很可能不是你想要的。对我来说,我需要休眠功能,所以这是一个错误的选择。
在意识到这点后,我移除了 `zramSwap.enable`,开始使用 `boot.zswap`:
```
boot.initrd.systemd.enable = true;
boot.zswap = {
enable = true;
compressor = "lz4";
};
boot.kernel.sysctl."vm.swappiness" = 100;
```
你会注意到,zswap 的压缩算法可以通过 `boot.zswap.compressor` (https://search.nixos.org/options?channel=26.05&query=boot.zswap.compressor&ref=blog.matthewbrunelle.com) 来控制。Linux 内核默认使用 `lzo`,因为它在速度和压缩率之间取得了良好的平衡。而 NixOS 默认使用 `zstd`,理由是它拥有最佳的压缩率,并且对 Nix 构建有益。
直到最近,我还在使用 `lz4`,它具有最快的压缩速度和最低的延迟。我做出这个选择是参考了 Arch Wiki (https://wiki.archlinux.org/title/Zswap?ref=blog.matthewbrunelle.com) 的内容,该页面主要使用 `lz4` 作为压缩器。但现实情况是,当内存溢出到磁盘时,压缩速度往往不是瓶颈。更好的压缩率可以让你在内存的压缩池中放入更多页面,从而减少磁盘的使用。
所以现在我使用 NixOS 的默认值 `zstd`。另外,当我添加那个配置时,`lz4` 需要启用 `boot.initrd.systemd.enable` (https://search.nixos.org/options?channel=unstable&query=boot.initrd.systemd.enable&ref=blog.matthewbrunelle.com)。这个选项现在默认为 true,所以我也可以移除那一行。最终,配置就只剩下两行。
我写作关于各种项目、活动和想法,但它们都有一个共同点:我学到了一些东西,并想与他人分享我的经验。
没有垃圾邮件,没有分享给第三方。只有你和我。
相似文章
将 NixOS 的内存占用和资源需求缩减到最低限度
一篇详细的文章,展示了如何对 NixOS 26.05 进行调优,使其空闲时仅占用 96MB 内存,并能在 512MB 内存下完成完整重建,方法包括使用内核命令行参数、屏蔽模块以及禁用未使用的硬件支持,适用于 KVM 虚拟机场景。
交换表、闪存友好的交换、swap_ops 等
本文介绍了 Linux 内核交换子系统的最新改进和未来计划,包括减少每页开销、基于 folio 的辅助函数,以及使交换更适配固态存储的努力。相关内容在 2026 年 Linux 存储、文件系统、内存管理与 BPF 峰会上进行了讨论。
NNN Stack: NixOS, Niri, Noctalia
NNN Stack 结合了 NixOS、Niri 组合器和 Noctalia shell,创建了一个声明式、可滚动且可复现的桌面环境,并邀请用户贡献他们的 dotfiles。
能给我更小的NixOS ISO吗?
关于构建最小化NixOS ISO并缩小其大小的指南,包含与Alpine Linux的对比以及逐步优化技巧。
你为什么选择了你否决的那个 nix?
一场 Lobsters 社区讨论,对比了 Determinate Nix、Lix、Guix 等 Nix 实现,以及 snix/tvix 等替代方案,探讨了生态系统的取舍、向上游贡献的相关顾虑,以及哪种版本适合不同的用户。