Linux系统下用文件创建ZFS分区与zstd,压缩PostgreSQL/MySQL等数据库或文件内容
步骤一:准备工作 - 启用 contrib 和 non-free 软件源
编辑 sources.list 文件:
sudo nano /etc/apt/sources.list修改文件内容:
在每一行 deb 和 deb-src 的末尾,添加 contrib non-free (对于较新的系统如 Debian 12,建议也加上 non-free-firmware)。
刷新软件包列表:
apt-get update步骤二:安装 ZFS 并加载内核模块
执行安装命令:
sudo apt-get install zfs-dkms zfsutils-linux加载 ZFS 内核模块:
sudo modprobe zfs检查是否成功:
sudo zfs list错误处理:如果 modprobe zfs 失败
如果您看到类似 modprobe: FATAL: Module zfs not found 的错误,这是因为 ZFS 模块虽然被 dkms 编译了,但尚未被当前运行的内核加载。
首选解决方案:重启服务器。 这是最简单且最有效的方法。
sudo reboot重启后,系统会自动加载为新内核编译的模块。再次登录服务器后,运行 sudo zfs list 验证即可。
备用方案 (如果重启无效): 手动重新编译模块。
# 安装与当前内核匹配的头文件和编译工具
sudo apt install build-essential linux-headers-$(uname -r)
# 强制 dkms 重新编译 zfs 模块
sudo dpkg-reconfigure zfs-dkms
# 再次尝试加载
sudo modprobe zfs步骤三:创建基于文件的 ZFS 存储池 (zpool)
创建虚拟硬盘文件:
# 创建一个 50GB 的文件作为 ZFS 存储池的后端设备
sudo fallocate -l 50G /zfs_storage.img创建 ZFS 存储池:
我们将存储池命名为 pgpool (您可以自定义)。
# -f 参数用于强制创建,避免因使用文件作为设备而产生的警告
sudo zpool create -f pgpool /zfs_storage.img检查存储池状态:
sudo zpool status您应该能看到名为 pgpool 的池,其状态为 ONLINE。
步骤四:创建 ZFS 数据集 (dataset) 并为 PostgreSQL 调优
创建数据集:
sudo zfs create pgpool/data开启 zstd 压缩:(也可以更改为lz4压缩)
sudo zfs set compression=zstd pgpool/data设置 Recordsize 为 8K:
将 ZFS 的记录大小与 PostgreSQL 的页面大小对齐 (均为 8KB) 可以显著提升性能。
sudo zfs set recordsize=8k pgpool/data设置挂载点:
# 假设您的 PostgreSQL 数据目录是 /var/lib/postgresql/14/main
# 请根据您的实际版本和路径进行调整
sudo zfs set mountpoint=/home/pgdata pgpool/data步骤五:验证压缩结果
将数据存入数据库后,运行指令
sudo zfs list -o name,used,logicalused,compressratio pgpool/data即可查看压缩效果。
经过实测:使用lz4压缩,压缩率在1.8x左右;使用zstd压缩,压缩率在2.5x左右。zstd相较于lz4更吃性能但是压缩效率更高。具体性能损耗未测试。
另外貌似postgresql的jsonb默认会使用pglz压缩方式,但我切换到lz4压缩硬盘占用并没有下降。
测试环境:阿里云ECS e实例 2c2g(免费1年学生机)