virtio 半虚拟化驱动对 VPS 性能的影响:网卡与磁盘为什么差那么多
2026-08-15 · DevCraft Studio
通俗讲清 virtio-net、virtio-blk、virtio-balloon 等半虚拟化驱动如何决定 VPS 的磁盘 I/O 与网络吞吐,对比 e1000/IDE 模拟设备的性能差距,并教你在 Linux 里检查驱动是否生效。
结论先说在前面:两台配置看起来一样的 VPS,跑 YABS 或者 fio 时分数能差好几倍,很多时候不是超售、也不是 CPU 缩水,而是磁盘和网络用的是不是 virtio 半虚拟化驱动。用 e1000 模拟网卡、IDE 模拟硬盘的老方案,网络吞吐和磁盘 IOPS 都被"模拟开销"拖了后腿;换成 virtio-net、virtio-blk 之后,延迟和吞吐通常能提升数倍,CPU 占用还更低。下面把原理、实测差距、还有怎么在机器里自查,一次讲清楚。
延伸阅读
更多相关攻略推荐:Ollama AI系列(2):VPS上的AI推理与API应用、Ollama AI系列(2):VPS上的AI推理与API应用、【CPU选型 01】搭载 AMD Ryzen 9950X 的 VPS、ARM / Ampere 席卷 VPS:性价比真香还是兼容陷阱?、Ollama AI系列(2):VPS上的AI推理与API应用。
一、什么是半虚拟化:virtio 比纯软件模拟(e1000/IDE)快在哪
在 KVM/QEMU 这类虚拟化里,VPS 看到的"网卡"和"硬盘"其实都是宿主机用软件模拟出来的。最省事的做法是完整模拟一套真实硬件:比如网卡模拟成 Intel E1000,硬盘控制器模拟成老式 IDE(PIIX4)。好处是 Windows、老内核这类系统自带这些标准硬件的驱动,开箱即用,不用额外装任何东西。
但代价很大。每一次 I/O 操作,Guest 里那个驱动都认为自己在和真硬件说话,于是去访问一堆 I/O 端口和寄存器,宿主机里的 QEMU 就得一次次拦截(这叫 VM Exit),翻译成对真实设备的操作,再回写结果。一次网络发包可能要进出虚拟机好几次,上下文切换极多,CPU 被白白烧掉。
半虚拟化(paravirtualization)换了个思路:它让 Guest 内核"知道"自己跑在虚拟机里,专门装一套 virtio 驱动,和宿主机之间用一块共享内存环形队列(virtqueue / vring)直接递交请求。前端驱动把数据放进 ring,写一次寄存器通知宿主机,宿主机后端一次性批量处理。这样 VM Exit 次数从"每个包一次"降到"一批一次",开销骤减。
virtio 这套标准最早由 Rusty Russell 为他的 lguest 项目设计,后来被 KVM、QEMU、Xen、VMware 广泛采用,已经成为事实上的半虚拟化接口标准。它把设备分成前后端:前端驱动在 Guest 内核里(如 virtio_net、virtio_blk),后端在宿主机的 QEMU 或内核模块里,中间靠统一的 virtqueue 传输协议连接。现代 Linux 发行版(Ubuntu、Debian、CentOS、Fedora 等)内核都自带这些驱动,所以新开 Linux VPS 一般会自动用上。
一句话总结差异:e1000/IDE 是"Guest 以为在开真车,其实每一步都要翻译",virtio 是"Guest 和宿主机说同一种语言,直接走专用通道"。
二、virtio-net 与 virtio-blk:网络和磁盘的实测差距
说原理太虚,直接看量级。下面这些数字来自多个基准测试整理的公开数据,具体数值会随宿主机 CPU、SSD 型号、网卡和网络拓扑变化很大,但数量级的差距是普遍存在的,请把它当成"大概区间"而不是精确结论。
| 设备类型 | 网络吞吐(约) | 磁盘顺序读写(约) | 随机 4K IOPS(约) | CPU 占用 |
|---|---|---|---|---|
| E1000 模拟网卡 | 2-3 Gbps | 不适用 | 不适用 | 高(可达 80% 以上) |
| virtio-net | 10-25 Gbps 区间 | 不适用 | 不适用 | 低 |
| IDE 模拟硬盘 | 不适用 | 200-400 MB/s | 数万级 | 高 |
| virtio-blk | 不适用 | 可达数 GB/s(近 NVMe) | 数十万到近百万级 | 低 |
网络侧,virtio-net 相对 e1000 通常被引用为 3 到 10 倍的吞吐提升。更重要的往往是延迟和 CPU:一份常见基准里,e1000 跑满时宿主机 CPU 能到 85%,而 virtio-net 同吞吐下只有 30% 左右。还有个厉害的开关叫 vhost-net——它把网络数据通路从 QEMU 用户态卸载到宿主机内核态,数据包直接穿透 QEMU,进一步省掉一次数据拷贝,单台 VM 轻松上 10 Gbps。
磁盘侧,virtio-blk 相对 IDE 模拟通常被引用为 2 到 5 倍提升。用 fio 跑 4K 随机读写最能拉开差距:同样是后端 NVMe,裸金属随机读约 98 万 IOPS,virtio-blk 直通(raw/LVM 卷)约 78 万(约 80%),而用 qcow2 文件镜像会掉到约 55%。随机读延迟 virtio 方案常见 0.1ms 上下,IDE 模拟能到 0.8ms 以上。差距在数据库、小文件密集的场景会被放大。
另外两个能再榨性能的点:一是多队列(multiqueue),让每个 vCPU 有独立的收发队列,避免所有 I/O 挤在一条队列上;二是卸载特性(TSO/GSO/GRO 等),把分段、校验和这类活从 CPU 挪给网卡处理。ethtool -k 能看到它们是否开启。
补充一句:virtio-blk 走单队列、最简单快,Guest 里盘符是 /dev/vda;virtio-scsi 功能更全(支持更多盘、TRIM、热插拔、SCSI 指令),开销略高一点。日常 VPS 用 virtio-blk 就够了。
三、virtio-balloon 内存气球:OOM 其实是被回收
virtio-balloon 是另一个常被忽略的 virtio 设备,它管的是"内存气球"。宿主机可以通过它向 Guest 借内存、也可以还回去: inflation(充气)是 Guest 把一部分内存交还给宿主机,deflation(放气)是宿主机把内存还回来。
对 VPS 用户来说,这个机制既能省钱(内存超卖、按需分配),也藏着坑。当你在机器里看到内存突然变少、甚至进程被 OOM Killer 杀掉,根因可能不是你真的内存泄漏,而是宿主机把气球充得太狠,Guest 内核感受到内存压力,自己触发了 OOM。
内核里有个细节:现代 virtio-balloon 支持"deflate on OOM"特性(VIRTIO_BALLOON_F_DEFLATE_ON_OOM),意思是 Guest 真要 OOM 时,气球会先放点气来缓解,而不是眼睁睁看着进程被杀。但这个特性在历史上改过几次实现(早期用 OOM notifier,中间一度换成 shrinker,后来 Red Hat 的 David Hildenbrand 又改回 OOM handler),行为并不总如你预期。
所以实用的建议是:在用了内存气球的 VPS 上,一定要留一点 swap(哪怕 512MB 到 1GB),给 Guest 一点缓冲,气球充得太狠时先换页而不是立刻 OOM。另外别把 balloon 当超售的借口无限压——业务真的吃内存时,最稳的还是买够配置或选明确不超售的方案。
四、在 Linux 里确认驱动是否生效(lspci/ethtool/lsblk)
光看厂商宣传没用,自己上机查最实在。下面命令都在 VPS 内部执行,不需要宿主机权限。
第一步,看内核模块有没有加载:
lsmod | grep virtio
正常会看到 virtio_net、virtio_blk、virtio_pci、virtio_ring 等。如果列表里压根没有 virtio_net,那网络大概率没走半虚拟化。
第二步,看 PCI 设备是什么型号:
lspci -nnk | grep -i virtio
输出里出现 "Red Hat, Inc. Virtio network device" 和 "Virtio block device" 就说明设备本身是 virtio 的。
第三步,确认网卡驱动:
ethtool -i eth0
把 eth0 换成你的网卡名。driver 字段应是 virtio_net 才对。还可以用 ethtool -k eth0 看 TSO/GRO 等卸载开关状态。
第四步,看磁盘是不是 virtio-blk:
lsblk
盘符以 vd 开头(比如 vda、vdb)而不是 sd 或 hd,基本就是 virtio 块设备了。再用 dmesg | grep -i virtio_blk 应能搜到加载记录。
如果这些命令显示的是 e1000、Intel Corporation 82545EM、或者 /dev/sda 配 IDE,那就是还在用模拟设备,性能吃亏。Linux 下切换到 virtio 通常不难(现代内核自带驱动),但改系统盘类型前记得先把 virtio 模块打进 initramfs(Debian/Ubuntu 用 update-initramfs,RHEL/CentOS 用 dracut),否则可能开不了机。
五、选购与重装注意:Windows VPS 必须装 virtio 驱动
上面说的"Linux 自带 virtio 驱动"在 Windows 上不成立。Windows 内核没有内置 virtio 驱动,所以当你在 KVM 上开一台 Windows VPS,如果磁盘控制器设成 virtio-blk/virtio-scsi,Windows 安装程序启动时根本认不到硬盘,会报"找不到任何驱动器"。
解决办法是加载 Fedora 维护的 virtio-win 驱动(ISO 形式,含 viostor 磁盘驱动、NetKVM 网卡驱动、vioscsi 等)。安装时通过加载驱动程序(inst.dd 或图形界面"加载驱动")把 viostor 加进去,装完系统后再补上网卡等驱动。很多商家在后台提供了"VirtIO 驱动"开关或预装的镜像,重装系统时务必确认这项是开的,否则要么认不到盘装不下去,要么装完没网卡。
选购 VPS 时也可以多问一句磁盘和网络用的什么模型。对 KVM 系的 Linux VPS,virtio 基本是默认;但一些老模板、或者为了兼容 Windows 临时切到 IDE/e1000 的,性能会明显打折。如果你买来之后跑分发现网络和磁盘异常低,先按第四节自查驱动,往往比纠结"是不是超售"更先找到真因。
#virtio #VPS性能 #半虚拟化 #KVM #磁盘IO