我的设置说明:
vm 存储的存储系统:supermicro 服务器,1 插槽 Xeon E5-2620 v4,基于 82599ES-intel 的 RA-Link 10GE 网络适配器,8x pci-e 2.0,插入 8x pci-e 3.0 插槽,debian 11
虚拟机托管的计算节点:supermicro 服务器,2 插槽 Xeon Silver 4216,与上述相同的适配器、pci-e 配置和操作系统。
BIOS 设置为性能模式,作为操作系统中的 CPU 调节器,所有漏洞缓解措施均被关闭。
我省略了存储配置,因为如果在服务器之间共享基于 RAM 的磁盘,情况是相同的。因此,最终测试配置是两台服务器上的 30GB RAM 磁盘,测试使用 fio 进行。
问题:在两台服务器上,我都获得了数百万的 iops,因为它位于 RAM 磁盘上,通过 10G 网络,在 4k 块大小上,我被困在 60-80k 的写入 iops 和 80-100k 的读取 iops 上,都是随机的。基于 NFS/ISCSI - 没关系,作为同步/异步模式。我在 Google 上搜索了所有针对 10G 的实际内核调整,ethtool 正在播放,它没有带来任何重大变化。基于 Linux 的网络堆栈或基于 openvswitch - 结果相同。RX/TX pps 在 4k 块大小 fio 上显示 ~40k/50k。驱动程序是默认内核 ixgbe。
如果我使用 16-32-64k 块大小进行测试或进行顺序读取/写入,它将完全饱和单个 10G 链路,大约 1050-1100 mbytes/s,而 4k 块大小则为 320-380 mbytes/s。测试期间的 CPU 负载约为 40% 或更低。
Fio:fio --randrepeat=1 --size=30G --name=fiotest --filename=testfio2 --numjobs=32 --stonewall --ioengine=libaio --direct=1 --bs=4k --iodepth=128 --rw=randread
主机系统和虚拟机内部的结果相同。
当前的 sysctl 调整:
- net.core.rmem_max = 67108864
- net.core.wmem_max = 67108864
- net.core.netdev_max_backlog = 30000
- net.ipv4.tcp_rmem = 4096 87380 33554432
- net.ipv4.tcp_wmem = 4096 65536 33554432
- net.ipv4.tcp_congestion_control=htcp
- net.ipv4.tcp_mtu_probing=1
- net.core.default_qdisc = fq
- net.ipv4.tcp_slow_start_after_idle=0
- 网.ipv4.tcp_sack=0
- net.ipv4.tcp_low_latency=1
- net.ipv4.tcp_timestamps=0
- net.ipv4.tcp_no_metrics_save=1
我没有提到巨型帧和其他显而易见的东西(是的,1500 或 9000 mtu 会产生相同的结果)。
通过 10G 交换机和服务器之间直接测试。存储设置本身可以在 4k 随机块上提供大约 300k iops(预热后,4 个 sas HDD 上的 raid10 + raid10 4 sas ssds 上的 lvm 缓存)。
现在我没什么主意了。如果我理解正确的话,10G 网络可以提供大约 250-300k iops 的等效值,但我在 4k 块上只有 60-100k 的随机写入/读取。
我错过了什么?
答案1
您正在使用 iowaits 饱和 PCIe 总线,不要看 CPU 负载。
40g 或 100g 会有点帮助:您的问题是延迟。
在没有 RDMA 或卸载或类似功能的情况下,您永远无法接近通过 NIC 执行 4k 随机读/写操作的顺序速度。