zram - Arch Linux 中文维基

跳至內容

# zram

出自 Arch Linux 中文维基

翻譯狀態：

- 本文（或部分內容）譯自 Zram，最近一次同步於 2025-04-10，若英文版本有所更改，則您可以幫助同步與翻譯更改的內容。
- 您可以在 ArchWiki 的對應頁面找到本文翻譯的原始修訂歷史。
- 本文可能與英文原文存在出入。

相關文章

- Swap
- zswap

zram（原名 compcache）是 Linux 內核模塊，在內存中創建壓縮塊設備，實現實時壓縮的 ramdisk。其主要用途為：

- 作 swap（最常見）
- 作 /tmp 等臨時文件存儲

早期僅用於壓縮 swap，故名 compcache。

## 作為 swap 的使用

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

即使保守估計 zstd 只能達到 1:2 壓縮比（實際中壓縮比通常為 1:3），zram 也能提供在內存中存儲比不進行內存壓縮更多內容的優勢。

注意：

- 在配置 zram 時設置的 zram 大小指代可存儲的最大未壓縮數據量，不是指壓縮後的數據大小。只要內存中的壓縮後數據量小於系統物理內存容量，你甚至可以將 zram 大小配置為等於或大於系統物理內存容量。
- 假如相關的 zswap 內核功能為啟用狀態，它將阻礙 zram 的有效使用。這是因為 zswap 會在 zram 之前被用作 swap 緩存，並在換出的內存分頁到達 zram 前對其進行攔截和壓縮。在這種情況下，儘管 zramctl(8) 的輸出可能並非如此，實際上大部分 zram 並未被使用。因此，建議在開始前通過內核參數或者 sysfs 設置永久禁用 zswap。
- 不支持在休眠時將內存換出至 zram，即便 zram 被配置在位於永久性存儲的設備上。logind 會阻止休眠到配置在 zram 上的交換空間的嘗試。

提示：你可以通過 `mem_limit` 參數指定 ZRAM 可存儲的最大壓縮後數據量。

一開始可以先嘗試配置大小為物理內存的一半。

### 臨時應用

參考如下配置一個採用 zstd 壓縮、容量為系統內存大小一半，優先度較高且非持久的 zram 設備 (重啟後失效)：

    # modprobe zram
    # zramctl /dev/zram0 --algorithm zstd --size "$(($(grep -Po 'MemTotal:\s*\K\d+' /proc/meminfo)/2))KiB"
    # mkswap -U clear /dev/zram0
    # swapon --discard --priority 100 /dev/zram0

如需禁用，可以重啟或執行以下命令：

    # swapoff /dev/zram0
    # modprobe -r zram

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

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

### 使用 udev 規則

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

顯式地在啟動時加載模組：

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

    zram

創建如下的 udev 規則（請按需調整 `disksize` 屬性）：

    /etc/udev/rules.d/99-zram.rules

    ACTION=="add", KERNEL=="zram0", ATTR{initstate}=="0", ATTR{comp_algorithm}="zstd", ATTR{disksize}="4G", RUN="/usr/bin/mkswap -U clear %N", TAG+="systemd"

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

    /etc/fstab

    /dev/zram0 none swap defaults,discard,pri=100 0 0

### 使用 zram-generator

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

如要使用，只需安裝 zram-generator包，並創建包含如下內容的 `/etc/systemd/zram-generator.conf` 配置文件：

    /etc/systemd/zram-generator.conf

    [zram0]
    zram-size = min(ram / 2, 4096)
    compression-algorithm = zstd

`zram-size` 是 zram 設備的大小，單位為 `MiB`，你可以使用 `ram` 指代總內存容量。

`compression-algorithm` 指定了 zram 設備使用的壓縮算法。執行 `cat /sys/block/zram0/comp_algorithm` 將顯示所有可用的壓縮算法（包括當前選用的算法）。

詳細信息請參考 zram-generator.conf(5)。

然後執行 daemon-reload，並啟動你配置的 `systemd-zram-setup@zramN.service` 示例（`N` 需要與實例編號匹配，該示例中為 `systemd-zram-setup@zram0.service`） 。

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

### 使用 zramswap

zramswapAUR 提供一個自動化腳本，可配置一個優先度較高、默認為 20% 系統內存容量的 swap。如需讓其自動在啟動時執行，請啟用 `zramswap.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 的 pull request 同時連結到了r/Fedora 上一些用戶所進行的測試，結果顯示 `vm.page-cluster = 0` 是較為合適的值。此外，他們也發現建議使用較高的 swappniess，這與內核文檔中的建議相符。

默認情況下該值為 60。

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

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

### 為 zram 塊設備啟用後備設備

可以配置 zram 將未壓縮內存頁放入指定的塊設備中。

如要手動添加後備設備：

    # echo /dev/sdX > /sys/block/zram0/backing_dev

如要通過 zram-generator 為 zram 塊設備添加後備設備，可在 `/etc/systemd/zram-generator.conf` 中對應的 `[zramX]` 設備下添加如下內容：

    /etc/systemd/zram-generator.conf

    writeback-device=/dev/disk/by-partuuid/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX

然後可以通過執行以下命令將未壓縮的頁面推送到塊設備：

    # echo huge > /sys/block/zramX/writeback

### 將 zram 用於非 swap 用途

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

- 無分區表支持（不會自動創建 `/dev/zramxpy`）。
- 塊大小固定為 4 kiB。

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

    # zramctl -f -s NG

    /dev/zramx

將磁碟鏡像複製到新創建的 `/dev/zramx`，然後創建迴環設備。如果磁碟鏡像有分區表，迴環設備的塊大小必須與分區表使用的塊大小匹配，通常為 512 或 4096 字節。

    # 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*` 的輸出結果取決於磁碟鏡像中的內容。

## 另請參閱

- Wikipedia:zram
- https://github.com/pop-os/default-settings/pull/163
- https://www.reddit.com/r/pop_os/comments/znh9n6/help_test_a_zram_optimization_for_pop_os/

分類：​

- 內核

zram
新增話題