zram
zram (以前は compcache と呼ばれていました) は、RAM 内に圧縮ブロックデバイスを作成するための Linux カーネルモジュールです。つまり、オンザフライのディスク圧縮を用いる RAM ディスクです。zram で作成されたブロックデバイスは、スワップとして使ったり、汎用 RAM ディスクとして使ったりすることができます。zram の最も一般的な2つの使用法は、一時ファイル (/tmp
) のストレージとスワップデバイスです。初期の zram には前者の機能しか存在しておらず、ゆえに元の名前は "compcache" ("compressed cache") でした。
目次
スワップとしての使用
最初の段階では、作成された zram ブロックデバイスは RAM を予約したり使用したりしません。ファイルをスワップアウトする必要が生じた場合にのみ、そのファイルは圧縮され、zram ブロックデバイスへ移動されます。zram ブロックデバイスは必要に応じて動的に拡大/縮小します。
例として、32 GiB RAM を搭載し、64 GiB の容量を持つ zram が設定されているシステムを考えてみましょう。zstd の圧縮比は 1:4 であると仮定し、zram が満タンになったときの物理 RAM 上の圧縮された zram ブロックサイズは約 16 GiB になるとします。このとき:
- RAM と zram が完全に満タン: 16 GiB RAM + 64 GiB zram (RAM 内では約 16 GiB)
- スワップの発生しない通常の使用時: 32 GiB RAM + 0 GiB zram
- 軽いスワップの発生している通常の使用時: 30 GiB RAM + 8 GiB zram (RAM 内では約 2 GiB)
- zram 無し: 32 GiB RAM
このように、RAM 内により多くの内容を保存できるという利点を常に提供します。
手動で
まず、sysfs から zswap を無効化してください:
# echo 0 > /sys/module/zswap/parameters/enabled
そして、32GiB の容量を持ち、通常より高い優先度の、zstd で圧縮された 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 モジュールの公式ドキュメント で見られます。
zram を永続的に設定するには、以下のいずれかのセクションの方法を取ってください。
udev ルールを使う
以下の例は、1つの udev ルールを使って起動時に自動的に zram 上にスワップをセットアップする方法を示しています。これを行うために、追加のパッケージは必要ないはずです。
始める前に、カーネルパラメータか 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
zram-generator を使う
zram-generator は、zram デバイスを自動的に初期化する systemd-zram-setup@.service
ユニットを提供します。ユーザがテンプレートやインスタンスを起動/有効化する必要はありません。zram-generator(8) と zram-generator.conf(5) を参照してください。
始める前に、カーネルパラメータか sysctl knob を使って永続的に zswap を無効化してください。[1]
zstd
と利用可能な ram 全体を使用する zram スワップデバイスを作成するには、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
インスタンスを起動してください。
systemd-zram-setup@zramN.service
インスタンスのユニットステータスを見るか zramctl(8) を使用して、設定した /dev/zramN
デバイスのスワップ状態を確認することができます。
zramswap を使う
zramswapAUR は、システム RAM の 20% のサイズをデフォルトで持つ、高い優先度のスワップをセットアップするための自動化されたスクリプトを提供します。起動毎にこれを自動的に行うには、zramswap.service
を有効化してください。
zramd を使う
zramdAUR は、デフォルトで zstd 圧縮アルゴリズムを使う zram を自動的にセットアップします。設定は /etc/default/zramd
で変更できます。zramd.service
ユニットを有効化することで、ブート時に zramd を起動できます。
ヒントとテクニック
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: 現在、1.9 GiB (圧縮前) のデータがこの zram デバイスに格納されています。
- 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 上のスワップを最適化する
zram はディスクスワップとは異なる挙動をするため、システムのスワップを設定することで 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 が使用しているものです。Pop!_OS の GitHub プルリクエストには、r/Fedora のユーザによるテスト結果へのリンクもあります。このテストでは vm.page-cluster = 0
が理想的であると判断されました。また、swappiness を高い値にすることも良いこと分かりました。このことは、カーネルのドキュメントで提案されていることとも合致します:
"デフォルトの値は 60 です。zram や zswap といったメモリ内のスワップの場合や、ファイルシステムよりも高速なデバイス上にスワップが存在するハイブリッドなセットアップの場合では、100 以上の値を検討することができます。例えば、スワップデバイスに対するランダム IO がファイルシステムに対する IO よりも平均して 2 倍速いのならば、swappiness は 133 とするべきでしょう (x + 2x = 200, 2x = 133.33)。"
ハードドライブのあるシステムでは、zswap デバイスに対するランダム IO は、ファイルシステムに対する IO よりも桁違いに高速であるため、swappiness はだいたい 200 とすべきでしょう。高速な SSD のあるシステムでも、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
zram をスワップ以外の目的で使う
zram は RAM 上の汎用ブロックデバイスとして使うこともできます。単なる RAM ディスクと比べて物理メモリの使用量は少なくなりますが、パフォーマンスがわずかに低下します。ただし、いくつかの注意点があります:
- パーティションテーブルのサポートはありません (
/dev/zramxpy
ファイルは自動的に作成されません)。 - ブロックサイズは 4 kiB に固定されます。
これらの問題を回避する方法は、zram に対してループバックデバイスを使用することです。losetup を使い、-b
オプションでブロックサイズを指定し、-P
オプションでパーティションテーブルの再スキャンを行って zram のパーティションループバックデバイスを自動的に作成します。
# zramctl -f -s NG
/dev/zramx
ディスクイメージを新しい /dev/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