zram は Linux の仮想メモリーのスワップを圧縮 RAM ディスクとして提供する機能です。
スワップアウトが発生すると通常は HDD なり SDD に用意されているスワップファイルやスワップ領域へのディスク I/O が発生しますが、この I/O 先がメモリーとなるため処理速度が速くなるというわけです。また、スワップアウト対象のデータを圧縮してから書き出すため容量も節約できるという機能です。(その分、圧縮のために少し CPU 負荷が増加する)
さて、さっそく zram のインストールです。非常に簡単です。
apt install zram-config sudo reboot
PC の再起動が終わるともう zram によるスワップが有効になっています。swapon コマンドで結果を確認してみましょう。
$ swapon --show NAME TYPE SIZE USED PRIO /swapfile file 1.9G 0B -2 /dev/zram0 partition 995.4M 0B 5 /dev/zram1 partition 995.4M 0B 5 /dev/zram2 partition 995.4M 0B 5 /dev/zram3 partition 995.4M 0B 5 /dev/zram4 partition 995.4M 0B 5 /dev/zram5 partition 995.4M 0B 5 /dev/zram6 partition 995.4M 0B 5 /dev/zram7 partition 995.4M 0B 5
ワタシの環境では /swapfile がもともと用意してあったスワップです。zram0 〜 zram7 が zram-config によって追加されたスワップ領域です。
なぜ突然に 8 個も追加したの?と思われるかもしれませんが、これは zram-config の仕様です。
搭載している CPU の論理コア数と同じ個数を用意するようになっています。さらにスワップ領域のサイズも搭載している物理メモリー容量の半分になるように確保されます。物理メモリー容量が 16GB なので、半分の 8GB を 8 個で確保できるように、ということでおおよそ 1GB ずつの領域に設定されています。(ちょっと多いかな)
ちなみに zramctl というコマンドでもう少し詳細を確認できます。
$ zramctl NAME ALGORITHM DISKSIZE DATA COMPR TOTAL STREAMS MOUNTPOINT /dev/zram7 lzo-rle 995.4M 4K 74B 12K 8 [SWAP] /dev/zram6 lzo-rle 995.4M 4K 74B 12K 8 [SWAP] /dev/zram5 lzo-rle 995.4M 4K 74B 12K 8 [SWAP] /dev/zram4 lzo-rle 995.4M 4K 74B 12K 8 [SWAP] /dev/zram3 lzo-rle 995.4M 4K 74B 12K 8 [SWAP] /dev/zram2 lzo-rle 995.4M 4K 74B 12K 8 [SWAP] /dev/zram1 lzo-rle 995.4M 4K 74B 12K 8 [SWAP] /dev/zram0 lzo-rle 995.4M 4K 74B 12K 8 [SWAP]
初期状態では圧縮アルゴリズムに LZO-RLE が設定されていて、これを変更することが可能です。
cat コマンドで選択可能な圧縮アルゴリズムと現在適用されている圧縮アルゴリズムを確認できます。Zstandard なども選択できるみたいです。
(これは初期値を変更したあとの結果です)
$ cat /sys/block/zram0/comp_algorithm lzo lzo-rle [lz4] lz4hc 842 zstd
今まで 2GB のスワップファイルを 1 本で運用してきた身には 1GB が 8 本というのは多すぎなので、もう少し減らしたいと思い、設定方法を探りました。ヒントはインストール時のログメッセージにありました。
$ apt install zram-config パッケージリストを読み込んでいます... 完了 依存関係ツリーを作成しています 状態情報を読み取っています... 完了 以下のパッケージが新たにインストールされます: zram-config アップグレード: 0 個、新規インストール: 1 個、削除: 0 個、保留: 0 個。 4,312 B のアーカイブを取得する必要があります。 この操作後に追加で 55.3 kB のディスク容量が消費されます。 取得:1 http://ftp.tsukuba.wide.ad.jp/Linux/ubuntu focal/universe amd64 zram-config all 0.5 [4,312 B] 4,312 B を 0秒 で取得しました (50.8 kB/s) 以前に未選択のパッケージ zram-config を選択しています。 (データベースを読み込んでいます ... 現在 295974 個のファイルとディレクトリがインストールされています。) .../zram-config_0.5_all.deb を展開する準備をしています ... zram-config (0.5) を展開しています... zram-config (0.5) を設定しています ... Created symlink /etc/systemd/system/multi-user.target.wants/zram-config.service → /lib/systemd/system/zram-config.service.
なんか /lib/systemd/system/zram-config.service というものが作成されたようです。(Linux Mint 20.3 の場合)
まずはこの中身を確認してみましょう。
$ cat /lib/systemd/system/zram-config.service [Unit] Description=Initializes zram swaping [Service] ExecStart=/usr/bin/init-zram-swapping ExecStop=/usr/bin/end-zram-swapping Type=oneshot RemainAfterExit=true [Install] WantedBy=multi-user.target
サービス開始時に /usr/bin/init-zram-swapping を使用するみたいです。こちらも中身を確認してみましょう。
$ cat /usr/bin/init-zram-swapping #!/bin/sh # load dependency modules NRDEVICES=$(grep -c ^processor /proc/cpuinfo | sed 's/^0$/1/') if modinfo zram | grep -q ' zram_num_devices:' 2>/dev/null; then MODPROBE_ARGS="zram_num_devices=${NRDEVICES}" elif modinfo zram | grep -q ' num_devices:' 2>/dev/null; then MODPROBE_ARGS="num_devices=${NRDEVICES}" else exit 1 fi modprobe zram $MODPROBE_ARGS # Calculate memory to use for zram (1/2 of ram) totalmem=`LC_ALL=C free | grep -e "^Mem:" | sed -e 's/^Mem: *//' -e 's/ *.*//'` mem=$(((totalmem / 2 / ${NRDEVICES}) * 1024)) # initialize the devices for i in $(seq ${NRDEVICES}); do DEVNUMBER=$((i - 1)) echo $mem > /sys/block/zram${DEVNUMBER}/disksize mkswap /dev/zram${DEVNUMBER} swapon -p 5 /dev/zram${DEVNUMBER} done
設定ファイルに設定値を用意しておくのではなく、このスクリプトで実行に CPU のコア数や物理メモリー容量を元に zram なスワップ領域を作成しているようです。
まずはスワップ領域の個数とサイズを決めないといけないのですが、どれくらいが適切なのかサッパリ見当がつきません。前と同じで 2GB を 1 個でもいいんですが、せっかくなので 1GB を 4 個に設定してみます。
また圧縮アルゴリズムも LZ4 に変えてみようと思います。参考にしたのはこちらのページの「Performance」という章です。
https://github.com/ecdye/zram-config
容量というか圧縮率よりもスピードを重視すると LZ4 が良いのでは?と思いまして。
$ sudo xed /usr/bin/init-zram-swapping #!/bin/sh # load dependency modules #NRDEVICES=$(grep -c ^processor /proc/cpuinfo | sed 's/^0$/1/') NRDEVICES=4 if modinfo zram | grep -q ' zram_num_devices:' 2>/dev/null; then MODPROBE_ARGS="zram_num_devices=${NRDEVICES}" elif modinfo zram | grep -q ' num_devices:' 2>/dev/null; then MODPROBE_ARGS="num_devices=${NRDEVICES}" else exit 1 fi modprobe zram $MODPROBE_ARGS # Calculate memory to use for zram (1/2 of ram) totalmem=`LC_ALL=C free | grep -e "^Mem:" | sed -e 's/^Mem: *//' -e 's/ *.*//'` #mem=$(((totalmem / 2 / ${NRDEVICES}) * 1024)) mem=$((1024 * 1024 * 1024)) # initialize the devices for i in $(seq ${NRDEVICES}); do DEVNUMBER=$((i - 1)) echo lz4 > /sys/block/zram${DEVNUMBER}/comp_algorithm echo $mem > /sys/block/zram${DEVNUMBER}/disksize mkswap /dev/zram${DEVNUMBER} swapon -p 5 /dev/zram${DEVNUMBER} done
変更したのは 3 点です。(うまく色付けできませんでした)
・NRDEVICES=4 と固定値を指定
・mem=$((1024 * 1024 * 1024)) とこちらも固定値を指定
・echo lz4 > /sys/block/zram${DEVNUMBER}/comp_algorithm を追加
comp_algorithm の設定は場所というか順番が大事で、disksize の設定の下に記載するとエラーになり設定できませんでした。
完成した zram のスワップは以下の通りです。
$ zramctl NAME ALGORITHM DISKSIZE DATA COMPR TOTAL STREAMS MOUNTPOINT /dev/zram3 lz4 1G 4K 64B 4K 8 [SWAP] /dev/zram2 lz4 1G 4K 64B 4K 8 [SWAP] /dev/zram1 lz4 1G 4K 64B 4K 8 [SWAP] /dev/zram0 lz4 1G 4K 64B 4K 8 [SWAP] $ swapon --show NAME TYPE SIZE USED PRIO /dev/zram0 partition 1024M 0B 5 /dev/zram1 partition 1024M 0B 5 /dev/zram2 partition 1024M 0B 5 /dev/zram3 partition 1024M 0B 5
さあ、早くスワップアウトよ発生するのだ。
(その後)
Timeshift の定時バックアップが走ったあたりで待望の?スワップアウトが発生しました。swapon コマンドと zramctl コマンドでそれぞれ使用状況を確認してみます。
$ swapon --show NAME TYPE SIZE USED PRIO /dev/zram0 partition 1024M 768K 5 /dev/zram1 partition 1024M 768K 5 /dev/zram2 partition 1024M 512K 5 /dev/zram3 partition 1024M 512K 5 $ zramctl NAME ALGORITHM DISKSIZE DATA COMPR TOTAL STREAMS MOUNTPOINT /dev/zram3 lz4 1G 516K 133.8K 368K 8 [SWAP] /dev/zram2 lz4 1G 388K 116.6K 388K 8 [SWAP] /dev/zram1 lz4 1G 140K 36.5K 204K 8 [SWAP] /dev/zram0 lz4 1G 604K 134.6K 368K 8 [SWAP]
スワップの使用量は 2.5MB(768K + 768K + 512K + 512K)です。これは Linux Mint のシステムモニターの値と一致しています。
しかし、zramctl コマンドの出力結果は難解です。
「COMPR」が圧縮後の格納データ容量らしいのですが、swapon コマンドの結果と一致していません。「TOTAL」さえも一致しておらず、はたして swapon コマンドが認識しているスワップの使用量とは何を示しているのやら、です。
またスワップアウトされた時に様子を見てみることにします。