多队列virtio-net

多队列 virtio-net

多队列 virtio-net 提供了随着虚拟 CPU 数量增加而改变网络性能的方法,即允许每一次通过一组以上的 virtqueue 传输数据包。

在单一队列的 virtio-net 中,客机中协议堆叠的缩放收到限制,因为网络性能不随虚拟 CPU 数量的增加而改变。鉴于 virtio-net 只有一组 TXRX 队列,客机不能并行传输或检索数据包。

多队列 virtio-net 在这些时候可以提供最佳性能:

  • 流量数据包相对较大

  • 客机同时在各种连接中活跃,流量从客机、客机到主机或客户端运行到外部系统。

    队列数量与虚拟 CPU 相同。因为多队列支持可以优化 RX 中断关联和 TX 队列选择,实现特定队列对于特定虚拟 CPU 的私有化。

注意

多队列 virtio-net 在输入流量中运行良好,但在少数情况下可能会影响输出流量的性能。启用多队列 virtio-net 提高总体吞吐量,同时提高 CPU 可用量。

配置多队列 virtio-net

  • 物理NC服务器

使用多队列 virtio-net 时,通过向虚拟机 XML 配置(N 的值为 1 到 8,即 kernel 最多可支持一组多队列 tap 设备中的 8 个队列)添加以下命令:

<interface type='network'>
      <source network='default'/>
      <model type='virtio'/>
      <driver name='vhost' queues='N'/>
</interface>

虚拟机需要关闭再使用多队列virtio皮质启动才能生效

  • KVM guest虚拟机操作

在虚拟机内部执行以下命令(M 的值为 1 到 N)时允许多队列支持:

# ethtool -L eth0 combined M

-L --set-channels - 设置指定网络设备的通道数量(the numbers of channels)

实践

  • 在没有设置virtio-vhost多队列之前,通过ps aux | grep vhost可以看到对应虚拟机vm-1vhost只有2个进程(单队列有一个收网络包的进程和一个发网络包进程)(当前虚拟机qemu进程号是17060

root     17061  0.0  0.0      0     0 ?        S    10:48   0:00 [vhost-17060-0]
root     17062  0.0  0.0      0     0 ?        S    10:48   0:00 [vhost-17060-1]
  • 将运行中的虚拟机配置导出

virsh dumpxml vm-1 > vm-1.xml
  • 修改vm-1.xml配置文件,在虚拟网卡配置段落的<model type='virtio'/>下面添加一行<driver name='vhost' queues='4'/>

<interface type='network'>
...
      <model type='virtio'/>
      <driver name='vhost' queues='4'/>
...
</interface>
  • 然后启动虚拟机

virsh create vm-1.xml
  • 此时再次ps aux | grep vhost可以看到这个虚拟机现在有了4个队列对应的8个vhost进程(当前虚拟机qemu进程号是61912

root     61913  0.0  0.0      0     0 ?        S    11:12   0:00 [vhost-61912-0]
root     61914  0.0  0.0      0     0 ?        S    11:12   0:00 [vhost-61912-1]
root     61915  0.0  0.0      0     0 ?        S    11:12   0:00 [vhost-61912-0]
root     61916  0.0  0.0      0     0 ?        S    11:12   0:00 [vhost-61912-1]
root     61917  0.0  0.0      0     0 ?        S    11:12   0:00 [vhost-61912-0]
root     61918  0.0  0.0      0     0 ?        S    11:12   0:00 [vhost-61912-1]
root     61919  0.0  0.0      0     0 ?        S    11:12   0:00 [vhost-61912-0]
root     61920  0.0  0.0      0     0 ?        S    11:12   0:00 [vhost-61912-1]
  • 登录到虚拟机内部,在虚拟内部没有启用多队列之前检查网卡

# ethtool -L eth0
no channel parameters changed, aborting
current values: tx 0 rx 0 other 0combined 1

使用ethtool -l eth0可以看到

# ethtool -l eth0
Channel parameters for eth0:
Pre-set maximums:
RX:        0
TX:        0
Other:        0
Combined:    4
Current hardware settings:
RX:        0
TX:        0
Other:        0
Combined:    1

-l --show-channels - 查询指定网络设备具有的通道数量。所谓通道(channel)就是一个IRQ和可以触发IRQ的队列集。

  • 虚拟机设置多队列支持

# ethtool -L eth0 combined 2

如果没有在物理服务器上设置好多队列支持,会提示错误Cannot set device channel parameters: Invalid argument

此时再次检查可以看到虚拟网卡硬件设置队列数是2

# ethtool -l eth0
Channel parameters for eth0:
Pre-set maximums:
RX:        0
TX:        0
Other:        0
Combined:    4
Current hardware settings:
RX:        0
TX:        0
Other:        0
Combined:    2

最多可以设置4个多队列(和物理服务器上设置对应)

# ethtool -L eth0 combined 4

# ethtool -l eth0
Channel parameters for eth0:
Pre-set maximums:
RX:        0
TX:        0
Other:        0
Combined:    4
Current hardware settings:
RX:        0
TX:        0
Other:        0
Combined:    4
  • 验证多队列生效的方法是观察中断,即cat /proc/interrupts

# cat /proc/interrupts
           CPU0       CPU1
...
 27:       1352          0   PCI-MSI-edge      virtio0-input.0
 28:          1          0   PCI-MSI-edge      virtio0-output.0
 29:        378          0   PCI-MSI-edge      virtio0-input.1
 30:          1          0   PCI-MSI-edge      virtio0-output.1
 31:        151          0   PCI-MSI-edge      virtio0-input.2
 32:          1          0   PCI-MSI-edge      virtio0-output.2
 33:        268          0   PCI-MSI-edge      virtio0-input.3
 34:          0          0   PCI-MSI-edge      virtio0-output.3

可以观察到中断分布到4个virtio0队列设备上。

参考

Last updated