上一篇 下一篇 分享链接 返回 返回顶部

如何在香港服务器上跑 Windows Server 2022 时,把 Hyper-V 虚拟交换机的性能“掰直”?

发布人:Minchunlin 发布时间:2025-08-30 10:03 阅读量:717


那天晚上是香港葵涌机房最常见的闷热潮湿。机柜风从脚下往上灌,像一股带着盐味的热浪。我蹲在42U机柜前,盯着一台托管的 2U 服务器:两张 25GbE,32 核 CPU,内存 256GB,Windows Server 2022 Datacenter + Hyper-V。几台北向 VM 做边界转发,几台东西向 VM 跑分布式缓存。业务刚从广州回源到香港,峰值流量贴着 40Gbps,虚机里延迟抖成锯齿,宿主机 CPU 的 0 号核被打到 100%,而其他核像在放假。值夜的小哥看我抬头,他问:“是不是 vSwitch 又在卡?”
我没回,就把随身的小凳子往机柜一塞,开干。

一、环境与目标(Baseline & Goal)

硬件/软件基线

配置
机型 双路 2U(2× Intel Xeon Gold,32C/64T 总计)
内存 256GB DDR4
NIC 2× 25GbE:Mellanox ConnectX-4 Lx(RoCEv2),固件 14.x;或 Intel E810 25G(视批次)
存储 2×NVMe(OS)+ 4×NVMe(数据盘)
OS Windows Server 2022 Datacenter, 最新补丁
虚拟化 Hyper-V,来宾系统混合(Windows/Linux)
机房 香港,ToR 支持 VLAN Trunk;PFC/DCB 不对客户开放(常见限制)

初始现象(未优化)

  • 同一宿主机 VM 间(东西向)平均吞吐仅 11–14Gbps,PPS(小包)不稳定;
  • 北向(经物理 NIC 出口)单 VM 吞吐 7–9Gbps;
  • 宿主机 CPU Core#0 100%,其余核心较空;
  • ping 抖动,偶发丢包;
  • Live Migration 偶尔把生产网“挤”出尖峰延迟。

优化目标

  • 东西向近线速(> 18Gbps/VM,合计逼近 25G 物理线速),小包稳定;
  • 北向单 VM > 15Gbps;
  • 让 CPU 负载均衡(RSS/vRSS/VMMQ 生效);
  • Live Migration/存储/管理业务互不抢网;
  • 有据可依,可复现,可回滚。

二、总体策略(一句话版)

用 SET(Switch Embedded Teaming)做外部 vSwitch,按“管理/存储/迁移/业务”拆 Host vNIC;开启 SR-IOV(能用就用)、VMMQ/vRSS/RSS、RSC/LSO/Checksum Offload、合理的 VMQ 核亲和与 VLAN 规划;以权重 QoS 管理带宽;能走 Jumbo 就全链路走;有 RDMA 环境就开 vSwitch RDMA,没有就规避半拉子配置。

三、网络拓扑与规划(先画草图再敲命令)

规划四张 Host vNIC(宿主机虚拟网卡):

逻辑网 用途 VLAN QoS 权重 备注
vMgmt 管理 10 10 RDP/运维,仅少量流量
vLM Live Migration 20 20 迁移时会打满,需权重
vSMB 存储/备份(SMB) 30 30 若机房允许 DCB/PFC,可做 RDMA
vProd 生产数据面 Trunk(100–199) 40 VM 的主要业务流量

注意:香港很多托管机房不开放 DCB/PFC,即便 NIC 支持 RoCEv2,也不要半开半关。要么全链路 RDMA(ToR/上联/端到端都通),要么干脆别开 RDMA。

四、逐步落地(PowerShell 实操)

4.1 驱动/固件一致性与 NIC 基线

先做这一步,后面所有优化才不白费。

# 查看适配器与驱动
Get-NetAdapter | Format-Table Name, InterfaceDescription, Status, LinkSpeed
Get-NetAdapterAdvancedProperty -Name "NIC1","NIC2"

# 开启常见 offload(先看默认,通常不用关闭)
Enable-NetAdapterChecksumOffload -Name "NIC1","NIC2"
Enable-NetAdapterLso -Name "NIC1","NIC2"
Enable-NetAdapterRsc -Name "NIC1","NIC2"

# 开启 RSS(物理 NIC)
Enable-NetAdapterRss -Name "NIC1","NIC2"
Get-NetAdapterRss -Name "NIC1" | Format-List *

坑 1: 有些批次的 Mellanox/Intel 驱动与固件不匹配,会导致 VMQ/VMMQ 状态异常或队列数异常偏少。先升到厂商推荐“配套版本”。

4.2 用 SET 创建外部 vSwitch(别再用 LBFO)

Windows Server 2022 上,给 vSwitch 做汇聚,官方推荐 SET;LBFO 虽在,但不支持 vSwitch 的很多新特性。

$uplinks = @("NIC1","NIC2")

# 建 SET + External vSwitch,关闭 AllowManagementOS(我们手动建 Host vNIC)
New-VMSwitch -Name "vSwitch-SET-Prod" `
  -NetAdapterName $uplinks `
  -EnableEmbeddedTeaming $true `
  -AllowManagementOS $false `
  -EnableIov $true `
  -BandwidthReservationMode Weight

# SET 默认是 Switch-Independent + Dynamic 负载分担,满足大多数托管场景
Get-VMSwitchTeam -Name "vSwitch-SET-Prod"

坑 2: SET 不支持 LACP(多数 ToR 也不愿跟客户做 LACP),所以保持 Switch-Independent 最稳。

4.3 划分宿主机虚拟网卡(Host vNIC)+ VLAN + QoS

# 宿主机 vNIC:分别挂到同一 vSwitch
$hostVnics = @(
  @{Name="vMgmt"; VLAN=10;  Weight=10},
  @{Name="vLM";   VLAN=20;  Weight=20},
  @{Name="vSMB";  VLAN=30;  Weight=30},
  @{Name="vProd"; VLAN=0;   Weight=40}   # vProd 设为 Trunk,后面单独开 Trunk
)

foreach ($n in $hostVnics) {
  Add-VMNetworkAdapter -ManagementOS -Name $n.Name -SwitchName "vSwitch-SET-Prod"
  if ($n.VLAN -gt 0) {
    Set-VMNetworkAdapterVlan -ManagementOS -VMNetworkAdapterName $n.Name -Access -VlanId $n.VLAN
  }
  Set-VMNetworkAdapter -ManagementOS -Name $n.Name -MinimumBandwidthWeight $n.Weight -VrssEnabled $true
}

# vProd 改为 Trunk(宿主机需要跑多 VLAN 的场景)
Set-VMNetworkAdapterVlan -ManagementOS -VMNetworkAdapterName "vProd" -Trunk -NativeVlanId 100 -AllowedVlanIdList "100-199"

# 为 Host vNIC 配置 IP(例)
New-NetIPAddress -InterfaceAlias "vEthernet (vMgmt)" -IPAddress 10.0.10.11 -PrefixLength 24 -DefaultGateway 10.0.10.1
New-NetIPAddress -InterfaceAlias "vEthernet (vLM)"   -IPAddress 10.0.20.11 -PrefixLength 24
New-NetIPAddress -InterfaceAlias "vEthernet (vSMB)"  -IPAddress 10.0.30.11 -PrefixLength 24
# vProd 可能做子接口或由上层路由/VRF 管

坑 3: VLAN Trunk 经常出错。宿主机 vNIC 与 ToR 的 Native/Allowed 要一致。如果不确定,先 Access 跑通再 Trunk。

4.4 Jumbo Frame(全路径一致才算成立)

# 物理 NIC Jumbo(视 ToR 支持,常用 9014/9216)
Set-NetAdapterAdvancedProperty -Name "NIC1","NIC2" -DisplayName "Jumbo Packet" -DisplayValue "9014 Bytes"

# vNIC/来宾 OS 也要配(Linux 倾向 9000,Windows 8996/9014),务必全链路一致
# 验证 MTU:Windows
ping <对端IP> -f -l 8972

坑 4: 机房不少 ToR 对外口 MTU 只开到 9216,下游设备再叠加封装会超。用 ping -f -l 验 MTU 是最省事的办法。

4.5 vSwitch 侧 RSC(Receive Segment Coalescing)

# vSwitch 侧软件 RSC
Set-VMSwitch -Name "vSwitch-SET-Prod" -EnableSoftwareRsc $true
# 确认
Get-VMSwitch -Name "vSwitch-SET-Prod" | fl Name,EnableSoftwareRsc

RSC 能把小包拼大包,减主机 CPU 开销,尤其在小包 PPS 高的业务里有肉眼可见的收益。

4.6 RSS / vRSS / VMMQ:把流量“撒”到多核

# 物理 NIC 保证 RSS 打开
Enable-NetAdapterRss -Name "NIC1","NIC2"

# 查看 VMQ(物理队列)状态
Get-NetAdapterVmq -Name "NIC1","NIC2"

# 为高吞吐 VM 开 VMMQ(来宾多队列)
Set-VMNetworkAdapter -VMName "Edge-VM01" -Name "Ethernet" -VmmqEnabled $true -VmmqQueuePairs 16
Set-VMNetworkAdapter -VMName "Cache-VM01" -Name "Ethernet" -VmmqEnabled $true -VmmqQueuePairs 8

# vRSS(来宾内核里的 RSS)
Set-VMNetworkAdapter -VMName "Edge-VM01" -VrssEnabled $true
Set-VMNetworkAdapter -VMName "Cache-VM01" -VrssEnabled $true

坑 5: 看到 Core#0 100% 其实是 RSS 没生效或队列没撒开。
坑 6: 某些驱动默认 VMQ 队列过少,或“自动”分配到跨 NUMA 的核,需要手动给 BaseProcessor 做亲和。

# 例:将 NIC1 的 VMQ 基线绑到 CPU#8(避开 0 号核),给 12 个核
Set-NetAdapterVmq -Name "NIC1" -BaseProcessorNumber 8 -MaxProcessors 12
Set-NetAdapterVmq -Name "NIC2" -BaseProcessorNumber 20 -MaxProcessors 12

核心思想:把物理队列与 NUMA 对齐,避免跨 NUMA 来回搬数据。

4.7 SR-IOV:给极限型 VM 一把“直通快刀”

# vSwitch 已带 -EnableIov $true
Get-NetAdapterSriov

# 为边界转发型 VM 提高 IOV 权重
Set-VMNetworkAdapter -VMName "Edge-VM01" -Name "Ethernet" -IovWeight 100

提醒:

  • SET 下 SR-IOV 可用(取决于 NIC/BIOS/主板/IOMMU);
  • SR-IOV 下某些 vSwitch 功能(端口镜像、ACL、捕获)不可用;
  • 机房若做流量清洗或镜像,甄别是否需要 SR-IOV。

托管商常见限制:系统固件没开 VT-d/IOMMU、PCIe ACS 隔离不足、上游不让 PFC——这些会直接把 SR-IOV/ROCE“封死”。碰到就别死磕。

4.8 带宽治理(QoS):权重而非硬限优先

# vSwitch 已启用权重模式(BandwidthReservationMode=Weight)
# 我们之前给 Host vNIC 设了 Weight,这里给 VM 也设
Set-VMNetworkAdapter -VMName "Edge-VM01"  -MinimumBandwidthWeight 50
Set-VMNetworkAdapter -VMName "Cache-VM01" -MinimumBandwidthWeight 30
Set-VMNetworkAdapter -VMName "Misc-VM01"  -MinimumBandwidthWeight 10

# Live Migration 另行限速(避免挤生产)
Set-SmbBandwidthLimit -Category LiveMigration -BytesPerSecond 20000000000  # 20Gbps

五、验证与指标(用数据说话)

5.1 测试方法

  • 东西向:同宿主机两台 VM 间 iperf3/ntttcp,分别测大包/小包,多流;
  • 北向:VM→外部测试机(同 ToR 不同端口),保持单流/多流;
  • CPU:PerfMon 看 Processor(_Total)\% Processor Time、Interrupts/sec、Hyper-V Virtual Switch(*) 计数器;
  • 队列:Get-NetAdapterVmqQueue,确认队列散布与迁移。

5.2 样例结果(单宿主机)

优化前 vs 优化后

场景 指标 优化前 优化后
VM↔VM(同宿主机,大包) 吞吐 11–14 Gbps 20–23 Gbps
VM↔VM(同宿主机,小包 512B) PPS 抖动严重 稳定提升 ~35–60%
VM→北向(单 VM,多流) 吞吐 7–9 Gbps 15–18 Gbps
宿主机 Core#0 利用率 ~100% 20–40%(均摊到多核)
Ping 抖动 RTT 1–5ms 抖 < 0.8ms 稳定
迁移挤压 业务延迟尖峰 偶发 控制在可接受范围

这组数据是在 RSC + RSS + VMMQ 开启、Jumbo 9014 全链路打通、SR-IOV 对关键 VM 打开 的前提下测得。

六、典型“坑”与现场排障过程(真事儿)

Core#0 爆满
症状:业务延迟抖、丢包;
排查:Get-NetAdapterRss 显示已开启,但 Get-NetAdapterVmq 队列少且 BaseProcessor=0;
操作:给 NIC1/NIC2 分别设 BaseProcessor & MaxProcessors,让队列远离 0 号核并靠近对应 NUMA;同时打开 VMMQ/vRSS;
结果:Core#0 降到 30% 左右,吞吐/PPS 稳了。

“Jumbo 开了反而更差”
症状:吞吐忽高忽低;
排查:ToR 口 MTU=9216,但上游采集/清洗盒子分片阈值与 DSCP 政策冲突;
操作:协调网络侧统一链路 MTU,ping -f -l 8972 验证沿途无碎片;
结果:RSC 生效明显,小包场景稳定。

SR-IOV 打不开
症状:Get-NetAdapterSriov 显示不支持;
排查:BIOS 里 VT-d 关闭;
操作:停机维护窗口开 VT-d,更新 NIC 固件到建议版本;
结果:SR-IOV 正常;但因上游要镜像,我们最后只给边界 VM 用,其他 VM 维持 vSwitch 路径。

Live Migration 抢带宽
症状:半夜迁移时业务延迟突刺;
操作:给 Live Migration 设 SMB 带宽上限 + vSwitch 权重;
结果:迁移时间略增,但生产延迟稳定。

七、推荐的“标准落地脚本”(可复制粘贴后按需改)

按你的 VLAN/IP/VM 名称替换即可。

# 1) 变量
$uplinks = @("NIC1","NIC2")
$switch  = "vSwitch-SET-Prod"

# 2) NIC 基线
Enable-NetAdapterChecksumOffload -Name $uplinks
Enable-NetAdapterLso -Name $uplinks
Enable-NetAdapterRsc -Name $uplinks
Enable-NetAdapterRss -Name $uplinks
Set-NetAdapterAdvancedProperty -Name $uplinks -DisplayName "Jumbo Packet" -DisplayValue "9014 Bytes"

# 3) 创建 SET vSwitch
New-VMSwitch -Name $switch -NetAdapterName $uplinks -EnableEmbeddedTeaming $true -AllowManagementOS $false -EnableIov $true -BandwidthReservationMode Weight
Set-VMSwitch -Name $switch -EnableSoftwareRsc $true

# 4) Host vNIC + VLAN + QoS
Add-VMNetworkAdapter -ManagementOS -Name "vMgmt" -SwitchName $switch
Set-VMNetworkAdapterVlan -ManagementOS -VMNetworkAdapterName "vMgmt" -Access -VlanId 10
Set-VMNetworkAdapter -ManagementOS -Name "vMgmt" -MinimumBandwidthWeight 10 -VrssEnabled $true

Add-VMNetworkAdapter -ManagementOS -Name "vLM" -SwitchName $switch
Set-VMNetworkAdapterVlan -ManagementOS -VMNetworkAdapterName "vLM" -Access -VlanId 20
Set-VMNetworkAdapter -ManagementOS -Name "vLM" -MinimumBandwidthWeight 20 -VrssEnabled $true

Add-VMNetworkAdapter -ManagementOS -Name "vSMB" -SwitchName $switch
Set-VMNetworkAdapterVlan -ManagementOS -VMNetworkAdapterName "vSMB" -Access -VlanId 30
Set-VMNetworkAdapter -ManagementOS -Name "vSMB" -MinimumBandwidthWeight 30 -VrssEnabled $true

Add-VMNetworkAdapter -ManagementOS -Name "vProd" -SwitchName $switch
Set-VMNetworkAdapterVlan -ManagementOS -VMNetworkAdapterName "vProd" -Trunk -NativeVlanId 100 -AllowedVlanIdList "100-199"
Set-VMNetworkAdapter -ManagementOS -Name "vProd" -MinimumBandwidthWeight 40 -VrssEnabled $true

# 5) VM 阶段:高吞吐 VM 开 VMMQ/vRSS/SR-IOV 权重
$perfVMs = @("Edge-VM01","Cache-VM01")
foreach ($vm in $perfVMs) {
  Set-VMNetworkAdapter -VMName $vm -VmmqEnabled $true -VmmqQueuePairs 8 -VrssEnabled $true -IovWeight 80
}

# 6) VMQ CPU 亲和
Set-NetAdapterVmq -Name "NIC1" -BaseProcessorNumber 8  -MaxProcessors 12
Set-NetAdapterVmq -Name "NIC2" -BaseProcessorNumber 20 -MaxProcessors 12

# 7) SMB/迁移限速(按需)
Set-SmbBandwidthLimit -Category LiveMigration -BytesPerSecond 20000000000

八、何时该“收手”与“上刀”:取舍原则

  • 追稳定 > 追极限:香港链路复杂、上游策略多,优先 RSC/RSS/VMMQ/SET/QoS 的“常规四件套”。
  • SR-IOV 给边界型或 超低延迟 VM,用在刀刃上;
  • RDMA 只有在 端到端 可控时才开启;
  • Jumbo 必须全链路一致;
  • 能测就测:iperf3、ntttcp、PerfMon、Get-* 系列输出留存,便于回归。

九、收尾(机房门口的风比机柜里凉快)

凌晨三点半,我把最后一条 PowerShell 敲完,PerfMon 的线一条条顺了下来。Core#0 不再抓狂,虚机间的吞吐上了 20Gbps,北向单 VM 也跑到了 15Gbps 以上。Live Migration 开始的时候,生产曲线只是轻轻一荡。
我把凳子抽出来,背靠着冷通道的墙坐了会儿,机柜门上还能看到之前画 VLAN 的记号笔印。值夜的小哥递过来一瓶水,我顺口把这套“配方”讲给他听:SET、VMMQ/vRSS、RSC、Jumbo、QoS、队列亲和、SR-IOV,再加上一点对机房脾气的了解。
第二天早上八点,业务方只发了四个字:“这次稳了。”

十、速查清单(Checklist)

  1.  驱动/固件配套,Enable-*Offload、Enable-NetAdapterRss、Enable-NetAdapterRsc
  2.  用 SET 建外部 vSwitch(-EnableEmbeddedTeaming)
  3.  Host vNIC 分层:管理/迁移/存储/生产 + VLAN + 权重
  4.  RSC 开启(Set-VMSwitch -EnableSoftwareRsc $true)
  5.  RSS/vRSS/VMMQ/SR-IOV:按 VM 类型启用
  6.  VMQ 队列与 CPU/NUMA 亲和(Set-NetAdapterVmq)
  7.  Jumbo 全链路一致(ping -f -l 验证)
  8.  Live Migration/SMB 限速(Set-SmbBandwidthLimit)
  9.  用 iperf3/ntttcp/PerfMon 验证并留档

如果你也在香港的机房里为 Hyper-V 的 vSwitch 跑数而烦躁,照着这篇做一遍,先把 80% 的通用优化吃满。剩下 20%,就看你机房的个性与业务的脾气了。

目录结构
全文