我的NAS 一直是禁用掉了 SWAP,因为关闭 SWAP 可以有效降低群晖 NAS 硬盘炒豆子的声音,群晖的这个 SWAP 机制简直是绝了,比如你的 4 个盘位都插上了硬盘,那它会在这 4 个块硬盘上都创建 SWAP 文件,并且启用 RAID1,也就是说要响,所有硬盘全响。。。
因为我的 NAS 是 16GB 内存,所以我对 SWAP 基本没有需求,但是不少同学的 NAS 可能也就 4GB,或者 8GB 内存,如果启用了虚拟机或者 docker 容器比较多,就会造成内存紧张,禁用 SWAP 可能会导致 OOM,所以我的建议是开启 ZRAM,并设置高优先级,这样内存不足时就会优先使用 ZRAM 了。
目录
ZRAM 介绍
zram,旧称为 compcache,是一个用于在内存中创建压缩的块设备的 Linux 内核模块,即带实时磁盘压缩的内存盘。通过 zram 创建的块设备可以用作 swap 或是内存盘。zram 有两个常见的应用场景,一个是储存临时文件(
引用自 archlinuxcn.org,本文主要是将 zram 用作 swap。/tmp
),另一个是用作 swap。早期 zram 只有前一个功能,也是它原名 “compcache” (compressed cache) 的由来。
一键脚本
我编写了一个群晖 DSM 一键启用 ZRAM 的脚本,默认为百分之 50 RAM,压缩算法 LZO(我的 DS918+实测,群晖zram 默认只支持这一种算法,不支持 zstd 算法,比较无语。)
复制这段代码,创建名为manage_zram.sh
的脚本。
使用方法,终端或群晖计划任务中运行该脚本sudo ./manage_zram.sh
#!/bin/bash
# 脚本名称: manage_zram.sh
# 描述: 这个脚本用于在群晖NAS上管理zram设备,包括创建、配置和停用zram。
# 使用方法: sudo ./manage_zram.sh [-p <百分比>] [-d] [-m <最大压缩流>]
# 选项:
# -p, --percent: 设置zram大小占总内存的百分比(默认50%)
# -d, --disable: 停用zram设备
# -m, --max-streams: 设置最大压缩流数量(默认为CPU核心数)
set -e # 遇到错误立即退出
set -u # 使用未定义的变量时报错
# 默认值
RAM_PERCENT=50
DISABLE_ZRAM=false
MAX_COMP_STREAMS=$(nproc)
# 错误处理函数
error_exit() {
echo "错误: $1" >&2
exit 1
}
# 日志函数
log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1"
}
# 解析命令行参数
while [[ $# -gt 0 ]]; do
case $1 in
-p|--percent)
RAM_PERCENT="$2"
if ! [[ $RAM_PERCENT =~ ^[0-9]+$ ]] || [ $RAM_PERCENT -lt 1 ] || [ $RAM_PERCENT -gt 100 ]; then
error_exit "RAM百分比必须是1到100之间的整数。"
fi
shift 2
;;
-d|--disable)
DISABLE_ZRAM=true
shift
;;
-m|--max-streams)
MAX_COMP_STREAMS="$2"
if ! [[ $MAX_COMP_STREAMS =~ ^[0-9]+$ ]] || [ $MAX_COMP_STREAMS -lt 1 ]; then
error_exit "最大压缩流数量必须是正整数。"
fi
shift 2
;;
*)
error_exit "未知选项: $1\n使用方法: $0 [-p <百分比>] [-d] [-m <最大压缩流>]"
;;
esac
done
# 检查root权限
[[ $EUID -ne 0 ]] && error_exit "此脚本必须以root权限运行。"
# 检查是否为DSM系统
[[ ! -f "/etc.defaults/VERSION" ]] && error_exit "无法检测到DSM系统,脚本可能无法正常工作。"
# 检查zram模块是否可用
check_zram_available() {
if ! modprobe -n zram &>/dev/null; then
error_exit "zram模块不可用。请确保您的系统支持zram。"
fi
}
# 停用zram函数
disable_zram() {
local zram_devs=$(ls /dev/zram* 2>/dev/null)
if [[ -n "$zram_devs" ]]; then
for dev in $zram_devs; do
swapoff $dev 2>/dev/null || log "无法停用 $dev"
echo 1 > /sys/block/$(basename $dev)/reset 2>/dev/null || log "无法重置 $dev"
done
rmmod zram 2>/dev/null || log "无法卸载zram模块"
log "zram已停用并移除。"
else
log "未检测到活动的zram设备。"
fi
}
# 配置和启用zram
configure_zram() {
# 加载zram模块
modprobe zram num_devices=1 || error_exit "无法加载zram模块。"
# 设置最大压缩流
echo $MAX_COMP_STREAMS > /sys/block/zram0/max_comp_streams || log "无法设置最大压缩流,使用默认值。"
# 计算zram大小
local TOTAL_MEM=$(grep MemTotal /proc/meminfo | awk '{print $2}')
local ZRAM_SIZE=$((TOTAL_MEM * 1024 * RAM_PERCENT / 100))
# 设置zram大小
echo $ZRAM_SIZE > /sys/block/zram0/disksize || error_exit "无法设置zram大小。"
# 创建swap并启用
mkswap /dev/zram0 || error_exit "无法创建swap分区。"
swapon -p 100 /dev/zram0 || error_exit "无法启用zram swap。"
log "zram已成功配置并启用为swap"
log "压缩算法: lzo (群晖NAS默认)"
log "最大压缩流: $(cat /sys/block/zram0/max_comp_streams)"
log "RAM使用百分比: $RAM_PERCENT%"
log "zram大小: $((ZRAM_SIZE / 1024 / 1024)) MB"
}
# 主逻辑
check_zram_available
if [[ $DISABLE_ZRAM = true ]]; then
disable_zram
else
disable_zram # 先停用现有的zram设备
configure_zram
fi
效果&性能测试(跑分)
性能测试:sudo fio -filename=/dev/block/zram0 -thread -rw=write -bs=32468k -size=500M -group_reporting -numjobs=1 -name=mytest
DS918+ 跑分数据(Intel J4125)
mytest: (g=0): rw=write, bs=(R) 31.7MiB-31.7MiB, (W) 31.7MiB-31.7MiB, (T) 31.7MiB-31.7MiB, ioengine=psync, iodepth=1
fio-3.33
Starting 1 thread
mytest: Laying out IO file (1 file / 500MiB)
mytest: (groupid=0, jobs=1): err= 0: pid=6383: Thu Aug 15 16:00:40 2024
write: IOPS=36, BW=1149MiB/s (1205MB/s)(476MiB/414msec); 0 zone resets
clat (usec): min=15108, max=15638, avg=15387.76, stdev=150.99
lat (usec): min=22538, max=23426, avg=23098.89, stdev=228.51
clat percentiles (usec):
| 1.00th=[15139], 5.00th=[15139], 10.00th=[15139], 20.00th=[15270],
| 30.00th=[15270], 40.00th=[15270], 50.00th=[15401], 60.00th=[15401],
| 70.00th=[15533], 80.00th=[15533], 90.00th=[15533], 95.00th=[15664],
| 99.00th=[15664], 99.50th=[15664], 99.90th=[15664], 99.95th=[15664],
| 99.99th=[15664]
lat (msec) : 20=100.00%
cpu : usr=27.60%, sys=72.40%, ctx=11, majf=0, minf=0
IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
issued rwts: total=0,15,0,0 short=0,0,0,0 dropped=0,0,0,0
latency : target=0, window=0, percentile=100.00%, depth=1
Run status group 0 (all jobs):
WRITE: bw=1149MiB/s (1205MB/s), 1149MiB/s-1149MiB/s (1205MB/s-1205MB/s), io=476MiB (499MB), run=414-414msec
相关文章
群晖性能优化-降低swap使用率
本文由 NG6 于2024年08月15日发表在 sleele的博客
如未特殊声明,本站所有文章均为原创;你可以在保留作者及原文地址的情况下转载
转载请注明:群晖 DSM 开启 ZRAM 内存压缩-增加可用内存 | sleele的博客
【DSM7.2.2】可是群晖自带zram啊。。。而且还是默认开启的。 设置项在 控制面板 – 硬件和电源 – 常规 – 内存压缩。 这个选项就是zram,默认就是启用的。 观察有没有开启可以用 cat /proc/swaps 你在这里能看到群晖的所有swap分区位置,默认情况下能看到几个带zram字样的分区,这就是说明已经开了zram了。 在控制面板关掉之后就没有了,剩下的只有默认的/dev/md1 这个硬盘上的swap分区了。
@番茄 而且在7.2.2中,zram的算法已经是zstd了。 可能跟我用的sa6400有关,内核比较新。
cat /sys/block/zram0/comp_algorithm
lzo [lzo-rle] zstd
@番茄 1、我一直是关闭swap使用,不确定群晖默认zram情况,写这个脚本和这篇文章的时候,我本机观察是没有zram的
2、和内核有关系吧,我的DS918 没有zstd,只有lzo
感谢大佬
@想上天的兔子 代码复制有多于空格,删除也报错manage_zram.sh: line 16: syntax error near unexpected token `$'{r”
DS918+群晖6.23,bash运行 即 bash /root/manage_zram.sh