业务高峰时,16个 virtio-scsi 队列同时压向4条后端路径,虚机吞吐从 1.2GB/s 跌到 600MB/s,p99 延迟从 2ms 跳到 40ms。重启虚机偶尔能恢复,监控却只显示“设备繁忙”。此时该查虚机、驱动,还是底层阵列?必须沿着虚拟磁盘到宿主机存储的请求路径逐层判断。
如果你正在选机器,或者想先把线路和配置跑通再谈长期方案,可以先看看这几家的线路说明和技术参数:ethernetservers(全球云服务器),先看清带宽线路、流量策略和退款条款,再决定要不要迁。
一、请求如何从虚拟磁盘走到物理介质
guest 内的块请求先进入 virtio-scsi队列机制:每个 virtqueue 保存描述符、状态位和中断通知信息。宿主机驱动取走描述符后,将其转换成 SCSI 命令,再交给宿主块层。设备通知可能合并,但 virtqueue 中待处理请求并不会因此消失,队列持续积压就会推高延迟。

多队列并发映射并非“队列越多越快”。虚机 vCPU、virtqueue、宿主中断和后端路径之间存在对应关系。若多个队列集中到同一 NUMA 节点、同一 CPU 或同一控制器队列,就会出现锁竞争和跨节点访问;反之,空闲队列与繁忙队列分布失衡,也会浪费并发能力。
请求继续下沉为 bio,经过合并、调度和驱动映射,最终由 HBA 写入阵列缓存或磁盘。块设备持久化边界由 FLUSH、FUA 及设备写缓存决定:普通写入返回成功,不代表介质已经持久化,突然断电仍可能丢失尚未落盘的数据。
二、用分段基线找出掉速位置
判断时不要只看 iostat 的 %util。满负载设备可能仍有很高吞吐,而低利用率设备也可能因单次长尾延迟拖垮虚机。应先固定块大小、队列深度和读写比例,用 fio 分别测试 iodepth=1 与 iodepth=32,再与裸盘、同宿主其他虚机及后端阵列基线比较。

随后执行宿主机存储栈排障:查看 virtqueue 长度、宿主机块层等待时间、HBA 队列深度及中断分布,用 perf、blktrace 和 irq 软中断统计确认 CPU 是否成为瓶颈;若多路径环境启用,再检查 multipath 路径状态与策略。ServLlama 可用于汇总虚机、宿主机和阵列侧的时序证据,避免只截取某一时刻的告警。
常见踩坑有三个:把平均延迟当尾延迟,把应用 fsync 延迟全算到磁盘,或在开启设备写缓存时把 ACK 当作持久化完成。正确做法是同时记录吞吐、p95/p99、队列深度、重置次数和路径切换事件,再判断瓶颈位于 guest、virtio 通知、宿主调度、设备队列还是后端介质。
队列并发如何映射到宿主机设备
virtio-scsi 的 I/O 请求先进入 guest 的 virtqueue;后端依据 vring 中的描述符建立地址、长度和读写方向,再把请求转换成宿主机块层命令。多队列并不等于多块盘:队列号只是并发通道,同一 LUN 的请求仍可能共享 SCSI 目标、HBA 队列及设备控制器。调整队列数后要同时核对 IRQ affinity、后端线程绑定和 vCPU 拓扑,否则请求只是从 guest 转移到 host 队列,未必缩短设备服务时间。
中断模式下,前端通过 eventfd 通知后端,处理完成再回推完成队列;轮询模式则减少唤醒,却会占用 CPU,并可能在设备变慢时形成轮询尖峰。观察延迟时应区分“请求进入队列等待”与“设备实际执行”:前者常由队列过深、CPU 软中断或锁竞争造成,后者才指向 HBA、介质、固件和温控。

沿存储栈定位抖动与写丢失
排障按 guest 虚拟块设备、virtio 后端、宿主机块层、SCSI/HBA、驱动与设备固件逐层切开。可在 guest 用 iostat、fio 记录 await、%util、fsync 延迟,在 host 对照 blktrace、/proc/interrupts、scsi_stats、multipath 与 dmesg;若同一时间只有 guest 抖动,多半是队列或虚拟化层问题,若 host 队列和服务时间同步升高,则继续查控制器、路径切换、后台任务及设备介质。不要只看平均延迟,还要关注 p99/p999、队列深度和超时重置。
常见误区是把宿主机缓存命中当作端到端低延迟,或用在线读写验证断电保护。写缓存为 write-back 时,FLUSH/FUA、虚拟化后端是否透传,以及 HBA 是否带掉电保护缓存,决定数据在何处落地;快照、thin provisioning 和 RAID 也不等于独立备份。掉电测试应使用可丢弃环境,并核对设备掉电保护状态、UPS 与备份策略。
可执行检查清单:① guest 确认 virtio 队列数、队列映射与 IRQ 亲和;② 分别采样 guest 和 host 的队列深度、利用率及尾延迟;③ 对照 SCSI/HBA 重试、超时、路径切换和固件事件;④ 验证 FLUSH/FUA 透传、掉电保护缓存与文件系统 barrier;⑤ 在压测中执行真实 fsync,再做受控断电与恢复校验;⑥ 固化基线、告警阈值和回滚配置。只有虚拟盘、宿主路径、持久化介质三层同时闭环,才能判断瓶颈并确认数据边界。


喜欢
顶
难过
囧
围观
无聊





