记录一次不严谨的ZVOL虚拟机顺序写入性能的测试
一直以来对于建构在ZVOL上面的虚拟机磁盘性能都不太满意。今天机缘巧合,测试一下,看看如何提高顺序的写入性能。
记录
测试平台
- Host OS: Proxmox VE 7.4
- CPU: i5 7600K
- RAM: 64GB DDR4 2400 No-ECC
- Motherboard: Gigabyte Z270p-D3
- Host File System: ZFS
- 一个非常不入流的SATA转接卡:基于ASMedia asm1061的PCIE 3.0 x1转4口SATA
- M.2 NVME: ADATA 850 2T
- HDD: 2 x Seagate EXOS 14TB + 1 WD EDGZ 14TB
测试方法非常的粗暴
- PVE 上面一个单独的NVMe,做单盘ZFS
- 在这个单盘ZFS上面创建ZVOL,在其上创建VM
- VM系统选择Xubuntu
- 这个 ZFS pool 上面不跑 PVE 的root。这个pool单纯只跑VM的images
- 另外有一个TrueNAS Scale的VM。
- 直通ASMedia asm1061给Truenas
- ZFS Mirror: Seagate EXOS 14TB + WD EDGZ 14TB
- 三路Mirror,理论上读取速度应为单盘3倍,写入速度还是1倍。
- TrueNAS管理的ZFS mirror,通过SAMBA share,分享给Xubuntu。
- 在Xubuntu上面通过 Copy一个40GB的文件来测试大文件顺序写入的性能。
一些测试中没有改变过的细节参数
- TrueNAS VM的RAM:16GB
- TrueNAS ZFS Mirror dataset的recordsize: 128k
- TrueNAS ZFS Mirror dataset已用空间:~1TB
- TrueNAS和Xubuntu的网络连接:virtual bridge,理论上跑10Gbe应该是没有问题的,保证网速不是瓶颈。
💡
即使是virtual bridge,性能上限达到并超过10Gbe应该不成问题,但是MTU设置依旧是1500,以保证兼容性。后续测试结果来看,受限于HDD的读取性能,此设定应该不是瓶颈。
以下就是测试的流水账了。
- Baseline:
volblocksize: 16k
, 在QEMU的config里面没有添加args: -global scsi-hd.physical_block_size=16384
, VM文件系统: EXT4, CPU cores: 2。- 使用
sudo tune2fs -l /dev/sda3
检查,确认 RAID stride 和 stripe 都是1,也就是说VM上面的文件系统不认为Virtual Disk上有RAID。 - 用默认的文件管理器Thunar,速度在170MB/s左右。
- 使用
- 在QEMU的config里面添加
args: -global scsi-hd.physical_block_size=16384
,重新安装系统sudo tune2fs -l /dev/sda3
确认RAID stride 和 stripe 都是4.- Thunar测试速度还是在170MB/s左右。
- 在PVE->Hardware里面,设定Harddrive,选上SSD Emulate 和 Discard
- Thunar测试发现速度没变。
- 在PVE主机上测试(mount samba share, then use rsync -ahP to the ‘fastpool’)
- 这时’fastpool’是一个dataset,而不是VM里面用的ZVOL
- 速度在400MB/s到600MB/s之间。应该是一个合理的3-way mirror HDD的读取速度。稳定的性能大概有440MB/s吧。
- CPU类型改为Host
- 依旧是170MB/s左右
- Harddrive Async IO改为
native
,threads
:- 依旧是170MB/s左右。使用 threads 的时候似乎性能更差了一些。
- Harddrive Async IO改回default (uring),CPU cores 从2添加到4。
- 速度大体能提升到220MB/s
- 在cores=2的时候,Samba copy的时候CPU占用率在65%左右。没想到这时候给更多的核居然可以提高一点性能。但是距离440MB/s还有很远。
- 内存从2GB提升到8GB
- 没有变化,甚至有些不稳定,在170到220之间飘忽不定。
- 把ZVOL的
volblocksize
改为64K
,重新创建VM,添加args: -global scsi-hd.physical_block_size=65536
,然后重新安装系统。- 没有变化
- 这个
args: -global scsi-hd.physical_block_size=65536
似乎对于顺序写入的影响不大(可以说基本没有任何影响)。
- 把ZVOL的volblocksize改为128K,重新创建VM以及安装系统。
- 系统的安装速度似乎变慢了一些。也许是小文件的写入性能已经劣化了。
- 1 Core CPU: 大文件顺序写入还是在200MB/s左右。
- 4 Core CPU: 250MB/s左右。
- Async IO = native: 最高270MB/s左右。稳定的速度还是在250MB/s左右。
- Cache改为write back:性能劣化,基本稳定在200MB/s左右。
- VM的ZVOL的
logbias
从latency,改为throughput:没有变化。 - 添加
scsi-hd.physical_block_size=131072
:没有变化。 - 尝试文件系统改为XFS(根据):没有变化。
- 尝试使用新的专用vmbr虚拟网口:没有变化。
- 不用文件管理器Copy,而是在VM上面 mount Samba share,然后使用
rsync -ahP
来copy这个40GB大文件:- 速度可以相对稳定在350MB/s。
- 最高可以达到450MB/s,甚至瞬时可以达到500MB/s以上。
- 证实了Thunar这个文件管理器在处理Samba的时候,性能有损耗!
- 改回
volblocksize=16k
的虚拟机(依旧是4 core CPU,8GB)- rsync速度下降为稳定在300MB/s以上,时不时在350MB/s左右。相比volblocksize=128k的情况,性能还是有所下降的。
- 在VM里面直接使用fio 写入 1M blocksize的8GB文件
- 速度可以高达1.6GB/s
- 但是不是很确定fio是不是都写入的0.
💡
Samba的挂载采用的是version 3.0。不确定是不是相比 version 1.0有性能上的提升。
结论
- Thunar的Samba性能有坑,不应当作为Samba读取性能的测试方式,甚至实际使用中还会有性能问题。
- 128k vs 16k 的volblocksize,对于其上运行的VM来讲,对于大文件的顺序写入性能还是有影响的。对于小文件写入应该也有影响,128K的应该对小文件写入有很大的负面影响,可能会有很大的写入放大。
- 从3-way HDD ZFS mirror rsync出来一个40GB的大文件,如果目的地是一个足够快的zfs dataset,440MB/s的速度大概就是稳定速度了。极速可能可以到600MB/s。此时,一个不入流的SATA -> PCIE卡还可以应付。由此推断,PCIE 3.0 x1的4口SATA,在全接HDD的情况下,应该大概还不会成为性能瓶颈(PCIE 3.0 x1 理论速度上限 8Gbps 即 1GB/s)。同理一个PCIE 2.0 x1 转 2口SATA的卡,大概也还能继续发挥余热。
- 但是一旦使用SSD,那么不上正经的PCIE 3.0 的HBA卡就说要不过去了。
- VM里面的速度目前最多也只能接近400MB/s,这是在使用128K的volblocksize的情况下,而且是使用了XFS(大文件方面XFS应当比EXT4性能更强,但是对于这次的单纯顺序写入,我认为应该是没有差异的。)
args: -global scsi-hd.physical_block_size=<your_volblocksize_in_bytes>
确实可以在VM系统安装格盘的时候,指导分区程序。做出来的文件系统,哪怕blocksize定死为4K的系统,也会认为下面的physical blocksize 是指定的这个大小。也许在小文件和随机写入方面,能够提高性能,减少写入放大的问题。不过在大文件顺序写入的时候,这个设定用处不大。
最终还是在VM里面把Samba中大文件的连续读取,写入本地磁盘的性能,从170MB/s提高到了300MB/s,甚至接近400MB/s。这里面主要因素大体应该是:volblocksize 16k vs 128k,rsync vs thunar,CPU 1 core vs 4 core。而其他一些设定比如 async io (default uring vs native),cache (no cache vs write back),ssd emulate,RAM size,XFS vs EXT4,都影响不大。
❗
这次测试的这个 VM 用的 ZFS pool 是开启了 thin provision的。这个也许对 ZVOL 上面模拟出来的 block 具体的存取操作性能有影响。另外这次测试中间改更改过 VM disk的大小,从128GB更改为512GB,但没有发现任何性能变化。也许当thin provision被关闭之后,更改大小也会影响性能。
后记
后来又尝试看看Windows虚拟机在读取Samba大文件时候的性能。可是折腾一通之后,不知道为什么,Windows下本地磁盘的写入性能极差,可以几乎卡死,任务管理器上显示hard disk 写入最高也就在 20MB/s。Google一番也没什么答案。大多数人使用Windows VM的时候,对应的Host storage都是 directory,然后使用 QCOW2或者RAW,没有查到关于使用 ZVOL的资料。遂放弃。
另外,记录一下期间用过的一些命令
FIO测试本地文件写入性能
File: write_test.fio
然后执行
sudo fio write_test.fio
挂载SAMBA share
# make sure install 'cifs-utils' first
# sudo apt-get install cifs-utils
# Then, run this
sudo mount -t cifs -o username=serverUserName //myServerIpAdress/sharename /mnt/myFolder/
# When finished, unmount
# Note: You can't unmount in the mount folder,
# you need to cd out of the mount folder tree first.
# Note 2: the command is 'umount', not 'unmount'.
cd ~
sudo umount <path_to_the_mount_folder>
检查RAID Stride 和 Stripe 的设定
# Note, you may need to install it first with apt-get
# /dev/sda2 is supposed to be the partition of your root system
# Change it accordingly, e.g. on Xubuntu, it is /dev/sda3
sudo tune2fs -l /dev/sda2
胡思乱想
- 总觉得 Proxmox上面的ZFS设定有点奇怪。在其上创建的ZVOL上面跑VM总觉得很难得到想要的Disk IO的性能。之前在Proxmox默认创建的
rpool
上面跑VM,即使是使用SSD ZFS mirror的情况下,也能在非常少量的VM内IO的时候,直接把主机卡死(IO delay 达到70左右,整机卡死)。因而我现在只把rpool当作Proxmox启动自己专用的系统盘,而不敢在上面跑VM。
💡
消费级SATA SSD 组VM pool的性能测试详见后续文章。
- Proxmox自然是要挣钱的,而企业方现在可能真的会大规模用的方案,应该是更多的使用Proxmox在超融合方面的能力,以及对于SAN的支持。对于生产环境而言,也许根本就不会有VM跑在本地的ZVOL上面。要不就是Ceph走超融合,要不就是iSCSI通过SAN来提供VM的存储。两者都能提供足够的冗余,并满足生产环境对于可迁移性的要求。本地跑ZVOL算是怎么回事,完全就是玩票的搞法。
- 并且考虑之前在Proxmox上面组HDD的 ZFS mirror 10的经验,TrueNAS的对于ZFS就专注很多。目前来看,性能表现上面,也一直是比较符合理论预期的。比较可惜的一点是,TrueNAS如果反过来再给主机Proxmox提供storage(尤其是iSCSI),则容易陷入因为挂载没有关闭,而无法关闭TrueNAS,进而Proxmox也在该关机的时候无法关机的陷阱。虽然有hook script可以解决一部分问题,但是既然是anti-pattern,那就不要这样做好了。之后考虑的方案可能就是 Application 的 VM 和 Infra 的VM分开在两个物理机上。Infra 的 物理机负责 TrueNAS,OPNsense,以及Backup的处理,主要就是提供大容量存储和网络(DNS, DHCP, Firewall)的需求。理论上这个 Infra 物理机也应该提供 SAN 的支持,或者至少是 iSCSI的服务。但是因为我现在没有10Gbe,所以大概没有太大必要这么做?而Application的主机就是跑各种应用服务以及 docker,甚至尝试 k8s 了。现在一个麻烦的地方就是,我现在手头的主板只有一个Asus B460M,只有一个PCIE x16和两个 PCIE x1。保留 PCIE x16给显卡的情况下,没有办法再接 10Gbe,所以暂时先搁置这个 Infra/Application 分开的方案。