将LUN直接挂载至KVM虚拟机后IOPS大幅降低的排查求助
问题背景
我部署了一台KVM主机,基于multipath存储池配置了多个Compellent SAN LUN,所有文件系统均为XFS。其中一个LUN挂载到/var/lib/libvirt/images存放虚拟机镜像,其余LUN计划直接透传给虚拟机存储邮件及元数据。
存储池卷列表:
virsh vol-list --pool multipathdm-3 /dev/mapper/maildata-store-2-repl
dm-4 /dev/mapper/maildata-store-1-back
dm-5 /dev/mapper/metadata-store-2-repl
dm-6 /dev/mapper/metadata-store-1-back
dm-7 /dev/mapper/images
镜像存储LUN挂载状态:
# df /dev/mapper/images1 Sys. de fichiers blocs de 1K Utilisé Disponible Uti% Monté sur /dev/mapper/images1 209611780 18752452 190859328 9% /var/lib/libvirt/images
用fio做随机写测试(命令如下),虚拟机内镜像存储目录的结果很好:
fio --randrepeat=1 --ioengine=libaio --direct=1 --gtod_reduce=1 --name=test --filename=/tmp/10g.file --bs=4k --iodepth=64 --size=4G --readwrite=randwrite
write: IOPS=66.1k, BW=258MiB/s
但通过以下XML把maildata-store-1-back LUN透传给VM_TEST虚拟机后:
<disk type='block' device='lun'> <driver name='qemu' type='raw'/> <source dev='/dev/mapper/maildata-store-1-back'/> <target dev='sda' bus='scsi'/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk>
执行virsh attach-device VM_TEST --file lun.xml --persistent,在虚拟机内完成分区、格式化、挂载后,同样的fio测试结果骤降:
write: IOPS=17.6k, BW=68.7MiB/s
尝试调整cache=none、bus=virtio等参数后无明显改善,以下是几个值得排查的方向:
具体排查方向
1. 多路径配置一致性检查
首先要确认直挂LUN的multipath配置和镜像存储LUN是否一致,毕竟镜像LUN的性能是正常的。
- 用
multipath -ll /dev/mapper/maildata-store-1-back查看该LUN的多路径配置,对比/dev/mapper/images的输出,重点看路径数量、负载均衡策略(比如rr轮询的queue-length参数)、path_checker设置。 - 登录Compellent SAN控制台,检查这个LUN的路径配置:是否启用了多路径、路径优先级是否合理、是否有链路故障导致只有单路径工作。
2. 优化KVM磁盘透传的底层配置
默认的SCSI控制器和磁盘参数可能不是最优的,试试这些调整:
- 切换到
virtio-scsi控制器:virtio-scsi相比传统SCSI控制器在高IO深度下性能更出色。需要先在虚拟机XML中添加控制器,再修改磁盘配置:<controller type='scsi' index='0' model='virtio-scsi'/> <disk type='block' device='lun'> <driver name='qemu' type='raw' cache='none' io='native'/> <source dev='/dev/mapper/maildata-store-1-back'/> <target dev='sda' bus='scsi'/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> - 验证
io='native'是否生效:这个参数让QEMU直接使用主机的IO引擎,减少中间层开销。可以用virsh domblklist VM_TEST --details查看磁盘的IO模式。
3. 隔离存储层与虚拟机层的问题
先在KVM主机上直接测试LUN的性能,排除虚拟机层的干扰:
fio --randrepeat=1 --ioengine=libaio --direct=1 --gtod_reduce=1 --name=host_test --filename=/dev/mapper/maildata-store-1-back --bs=4k --iodepth=64 --size=4G --readwrite=randwrite
- 如果主机上的测试结果同样差,那问题肯定在存储层(SAN配置、多路径、链路故障);
- 如果主机上结果正常,再把注意力放回虚拟机内部和KVM配置。
4. 虚拟机内的IO优化
虚拟机内部的配置也可能拖后腿:
- 确认安装了
libaio库:fio的libaio引擎依赖这个库,CentOS/RHEL安装libaio-devel,Debian/Ubuntu安装libaio-dev。 - 优化XFS挂载参数:添加
noatime,nodiratime减少元数据写入,调整日志缓冲区参数(比如logbufs=8、logbsize=256k):mount -o noatime,nodiratime,logbufs=8,logbsize=256k /dev/sda1 /test - 调整IO调度器:对于SAN/SSD存储,推荐使用
mq-deadline或none调度器,避免不必要的IO排队:echo mq-deadline > /sys/block/sda/queue/scheduler
5. 检查QEMU进程的资源限制
KVM主机上的QEMU进程如果资源受限,也会影响IO性能:
- 用
top/htop查看QEMU进程的CPU使用率,如果测试时CPU跑满,可能需要调整虚拟机的CPU配置(比如增加vCPU、开启CPU passthrough),或者检查cgroup是否限制了CPU资源。 - 查看QEMU日志(通常在
/var/log/libvirt/qemu/VM_TEST.log),看看有没有IO相关的错误或警告信息,比如路径权限问题、IO超时等。
内容的提问来源于stack exchange,提问作者Is ma Live

