我最近在配备 i7-6820HQ、32GB 内存和 512GB 美光 1100 SSD 的联想 T460p 上安装了 Ubuntu 16.04 LTS(内核 4.8.0-52)。我在安装过程中检查了全盘加密框并使用了默认的分区布局。总的来说,性能很棒。
然而,随着时间的推移,我的构建开始运行大约需要两倍的时间。此外,在写入大文件的构建部分期间,任何需要磁盘 I/O 的(非构建)任务最终都会等待很多。这包括启动新程序、在 Firefox 中加载页面等。例如,在 Firefox 中,我可以导航 UI、切换选项卡,一切都很好。但是如果我点击一个链接,整个 UI 就会锁定,直到事情平静下来。
所以总而言之,经过一段时间后,构建突然需要更长的时间,并且在构建过程中的某些时间点计算机基本上无法使用。
我该怎么做才能尝试诊断或解决此问题?
不要经常重启,所以在我遇到这个问题之前系统通常会运行几天。一旦我击中它,我就试图找出问题所在,然后重新启动以便我可以继续工作。
解决问题的唯一方法是重新启动机器。我已经尝试退出所有应用程序,注销并重新登录,并删除缓冲区缓存(连枷理论,因为它使用内存空间磁盘同步发生得更频繁),但只有重新启动才有效。
从长远来看,我尝试了这个答案的解决方案,但行为没有变化。
每当我遇到问题时,运行都会iotop显示dmcrypt_write使用 99% I/O的线程。当我没有遇到这个问题时,我也会看到dmcrypt_write以相对较高的 IO % 弹出到顶部,但它不会在那里停留很长时间。
如果我dd if=/dev/urandom of=$HOME/bigfile bs=10k count=200k; sync在一切正常运行时运行,dmcrypt_write会跳到顶部一两秒钟,但它的持续时间与我的一个构建过程中的持续时间相差甚远。
完整构建会生成大约 1.4 GB 的数据。这是一个包含多个模块的 Java 项目。因此,创建了许多小文件以及聚合所有这些小文件的一些较大的 JAR 文件。
总是有足够的内存可用,并且没有使用交换分区。
我有使用类似计算机 (T460p) 的同事也运行 Ubuntu,但没有遇到此问题。不过,它们似乎都有不同的SSD 品牌/型号。
这个问题再次浮出水面,所以我根据对这个问题的回复做了更多的测试。
discard选项,所以我fstrim假设这有点类似于discard启用了该选项fstrim,构建速度似乎恢复了正常......但是在构建完成后,dmcrypt_write线程启动并使系统无法使用一段时间。构建和使系统可用的所有总时间似乎与以前大致相同。/proc/sys/vm/dirty_ratio2 和/proc/sys/vm/dirty_background_ratio1 并运行了一些构建。构建花费的时间比正常情况长——与我上次遇到此问题时大致相同,但系统似乎没有锁定那么多。将其改回 20 和 10 恢复到上述行为。/proc/sys/vm/dirty_ratio为 2 和/proc/sys/vm/dirty_background_ratio1,时间与 20 和 10 相当。我在 Debian 10+11 上遇到了类似的问题,如果我在 LUKS 磁盘上进行大量写入操作,我的整个系统会冻结一段时间,然后再次响应,然后再次冻结......
不过我不必重新启动 - 只需等到写入操作完成即可。
正如 ScumCoder 所写,有一个可用的修复程序。从内核 5.9 开始,该修复已集成到内核中。
以下命令为我解决了这个问题:
cryptsetup --allow-discards --perf-no_read_workqueue --perf-no_write_workqueue --persistent refresh nvme0n1p3_crypt
Run Code Online (Sandbox Code Playgroud)
我使用命令提取了我的磁盘名称“nvme0n1p3_crypt”dmsetup table
我从https://wiki.archlinux.org/title/Dm-crypt/Specialties#Disable_workqueue_for_increased_solid_state_drive_(SSD)_performance获得灵感
修复后我的写作速度快了很多。
我和你有完全相同的问题,快速研究显示了这篇文章:
https://blog.cloudflare.com/speeding-up-linux-disk-加密
CloudFlare 员工对 Linux 源代码进行了大量挖掘,得出的结论是罪魁祸首是当前的dmcrypt实现。他基本上是通过重写内核的相应部分来解决这个问题的。
因此,据我所知,摆脱速度缓慢的唯一两种方法是(1)编译他的内核版本,或(2)偶尔重新启动一次(正如您所说)。我选择了后者。
小智 1
不具体了解 LUKS,但对于 SSD 上的一般 IO 问题,请确保您的 fs 挂载启用了丢弃,即 grep Discard /proc/mounts 也可能会尝试(以 root 身份)“echo 1 >> /proc/sys/ vm/dirty_background_ratio; echo 2 >> /proc/sys/vm/dirty_ratio",这将使系统在需要写出的数据较少时更快地启动 IO。