在试验 Proxmox VE 时,我们遇到了一个奇怪的性能问题:
VM 磁盘可以存储为单独的原始 ZFS zvol,也可以存储为单个公共数据集上的 qcow2 文件(还有其他选项)。
出于某种原因,zvols 的顺序写入性能非常差而不是数据集,即使两者都驻留在同一个 zpool 上。
这不会明显影响 VM 的正常运行,但在休眠/RAM 快照 VM 时会产生巨大差异(休眠 32 GB RAM 时为 140 秒 vs 44 秒)。
当同一个 zpool 上都是相同的数据时,怎么会发生这种情况呢?
以下是 (1) 数据集、(2) Proxmox 创建的 zvol 和 (3) 具有更大 volblocksize 的手动创建的 zvol 的写入性能。奇怪的是,当 (4) 在完全相同的 zvol 上创建文件系统并写入该文件系统时,写入吞吐量会稍微快一些。test.bin
包含 16 GiB 的 urandom 数据以绕过 ZFS 压缩。我已经运行了几次每个测试,结果大致相同,因此缓存似乎不是一个重要因素。
# rpool/ROOT recordsize 128K default
> dd if=/mnt/ramdisk/test.bin of=/var/lib/vz/images/test.bin bs=1M status=progress
17179869184 bytes (17 GB, 16 GiB) copied, 20.9524 s, 820 MB/s
# with conv=fdatasync, this drops to about 529 MB/s
# rpool/data/vm-112-disk-0 volblocksize 8K default
> dd if=/mnt/ramdisk/test.bin of=/dev/zvol/rpool/data/vm-112-disk-0 bs=1M status=progress
17179869184 bytes (17 GB, 16 GiB) copied, 67.7121 s, 254 MB/s
# with conv=fdatasync, this drops to about 151 MB/s
# rpool/data/vm-112-disk-2 volblocksize 128K -
> dd if=/mnt/ramdisk/test.bin of=/dev/zvol/rpool/data/vm-112-disk-2 bs=1M status=progress
17179869184 bytes (17 GB, 16 GiB) copied, 35.2894 s, 487 MB/s
# with conv=fdatasync, this drops to about 106 MB/s
> mkfs.ext4 /dev/zvol/rpool/data/vm-112-disk-2
> mount /dev/zvol/rpool/data/vm-112-disk-2 /mnt/tmpext4
> dd if=/mnt/ramdisk/test.bin of=/mnt/tmpext4/test.bin bs=1M status=progress
17179869184 bytes (17 GB, 16 GiB) copied, 23.7413 s, 724 MB/s
# with conv=fdatasync, this drops to about 301 MB/s
系统和 zpool 设置如下所示:
> uname -r
5.4.78-2-pve
> zfs version
zfs-0.8.5-pve1
zfs-kmod-0.8.5-pve1
> zpool status
pool: rpool
state: ONLINE
scan: scrub repaired 0B in 0 days 00:10:19 with 0 errors on Sun Mar 14 00:34:20 2021
config:
NAME STATE READ WRITE CKSUM
rpool ONLINE 0 0 0
raidz2-0 ONLINE 0 0 0
ata-ST4000NE001-xxxxxx_xxxxxxxV-part3 ONLINE 0 0 0
ata-ST4000NE001-xxxxxx_xxxxxxx4-part3 ONLINE 0 0 0
ata-ST4000NE001-xxxxxx_xxxxxxx3-part3 ONLINE 0 0 0
ata-ST4000NE001-xxxxxx_xxxxxxx9-part3 ONLINE 0 0 0
ata-ST4000NE001-xxxxxx_xxxxxxx6-part3 ONLINE 0 0 0
ata-ST4000NE001-xxxxxx_xxxxxxxP-part3 ONLINE 0 0 0
logs
mirror-1 ONLINE 0 0 0
ata-INTEL_SSDSC2BB800G6_xxxxxxxxx5xxxxxxxx-part2 ONLINE 0 0 0
ata-INTEL_SSDSC2BB800G6_xxxxxxxxx6xxxxxxxx-part2 ONLINE 0 0 0
cache
ata-INTEL_SSDSC2BB800G6_xxxxxxxxx5xxxxxxxx-part1 ONLINE 0 0 0
ata-INTEL_SSDSC2BB800G6_xxxxxxxxx6xxxxxxxx-part1 ONLINE 0 0 0
errors: No known data errors
答案1
您可能遇到过(正在遇到)OpenZFS 问题 #11407[性能] 写入 ZVOL 时,性能损失严重,延迟和写入放大。
引用 sempervictus 的话:
ZVOL 的设计相当糟糕。块设备是一系列原始位,句号。zvol 是一种抽象,它表示一个范围,但将它们映射到非连续空间中,并使用涉及线性化的确定性逻辑。因此从架构上讲,它本质上会更慢地解决请求。请求路径会随着在 zvol 之前写入的数据而延长,这一事实放大并加剧了糟糕的设计。
最重要的是,在引入变更时几乎从未考虑过 zvols,多年来 zfs 的性能不断下降,而维护人员从来没有时间或兴趣关注该功能。
针对这一确切问题,我亲自对机械驱动器(旋转锈蚀)进行了广泛的基准测试,存储在数据集上的 kvm 磁盘映像(我今天偏爱原始映像)在几乎所有测试案例中都击败了 zvol,并表现出“正常”的系统负载,而 zvol 测试几乎总是导致负载增加几个数量级。一些 zvol 测试配置fio
也buffered=1
确实导致系统不稳定、锁定和崩溃。