刘泉皓

没有最强的法术,只有最强的法师。

linux系统启用zram做swap

04 May 2020 » memory

zram,一种linux内核内存压缩技术,使用压缩内存作为swap。默认情况下,swap默认使用硬盘做交换空间,所以一旦使用到它,系统将奇卡无比,5分钟动一下鼠标,10分钟切一下桌面:)。但是使用了zram后,内核使用一部分内存作为swap,当系统需要swap时,会把普通内存中的数据压缩后放到zram中,这样读写极快,系统就不会卡了。传闻,可以让4G内存用成8G的效果。windows和mac系统有各自类似zram的技术,相关信息可自行查阅。

一、安装zram-config

我的系统是ubuntu20.04,所以直接apt安装即可,其余系统可以自行google,zram套件安装很简单。

liuxu@liuxu-TM1612:~$ sudo apt install zram-config

二、压缩算法选择

首先看看系统支持那些算法。

liuxu@liuxu-TM1612:~$ cat /sys/block/zram0/comp_algorithm
[lzo] lzo-rle lz4 lz4hc 842 zstd 

一般情况下,各种博客建议使用lz4算法,但是根据zstd介绍,我这里建议,如果你需要更快的压缩解压速度,选择lz4,如果你需要更高的压缩率(高一个点,如果你特别缺内存的话),可以选择zstd。我笔记本也就4G内存,划给zram也就2G,所以选择了zstd,压缩速度470 MB/s,解压速度1380 MB/s够用了。

三、配置zram

安装后会有zram-config.service这个systemd文件,它使用/usr/bin/init-zram-swapping这个脚本做启动配置zram。

liuxu@liuxu-TM1612:~$ cat /etc/systemd/system/multi-user.target.wants/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
liuxu@liuxu-TM1612:~$ 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 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

如果要设置自定义的算法,只需要在# initialize the devices下面的for循环里添加就行。

liuxu@liuxu-TM1612:~$ cat /usr/bin/init-zram-swapping
...
# initialize the devices
for i in $(seq ${NRDEVICES}); do
  DEVNUMBER=$((i - 1))
  echo zstd > /sys/block/zram${DEVNUMBER}/comp_algorithm
  echo $mem > /sys/block/zram${DEVNUMBER}/disksize
  ...
done

然后重启zram-config.service即可。

liuxu@liuxu-TM1612:~$ sudo systemctl restart zram-config.service
liuxu@liuxu-TM1612:~$ cat /sys/block/zram0/comp_algorithm 
lzo lzo-rle lz4 lz4hc 842 [zstd]
liuxu@liuxu-TM1612:~$ zramctl --output-all
NAME       DISKSIZE  DATA COMPR ALGORITHM STREAMS ZERO-PAGES TOTAL MEM-LIMIT MEM-USED MIGRATED MOUNTPOINT
/dev/zram3     481M 45.2M  9.3M zstd            4       2008 10.1M        0B    10.1M       0B [SWAP]
/dev/zram2     481M 45.2M  9.5M zstd            4       1541 10.3M        0B    10.3M       3B [SWAP]
/dev/zram1     481M 46.5M  9.7M zstd            4       1899 10.5M        0B    10.5M       0B [SWAP]
/dev/zram0     481M 47.4M  9.9M zstd            4       2026 10.7M        0B    10.7M       4B [SWAP]

四、额外信息

参考:

http://kernel.meizu.com/zram-introduction.html

https://blog.gloriousdays.pw/2018/11/30/memory-compress-using-zram/


知识共享许可协议    鄂ICP备 15002452号-5    鄂公网安备 42088102000048号