跳至內容
出自 Arch Linux 中文维基

提升系統的啟動性能可以縮短啟動等待時長,還能學習系統文件和腳本見交互的方式。本文整合了數種提升 Arch Linux 啟動性能的方式。

啟動過程分析

使用 systemd-analyze

systemd 提供了一個名為 systemd-analyze 的工具,可用於顯示有關啟動過程的計時細節, 包括一個顯示各單元等待其依賴項的 svg 圖。您可以看到哪些單元文件導致啟動過程減慢, 然後可以相應地優化系統.

要查看啟動時在內核/用戶空間中消耗的時間, 只需使用:

$ systemd-analyze
提示:如果系統使用 UEFI 引導,且啟動引導器實現了 systemd 的啟動引導器接口(目前只有 GRUBsystemd-boot 實現了),systemd-analyze 還可以顯示 EFI 固件和啟動引導器自身花費的時間。

按照耗費時間順序,列出啟動各個單元耗費的時間:

$ systemd-analyze blame

在啟動過程的一些時刻,需要特定的單元成功啟動了才能繼續。要查看在啟動鏈中哪些單元處於這些關鍵點,可以執行:

$ systemd-analyze critical-chain

類似於 Bootchart,還可以生成 SVG 形式的啟動流程圖:

$ systemd-analyze plot > plot.svg

更多信息請參考 systemd-analyze(1)

使用 bootchart2

你還可以使用 Bootchart2 將啟動流程可視化。

編譯自定義內核

使用自定義內核可以減少啟動時間和內存占用,但由於 Linux 內核的模塊化特性以及 64 位架構的逐漸標準化,這些好處可能沒有預期的那麼大。具體信息請參考內核#編譯

官方內核的模塊默認壓縮等級為 ZSTD_CLEVEL=19,但 SSD 可能更適合使用 ZSTD_CLEVEL=1

建議將會用到的存儲和文件系統模塊嵌入到內核中,以使用 Arch 的啟動流程#Running_without_initramfs

Initramfs

最佳做法是 Arch 的啟動流程#Running_without_initramfs

mkinitcpio 默認使用 baseudev 鉤子,將它們替換為 systemd可以提升啟動速度,具體細節請參考 Mkinitcpio#常用鉤子。如果要替換 fsck 鉤子,請參考 Fsck#啟動時檢查

#編譯自定義內核類似,initramfs 也可以被精簡。最簡單的方法是包含 mkinitcpioautodetect 鉤子。Booster 可以生成比 mkinitcpiodracut 更小的 initramfs,並使用更快的單二進制文件 init. 參閱 極簡 initramfsBooster#Removing modules 以獲得更多信息。

取決於你的硬體(處理器和存儲速度)不同,由於啟動時更快的解壓速度通常可以抵消掉從硬碟讀取稍大的 initramfs 的負面影響,使用 lz4 取代默認的 zstd 壓縮算法有可能會更快,具體細節請參考 Mkinitcpio#壓縮方式(COMPRESSION)

選擇合適的服務啟動方式

systemd 的一個核心功能是 D-Bus 和 socket 激活。多數情況下建議使用該功能,它會使服務只在初次訪問時啟動,通常來說這是件好事(例如 cups.service 在桌面環境通常沒必要開機啟動,而啟用 cups.socket 會使只在列印時啟動服務)。

但如果有個服務(以 upower 為例)始終會在開機時啟動,那儘早將其啟動有可能會減少啟動耗時,該操作可通過啟用 upower.service 達成(前提是已配置了啟動文件,多數情況下都是如此)。

這樣 systemd 就會儘早啟動 UPower,而不會引起 socket 或 D-Bus 激活的競爭。

分批啟動

有些硬體使用了分批啟動(Staggered spin-up,SSP),會使系統按順序探測 ATA 接口,從而使硬碟逐個輪流啟動,以降低耗電峰值。這會降低啟動速度,且由於多數消費級硬體在通電後就會立即啟動,因此並沒有提供什麼優勢。執行以下命令可以檢查是否啟用了分批啟動:

# dmesg | grep SSS

無輸出表示沒有使用該功能。

可以將 libahci.ignore_sss=1 添加到內核參數以禁用該功能。

掛載文件系統

藉助 mkinitcpiofsck 鉤子,你可以通過在內核命令行中將 ro 改為 rw 來避免對 root 分區進行影響性能的重掛載:一個選擇是使用 rootflags=rw,other_mount_options 來設置相關選項。必須從 /etc/fstab 中移除對應的條目,否則 systemd-remount-fs.service 仍會嘗試應用這些設置。或者,也可以嘗試屏蔽(mask)此服務單元。

如果根文件系統是 Btrfs,就不需要和其他文件系統一樣每次啟動都進行 fsck。在這種情況下,可以移除 mkinitcpio 的 fsck 鉤子。你也可以選擇屏蔽(Mask) systemd-fsck-root.service,或者使用內核命令行fsck.mode=skip來告訴根文件系統跳過 fsck。沒有 mkinitcpio 的 fsck 鉤子,systemd 仍會使用 systemd-fsck@.service 對任何相關的文件系統進行 fsck。

你也可以移除/etc/fstab中的 API 文件系統,因為 systemd 會自動掛載它們(列表見 pacman -Ql systemd | grep '\.mount$')。用戶可能看到從 sysvinit 遷移過來的 /tmp 條目,但你可能已經注意到,從上面的命令可以看出,systemd 已經處理了這個問題。因此,/tmp 條目可以安全地移除。

其他文件系統,比如 /home 或者 EFI 系統分區,可以使用自定義的掛載單元進行掛載。向掛載參數中添加 noauto,x-systemd.automount 會延遲掛載分區,直到首次訪問時才進行 fsck 和掛載,從而減少啟動過程中需要 fsck 或掛載的文件系統數量,幫助加快啟動速度。

注意:
  • 這將使你的 /home 文件系統類型變成 autofs,默認情況下,locate 會忽略它。自動掛載 /home 的加速效果可能不會超過一兩秒,具體取決於你的系統,因此這個技巧可能並不值得嘗試。
  • 如果系統安裝在一個 btrfs 子卷中(具體來說:根目錄 / 本身是一個子卷),並且 /home 是一個獨立的文件系統,你可能還需要防止創建一個 /home 子卷。可以通過屏蔽 home.conf 臨時文件來實現:ln -s /dev/null /etc/tmpfiles.d/home.conf

精簡啟動階段輸出信息

對於某些用戶,特別是 SSD 用戶,TTY 的龜速實際上成為了性能瓶頸,精簡輸出信息實際上有利於提高性能。具體建議請參考靜默啟動

替換啟動引導器

替換引導加載程序(例如換成 systemd-boot 這種簡單的引導器)可能會減少數秒的啟動時間。

在可用的情況下,只使用一個 EFI boot stub 可以進一步降低啟動耗時。

內核參數

有些內核參數可以提升啟動性能。

如果不需要 systemd-gpt-auto-generator,使用 systemd.gpt_auto=no 可能會減少 0.2~3 秒的啟動時長。如果根分區是 Btrfs 且沒有使用 initramfs 進行啟動,那 systemd-gpt-auto-generator 不會起效[1]

cryptomgr.notests 會禁用自測試,但效果可能不大。

掛起到內存

減少啟動時長的最好方法是完全不用啟動,可以考慮轉而將系統掛起到內存