vhost-net 是什么
vhost-net 把 virtio 网卡的数据面从用户态搬到内核:宿主内核线程(表现为 vhost-<pid>)直接处理虚机的收发队列,省去一次上下文切换与内存拷贝,是提升虚机网络吞吐、降低 CPU 占用的常用优化。域定义里把网卡 driver 写为 vhost 即启用;写成 qemu 则回退到用户态处理,抓包与调试更方便。
基本信息
| 内核模块 | vhost_net(lsmod | grep vhost) |
|---|---|
| 域侧声明 | <driver name='vhost'/> |
| 对照模式 | name='qemu' 走用户态,便于调试 |
| 判断生效 | 宿主进程列表中可见 vhost-<pid> 内核线程 |
| 配合项 | 队列数(queues)与多队列设置一起生效 |
典型使用场景
- 虚机网络吞吐成为瓶颈,需要降低单包处理开销
- 宿主 CPU 被虚机网络软中断大量占用,需要优化
- 与多队列配合,把收发压力分摊到多个内核线程
- 迁移到高性能内网规格后复核网络数据面配置
- 排查网络异常时临时切回用户态模式对比表现
检查与声明
检查与声明
lsmod | grep -E 'vhost(_net)?' # 确认模块已加载
virsh dumpxml vm1 | grep -A4 '<interface' # 查看网卡驱动的 name 与 queues
# 期望片段:<driver name='vhost' queues='4'/>
ps -ef | grep -c '\[vhost-' # 宿主上的 vhost 内核线程数
ethtool -L eth0 combined 4 # guest 内侧队列数要与域定义匹配项目与表现
| 项目 | 正常表现 | 说明 |
|---|---|---|
| 内核模块 | vhost_net 已加载 | 模块缺失时启用 vhost 会启动失败 |
| vhost 线程 | 宿主上存在 vhost-<pid> 线程 | 没有线程说明实际未走内核加速 |
| driver name | 域定义中为 vhost | 写 qemu 时退回用户态处理 |
| 队列数 | 域定义与 guest 设置一致 | 只改一侧无效 |
| 对照模式 | 可切回 qemu 做抓包对比 | 排查网络问题时使用,不要长期保留 |
与 vhost-user/DPDK 方案不同,vhost-net 无需额外数据面进程,适合常规业务;追求极致吞吐的场景才考虑用户态数据面。
vhost-net 的收益依赖队列数配置:单队列时优化有限,通常要配合多队列与足够的 vCPU 才能看到明显提升。
优化网络前建议先定位瓶颈:用 iperf 类工具测虚机间与虚机到宿主的吞吐,再对比宿主 CPU 的软中断占用,确认瓶颈确实在数据面路径上,避免做无效改动。