提高性能/启动过程

出自 ArchWiki

改进系统的启动性能可以减少启动等待时间,并有助于更深入地了解某些系统文件和脚本如何相互作用。本文试图汇总关于如何提高 Arch Linux 系统启动性能的方法。

分析启动过程

使用 systemd-analyze

systemd 提供了一个名为 systemd-analyze 的工具,可以用来显示关于启动过程的详细计时信息,包括一个 svg 图,显示等待依赖项的单元。你可以看到哪些单元文件导致你的启动过程变慢。然后你可以相应地优化你的系统。

要查看启动时在内核空间和用户空间花费了多少时间,只需使用

$ systemd-analyze
提示: 如果你通过 UEFI 启动,并使用实现了 systemd 启动引导器接口 的启动引导器(目前 systemd-bootGRUB 实现了),systemd-analyze 还可以额外显示在 EFI 固件和启动引导器本身中花费了多少时间。

要列出已启动的单元文件,按每个单元文件启动所花费的时间排序

$ systemd-analyze blame

在启动过程的某些点,在给定的单元成功之前,事情无法继续进行。要查看哪些单元位于启动链中的这些关键点,请执行

$ systemd-analyze critical-chain

你还可以创建一个 SVG 文件,以图形方式描述你的启动过程,类似于 Bootchart

$ systemd-analyze plot > plot.svg

有关详细信息,请参阅 systemd-analyze(1)

使用 bootchart2

你也可以使用 Bootchart2 来可视化启动序列。

在早期 init 阶段使用 systemd 代替 busybox

默认情况下,Mkinitcpio 配置使用 baseudev 钩子来构建 initramfs。通过用 systemd 替换它们,可以实现更快的启动时间。

有关更多详细信息,请参阅 Mkinitcpio#常用钩子。如果替换 fsck 钩子,另请参阅 Fsck#启动时检查

编译自定义内核

编译自定义内核可以减少启动时间和内存使用。虽然随着 64 位架构的标准化和 Linux 内核的模块化特性,这些好处可能不如预期的那么大。有关更多信息,请参阅 Kernel#编译

Initramfs

#编译自定义内核 类似,可以精简 initramfs。一个简单的方法是包含 mkinitcpio autodetect 钩子。如果你想更进一步,请参阅 Minimal initramfs

根据你的硬件(处理器和存储速度),使用 lz4 而不是默认的 zstd 压缩选项可能会更快,因为启动时更快的解压缩速度通常会抵消必须从磁盘读取的 initramfs 稍大的尺寸。请参阅 Mkinitcpio#压缩

为服务选择合适的启动方式

systemd 的一个核心功能是 D-Bus 和套接字激活。在大多数情况下,应该优先选择此功能,因为它使服务仅在首次访问时才启动,并且通常是一件好事(例如,对于桌面使用,通常不需要在启动时启用 cups.service,而是启用 cups.socket,它只会在实际打印时启动服务)。

但是,如果你知道某个服务(如 upower)总是在启动期间启动,那么尽早启动它可以缩短整体启动时间。这可以通过 启用 upower.service 来实现(如果服务文件为此设置,在大多数情况下都是这样)。

这将导致 systemd 尽快启动 UPower,而不会与套接字或 D-Bus 激活发生冲突。

错峰启动

某些硬件实现了 错峰启动,这会导致操作系统串行探测 ATA 接口,从而可以逐个启动驱动器并降低峰值功耗。这会减慢启动速度,并且在大多数消费级硬件上,由于驱动器在电源打开时已经立即启动,因此根本没有任何好处。要检查是否正在使用 SSS

# dmesg | grep SSS

如果在启动期间未使用它,则不会有任何输出。

要禁用它,请添加 libahci.ignore_sss=1 内核参数

文件系统挂载

感谢 mkinitcpiofsck 钩子,你可以通过在内核行上将 ro 更改为 rw 来避免可能代价高昂的根分区重新挂载:可以使用 rootflags=rw,other_mount_options 设置选项。必须从 /etc/fstab 文件中删除该条目,否则 systemd-remount-fs.service 将继续尝试应用这些设置。或者,可以尝试屏蔽该单元。

如果 Btrfs 用于根文件系统,则像其他文件系统一样,无需在每次启动时都进行 fsck。如果属于这种情况,可以删除 mkinitcpiofsck 钩子。你可能还想屏蔽 systemd-fsck-root.service,或者使用 fsck.mode=skip 从内核命令行告诉它不要 fsck 根文件系统。如果没有 mkinitcpiofsck 钩子,systemd 仍然会使用 systemd-fsck@.service fsck 任何相关的文件系统

你还可以从 /etc/fstab 中删除 API 文件系统,因为 systemd 将自行挂载它们(有关列表,请参阅 pacman -Ql systemd | grep '\.mount$')。用户通常会从 sysvinit 沿用 /tmp 条目,但你可能已经从上面的命令中注意到 systemd 已经处理了这个问题。因此,可以安全地删除它。

其他文件系统,如 /homeEFI 系统分区,可以使用自定义挂载单元进行挂载。在挂载选项中添加 noauto,x-systemd.automount 将缓冲对该分区的所有访问,并在首次访问时对其进行 fsck 和挂载,从而减少启动过程中必须 fsck/挂载的文件系统数量。

注意
  • 这将使你的 /home 文件系统类型变为 autofs,默认情况下 locate 会忽略它。自动挂载 /home 的加速可能不超过一两秒,具体取决于你的系统,因此这个技巧可能不值得。
  • 如果系统安装到 btrfs 子卷中(特别是:根目录 / 本身是一个子卷),并且 /home 是一个单独的文件系统,你可能还想阻止创建 /home 子卷。屏蔽 home.conf tmpfile:ln -s /dev/null /etc/tmpfiles.d/home.conf

减少启动时的输出

对于某些系统,特别是那些使用 SSD 的系统,TTY 的缓慢性能实际上是一个瓶颈,因此更少的输出意味着更快的启动。有关建议,请参阅 静默启动 文章。

更换启动引导器

更换你的 启动引导器(例如,更简单的启动引导器,如 systemd-boot)可能会将启动时间缩短几秒钟。

如果你的设置允许,尝试仅使用 EFI 启动存根 以获得更短的启动时间。

挂起到内存

减少启动时间的最佳方法是不启动。考虑将你的系统挂起到内存