问题摘要
在启用 Ubuntu 安装程序中的 LUKS / dm-crypt 全盘加密选项后,磁盘 I/O 性能非常糟糕。写入磁盘会导致系统停滞/冻结。从磁盘读取的数据似乎已损坏。
如果我不使用 LUKS / dm-crypt,那么我就不会遇到任何问题。一切都非常稳定且性能出色。我知道加密会影响性能。我期望性能降低,而不是长达数分钟的系统冻结和数据损坏。
我以前从未在完全干净的 Ubuntu 安装中遇到过这么多问题。我不在乎出错。我只想让我的东西正常工作!
下面列出的两个系统都受到此问题的影响。所有实验都在 Ryzen 系统上进行。i5 两年来基本没有做任何事情,所以我直到现在才注意到这个问题。
系统 #1(运行约 2 年,大部分时间处于闲置状态)
- Ubuntu Server 20.04.3 LTS
- 英特尔 i5-3570
- 8GB RAM,非 ECC
- 金士顿 120GB A400 SATA 固态硬盘
- Memtest86+ 或 Prime95 没有报告任何错误
系统 #2(新系统,首次发现问题的地方)
- Ubuntu 服务器 22.04 LTS
- AMD 锐龙 5 5600
- 32GB 内存,ECC
- 金士顿 120GB A400 SATA 固态硬盘
- Memtest86+ 或 Prime95 没有报告任何错误
重现步骤
- 安装 Ubuntu 20.04 LTS 或 22.04 LTS
- 在安装过程中,设置磁盘时,选择以下选项
- 使用整个磁盘
- 将此磁盘设置为 LVM 组
- 使用 LUKS 加密 LVM 组
- 扩展包含以下内容的分区
/
,使其占用 LVM 组中的所有可用空间 - 安装并启动后,使用 SSH/samba/USB/其他方式将大文件传输到操作系统磁盘
期待
- 将大文件(大于~6GB)写入磁盘,系统不会冻结
- 从磁盘读回文件并确保它们不被损坏
现实
所有这些问题都是在 Ryzen 系统上发现的。我在 i5 系统上测试了重度 I/O 负载一次并能够重现该问题。我不敢继续推进,否则我会损坏操作系统磁盘并不得不重建它。
- 写入大文件会使系统冻结到只有控制台回显可以工作的程度。命令无法运行。甚至
ls
不会返回任何内容。SSH 传输停滞、超时并失败。 - iotop 表示至少有一个 kcryptd 工作线程达到 99% 的 IO 负载,然后挂在那里几分钟(感觉像 2-3 分钟)
- 从磁盘读回的大文件似乎已损坏。我移动了一个 VM 映像,但由于内部文件系统损坏,它无法运行超过几秒钟,否则就会崩溃。几次重启后,
apt
开始抱怨软件包损坏。网络连接停止。最终系统出现内核崩溃,我放弃了。 - 奇怪的是,它
reboot
实际上并没有重新启动。关闭操作系统后,系统将挂起并出现黑屏。灯和风扇保持打开状态。底盘重置按钮在此状态下不起作用。我必须将电源线从墙上拔下来才能让一切恢复正常。
请注意,如果操作系统没有安装 LUKS / dm-crypt,则不会出现这些问题。这包括挂起重启的奇怪问题。
另请注意,我尝试在 Ryzen 系统上运行 Windows 10 + BitLocker,没有任何问题。
附加信息
我在装有 Ubuntu 22.04 LTS 的新 Ryzen 系统上完成了所有这些操作。
- 我尝试设置
cryptsetup --allow-discards --perf-no_read_workqueue --perf-no_write_workqueue --persistent refresh
,认为这是由廉价 SSD 的一些异常引起的。它有助于提高写入性能,但读取仍然出现损坏。 - 我尝试了完全干净的重新安装,没有安装任何额外的应用程序。只有基本操作系统和 iotop。没有更新。问题仍然存在。
- 我将金士顿 SSD 换成了已知良好的 7200RPM 旋转硬盘。SATA 2.5 英寸 320GB 非 SMR。完全全新重新安装。问题仍然存在。
- 我将金士顿 SSD 换成了已知良好的 NVMe 驱动器三星 SSD 970 EVO Plus。完全全新安装。问题仍然存在。
- 我更换了 SATA 电缆,尽管没有加密一切正常。问题仍然存在。
- 所有涉及此问题的驱动器均已通过坏块和 SMART 测试。
此时,我正在认真考虑回到 Windows 10 + BitLocker,因为我不知道还能做什么。
链接
- 如何解决可能与 dm-crypt/LUKS 相关的磁盘 IO 性能问题?就是我从那里得到
cryptsetup
上述建议的。 - https://ubuntuforums.org/showthread.php?t=2474486- 我在 Ubuntu 论坛上发布的长篇大论的帖子。请注意,我在该帖子中多次提到 VirtualBox,但 VirtualBox 并不是问题所在,因为在没有安装 VirtualBox 的情况下,全新安装 Ubuntu 22.04 时问题仍然存在。问题出现时,我恰好正在使用 VirtualBox。
答案1
事实证明有两个问题共同导致了我的生活变得困难。
第一期:Ubuntu / Fedora / Linux 概述
Ubuntu 附带启用了 dm-crypt 工作 I/O 队列。显然这些队列写得不太好。内核会等到它们已满或接近已满后才尝试将它们转储到磁盘,由于多个队列都在争夺磁盘访问权限,磁盘会在负载下死机,系统会锁定。
但是“Reeeeeee!”,你会说,“事情不是这样的,队列很完美,没有什么可以写入的”别在意,我不是内核开发人员,我所知道的只是我在 iotop 中看到的内容,以及当我将大量内容写入磁盘时系统会严重锁定的事实。当系统在没有加密的情况下运行时,不会发生这种情况。dm-crypt 队列已损坏。故事结束。
如果您不同意我的观点,那么您可以阅读 Cloudflare 对此的看法。https://blog.cloudflare.com/speeding-up-linux-disk-encryption/
无论如何,禁用队列“解决”了这个问题。您可以在上面的原始帖子中看到我用来执行此操作的命令。
第二期:VirtualBox
此票:https://www.virtualbox.org/ticket/10031?cversion=0&cnum_hist=14
... 已经开放了 10 多年。根据这些信息,我猜测 VBox 对 I/O 延迟的容忍度不高,如果访问主机存储的时间过长,最终会放弃。VBox 模拟器/虚拟机管理程序/无论它是什么,都会返回到客户虚拟机并说“抱歉,我无法读取或写入磁盘”。
VM 如何处理充当有缺陷硬盘的虚拟化 I/O 层?它无法处理。它会立即爆炸成原子,就像超级英雄在灭霸的打击下失败了一样。
我通过放弃 VirtualBox 并切换到 KVM 来“解决”这个问题。我现在使用 SSH 上的 virt-manager 和 X-forwarder 来做我的事情。KVM 似乎对慢速主机 I/O 的容忍度更高,这使其与 LUKS 完美匹配。
切换到 KVM
VirtualBox .vdi 文件可轻松转换为 .qcow2 格式。关于如何执行此操作的教程数不胜数。
在启用 x-forwarding 的情况下,virt-manager UI 在 SSH 上运行良好。
USB 直通到客户虚拟机也很好用。如果您的权限设置不正确,您可能需要编辑 udev 规则。同样,通过 Google 可以轻松找到大量有关此信息。
如果您希望从 VirtualBox 进行同样的操作,但希望客户虚拟机上的桥接网络适配器直接连接到网络(就像我一样),那么您需要相应地更改 netplan 设置。这是我自己的配置文件中的一个示例:
network:
version: 2
renderer: networkd
ethernets:
eno1:
match:
name: eno1
dhcp4: no
optional: yes
bridges:
br0:
macaddress: 74:46:a0:b4:39:b9
dhcp4: yes
interfaces:
- eno1
如果您不想弄乱 DHCP 静态映射,请将桥接 MAC 设置为物理 NIC 的 MAC。