zram

出自 Arch Linux 中文维基

zram,舊稱為 compcache,是一個用於在內存中創建壓縮的塊設備的 Linux 內核模塊,即帶實時磁盤壓縮的內存盤。通過 zram 創建的塊設備可以用作 swap 或是內存盤。zram 有兩個常見的應用場景,一個是儲存臨時文件(/tmp),另一個是用作 swap。早期 zram 只有前一個功能,也是它原名 「compcache」 (compressed cache) 的由來。

作為 swap 的使用[編輯 | 編輯原始碼]

在最開始,創建出的 zram 塊設備並不會預留或使用任何內存。僅當有文件需要被或者想要被交換出內存時,它們才會被壓縮並移入 zram 塊設備。因此,zram 塊設備將會根據需要動態地增長或收縮。

例如,考慮一個具備 32 GiB 內存的系統,其上配置了容量為 64 GiB 的 zram。假設 zstd 能夠實現 1:4 的壓縮比率,當被全部占用時,該 zram 塊被壓縮後在物理內存中占用的大小將在 16 GiB 左右。因此:

  • 當內存和 zram 均完全被占用時:16 GiB 內存 + 64 GiB zram (在內存中約占用 16 GiB)
  • 正常使用且未發生交換時:32 GiB 內存 + 0 GiB zram
  • 正常使用且發生少數交換時:30 GiB 內存 + 8 GiB zram (在內存中約占用 2 GiB)
  • 不進行任何 zram 配置:32 GiB 內存

可見,zram 總是提供能在內存中存儲更多內容的優勢。

注意:
  • 假如相關的 zswap 內核功能為啟用狀態,它將阻礙 zram 的有效使用。這是因為 zswap 會在 zram 之前被用作 swap 緩存,並在換出的內存分頁到達 zram 前對其進行攔截和壓縮。在這種情況下,大多數的 zram 其實並未被使用,儘管 zramctl(8) 的輸出可能並非如此。
  • 如上所述,在配置 zram 時,zram 設備的大小控制着其能存儲的最大未壓縮數據量,而非最大壓縮後數據量。您可將 zram 的大小配置為與您系統的物理內存容量相等,甚至更大,只需保證數據壓縮後所占用的大小不超過系統物理內存的容量即可。
  • 不支持在休眠時將內存換出至 zram,即便 zram 被配置在位於永久性存儲的設備上。logind 會阻止休眠到配置在 zram 上的交換空間的嘗試。

手動應用[編輯 | 編輯原始碼]

首先,通過 sysfs 禁用 zswap

# echo 0 > /sys/module/zswap/parameters/enabled

接着,配置一個採用 zstd 壓縮、32GiB 容量且優先度較高的 zram 設備 (僅對當前會話生效):

# modprobe zram
# zramctl /dev/zram0 --algorithm zstd --size 32G
# mkswap -U clear /dev/zram0
# swapon --priority 100 /dev/zram0

如需禁用,可以重啟或執行以下命令:

# swapoff /dev/zram0
# modprobe -r zram
# echo 1 > /sys/module/zswap/parameters/enabled

關於每一步操作、配置選項及潛在問題的詳細信息可以參考 zram 模組的官方文檔

若需一個持久化的解決方案,請在下屬章節所述的方法中任選其一。

使用 udev 規則[編輯 | 編輯原始碼]

以下的案例描述了如何通過單個 udev 規則自動在啟動時配置 zram 內 swap。該案例無需額外的軟件包。

在開始之前,通過內核參數或 sysctl knob 永久性 禁用 zswap

顯式地 在啟動時加載模組

/etc/modules-load.d/zram.conf
zram

創建如下的 udev 規則 (請按需調整 disksize 屬性):

/etc/udev/rules.d/99-zram.rules
ACTION=="add", KERNEL=="zram0", ATTR{comp_algorithm}="zstd", ATTR{disksize}="4G", RUN="/usr/bin/mkswap -U clear /dev/%k", TAG+="systemd"

/dev/zram 以一個高於默認值的優先度添加到您的 fstab

/etc/fstab
/dev/zram0 none swap defaults,pri=100 0 0
注意: 不能在 fstab 中使用 LABEL 或 UUID 對 zram 上的交換空間進行引用,因為 udev 不會為 zram 設備創建 /dev/disk/by-label/*/dev/disk/by-uuid/* 的符號鏈接。

使用 zram-generator[編輯 | 編輯原始碼]

zram-generator 提供一個 systemd-zram-setup@.service 單元,可自動初始化 zram 設備而無需用戶啟動/啟用相關模板或實例。詳見 zram-generator(8)zram-generator.conf(5)

在開始之前,通過內核參數或 sysctl knob 永久性 禁用 zswap[1]

接下來,要創建一個使用 zstd 壓縮、大小為所有可用內存容量一半的 zram swap 設備,只需安裝 zram-generator,然後創建包含如下內容的 /etc/systemd/zram-generator.conf 配置文件:

/etc/systemd/zram-generator.conf
[zram0]
zram-size = ram / 2
compression-algorithm = zstd
swap-priority = 100
fs-type = swap

執行 daemon-reload,然後啟動您所配置的 systemd-zram-setup@zramN.service 等實例。

您可使用 zramctl(8) 命令,或是通過查閱 systemd-zram-setup@zramN.service 實例的單元狀態,來檢查您所配置的 /dev/zramN 設備的 swap 狀態

使用 zramswap[編輯 | 編輯原始碼]

zramswapAUR 提供一個自動化腳本,可配置一個優先度較高、默認為 20% 系統內存容量的 swap。如需讓其自動在啟動時執行,請啟用 zramswap.service

使用 zramd[編輯 | 編輯原始碼]

zramdAUR 默認使用 zstd 壓縮自動配置 zram,可通過位於 /etc/default/zramd 的文件修改其配置。通過啟用 zramd.service 可讓其在啟動時自動運行。

提示與技巧[編輯 | 編輯原始碼]

查看 zram 狀態[編輯 | 編輯原始碼]

使用 zramctl(8)。示例:

$ zramctl
NAME       ALGORITHM DISKSIZE  DATA  COMPR  TOTAL STREAMS MOUNTPOINT
/dev/zram0 zstd           32G  1.9G 318.6M 424.9M      16 [SWAP]
  • DISKSIZE = 32G: 該 zram 設備最多會存儲 32 GiB 的未壓縮數據
  • DATA = 1.9G: 目前, 該 zram 設備上存儲着 1.9 GiB (未被壓縮的) 數據
  • COMPR = 318.6M: 這 1.9 GiB 未被壓縮的數據被壓縮到了 318.6 MiB
  • TOTAL = 424.9M: 包含元信息在內,這 1.9 GiB 未壓縮的數據使用了 424.9 MiB 的物理內存

多個 zram 設備[編輯 | 編輯原始碼]

初始情況下,加載 zram 模塊會創建一個 /dev/zram0 設備。

如果您需要更多的 /dev/zram 設備,使用 num_devices 內核模塊參數指定設備的量,或在之後按需添加它們

優化 zram 上的 swap[編輯 | 編輯原始碼]

介於 zram 與磁盤 swap 的行為不同,可以配置系統的 swap 以充分利用 zram 的優勢:

/etc/sysctl.d/99-vm-zram-parameters.conf
vm.swappiness = 180
vm.watermark_boost_factor = 0
vm.watermark_scale_factor = 125
vm.page-cluster = 0

該配置的解釋:

這些值與Pop!_OS 中使用的值相同。這條 GitHub 上 Pop!_OS 的 PR 同時鏈接到了r/Fedora 上一些用戶所進行的測試,結果顯示 vm.page-cluster = 0 是較為合適的值。此外,他們也發現建議使用較高的 swappniess,這與內核文檔中的建議相符。

"默認情況下該值為 60。對於像 zram 或 zswap 這樣在內存中的 swap,以及一些混合式的、在相較文件系統來說更為快速的設備上 swap 的配置,應當考慮 100 以上的值。例如,若 swap 設備上的隨機讀寫平均快於文件系統上隨機讀寫的 2 倍,則 swappiness 值應為 133 (x + 2x = 200, 2x = 133.33)。"

在配備硬盤驅動器的系統上,在 zswap 設備上的隨機讀寫會比在文件系統上的讀寫快若干數量級,因此 swappiness 應為 200 左右。甚至是在配備高速固態硬盤的系統上,較高的 swappiness 值也是理想的。

將 zram 用於非 swap 用途[編輯 | 編輯原始碼]

Zram 也可以被用作普通的內存塊設備,像是占用較少物理內存,但性能略微下降的 /dev/ram 設備。然而,有幾個問題需要注意:

  • 無分區表支持(不會自動創建 /dev/zramxpy)。
  • 塊大小固定為 4 kiB。

顯然,可以通過在 zram 上疊加迴環設備來繞過這一問題。使用 losetup,可以使用 -b 參數指定塊大小,使用 -P 參數處理分區表並自動創建分區迴環設備。

# zramctl -f -s NG
/dev/zramx

將磁盤鏡像複製到新創建的 /dev/zram

本文或本章節的事實準確性存在爭議。

原因: 為什麼塊大小要設為 512?(在 Talk:Zram 中討論)


# losetup -f -b 512 -P /dev/zramx
# ls /dev/loop*
/dev/loop0 /dev/loop0p1 /dev/loop0p2
# mount /dev/loop0p1 /mnt/boot
# mount /dev/loop0p2 /mnt/root
注意:
  • zram 設備編號取決於已有的 zram 設備,其大小應足以存放磁盤鏡像。
  • ls /dev/loop* 的輸出結果取決於磁盤鏡像中的內容。

另請參閱[編輯 | 編輯原始碼]