zswap 是一個內核功能,它為交換頁提供了一個壓縮的內存緩存。原本會交換到磁碟的頁被壓縮並存儲到內存中的存儲池中。一旦池已滿或內存耗盡,最近最少使用的(LRU)頁就會被解壓縮並寫入磁碟,就好像它沒有被攔截一樣。將頁解壓縮到交換緩存後,可以釋放池中的壓縮版本。
與 zram 相比的區別在於,zswap 與 swap 設備協同工作,而 zram 是內存中的交換設備,不需要後備交換設備。
開關 zswap
在穩定版(stable)的 linux包 官方內核中,zswap 會被默認啟用。這可以通過穩定版內核配置中的 CONFIG_ZSWAP_DEFAULT_ON
標誌進行驗證。
要在運行時禁用 zswap,請執行下面的命令:
# echo 0 > /sys/module/zswap/parameters/enabled
要永久禁用 zswap,添加 zswap.enabled=0
到你的內核參數。
定製 zswap
當前參數
zswap 有幾個可自定義的參數。可以使用以下方式顯示實時設置:
$ grep -R . /sys/module/zswap/parameters
/sys/module/zswap/parameters/same_filled_pages_enabled:Y /sys/module/zswap/parameters/enabled:Y /sys/module/zswap/parameters/max_pool_percent:20 /sys/module/zswap/parameters/compressor:lz4 /sys/module/zswap/parameters/zpool:z3fold /sys/module/zswap/parameters/accept_threshold_percent:90
見 zswap 文檔獲取不同參數的描述。
顯示初始配置的引導時加載消息可以通過以下方式檢索:
# dmesg | grep zswap:
[ 0.317569] zswap: loaded using pool lz4/z3fold
設定參數
使用 sysfs
每個設置都可以在運行時通過 sysfs 接口進行更改。作為示例,要更改 compressor
參數:
# echo lz4 > /sys/module/zswap/parameters/compressor
使用內核引導參數
要持久化參數更改,必須在內核引導參數中添加相應的選項,例如 zswap.compressor=lz4
。因此,要永久設定上述所有設置,必須添加以下內核參數:
zswap.enabled=1 zswap.compressor=lz4 zswap.max_pool_percent=20 zswap.zpool=z3fold
當通過引導參數更改壓縮算法時,需要確保在引導期間儘早加載相應的壓縮模塊(參考 #壓縮算法)。
最大池大小
存儲池不是預先分配的,它可以增長到可用內存總量的一定百分比,默認情況下最多占內存總量的20%。一旦達到此閾值,就會將頁從池中逐出到交換設備中。壓縮池的最大大小由參數 max_pool_percent
控制。
壓縮存儲池分配器
zpool 參數控制壓縮存儲池的管理。
在 6.3 版本後的內核中,添加了 zsmalloc 分配器。它在低內存條件下表現良好,並且可以節省更多內存。
對於較舊的內核,可以使用 zbud 數據分配器,它將恰好兩個壓縮頁面存儲到一個中,這將壓縮比限制為 2 或更低。
同樣, z3fold 分配器允許每頁最多 3 個壓縮對象(與 zbud 的 1.7 相比,典型的壓縮比平均約為 2.7)。該分配器以前被建議優於 zsmalloc,因為它具有更好的性能,但由於這一點不再成立且存在眾多錯誤,自 6.13 起已被棄用並默認禁用(在 6.6.55 中回移植到 6.6 LTS),並計劃移除。
默認情況下會創建一個類型為 zsmalloc 的 zpool。使用內核參數 zswap.zpool
可以在啟動時選擇其他分配器。數據分配器也可以在後期通過 sysfs 接口進行更改。
壓縮算法
對於頁的壓縮,zswap 使用內核加密 API 提供的壓縮器模塊。默認情況下會使用 lz4 壓縮算法,但也可以在啟動時使用 zswap.compressor
更改壓縮算法。其他選項包括 deflate, lz4hc, lzo, lzo-rle, 842 和 zstd。
使用 sysfs 在運行時更改壓縮不會有問題,但在本例中,zswap 從 lz4 開始,並在稍後階段切換到定義的算法。要立即使用另一種算法啟動 zswap,必須通過內核引導參數進行設定,並且內核必須儘早加載相應的模塊。這可以通過以下步驟來實現:
- 將與所選壓縮器相關的模塊添加到 mkinitcpio#模塊(MODULES)數組中。
- 修改 mkinitcpio 配置後重新生成 ramdisk 環境:見 mkinitcpio#創建和啟用鏡像。
- 在內核參數中將
zswap.compressor
設定為你選擇的算法。
在下次啟動時,見 #當前參數來檢查 zswap 現在是否使用了請求的壓縮器。