如何在香港服务器的Windows Server 2019环境下优化Hyper-V虚拟机性能,解决存储与网络资源竞争问题?

这是我在香港机房(荃湾工业区一隅)给一台承载多业务的 Hyper-V 宿主机做性能“手术”的完整记录。文中既有我踩过的坑,也有最终可复用的参数与脚本。你可以把它当成一份可落地的操作手册:从硬件到系统、从存储到网络、从单机到可扩展,逐层解决虚拟机之间对 I/O 与带宽的争抢。
背景与诉求
场景:香港单机柜、双上联(10/25GbE),一台主力宿主机跑 12 台混部 VM(数据库、Web、日志、备份代理、ETL),白天吞吐高、晚上批处理+备份导致 存储与网络资源强烈竞争,时不时拖慢线上。
目标:
- 把“尖峰争抢”变成“可控分配”;
- 同时提升平峰性能下限(稳态低延迟),避免偶发卡顿。
- 约束:不能停机太久(窗口 2 小时内),设备就地优化为主。
1. 物理与基础设施基线(基线打不好,后面全白搭)
1.1 宿主机与硬件参数(实配)
| 组件 | 型号/数量 | 关键点 |
|---|---|---|
| CPU | 2 × Xeon Silver 4314 (16C/32T, 2.4GHz) | NUMA 2 节点;更注重 cache/NUMA 亲和 |
| 内存 | 256GB DDR4-3200 (16×16GB) | 每 NUMA 128GB |
| 系统盘 | 2 × SATA SSD 480GB(RAID1) | 仅装系统/日志 |
| 数据盘 | 2 × NVMe SSD Intel P4510 3.2TB | 分为 热卷(OLTP/日志)与 冷卷(文件/备份) |
| 网卡 | 2 × Intel X710 10GbE(或 25GbE 同类) | 支持 SR-IOV、VMQ、VMMQ、RSS |
| HBA/RAID | 无专用卡,NVMe 直通 | 减少额外队列瓶颈 |
| 机房网络 | 双上联、BGP 出口 | 夜间跨站点同步压力大 |
经验:NVMe 直通比“通用 RAID 卡 + SSD”更稳、更快(尤其队列深度和延迟稳定性)。如果一定要阵列卡,务必确认写回缓存策略与掉电保护。
1.2 固件与电源策略
BIOS 里把 C-State 深度节能 关掉,电源设为 Performance。
Windows 电源计划改 高性能:
- powercfg /setactive SCHEME_MIN
- 升级 NIC 与 NVMe 固件到运营商允许的最新稳定版。
2. Windows Server 2019 与 Hyper-V 基础设置
2.1 角色与补丁
安装 Hyper-V、Failover Clustering(即使先不组群,日后好扩)。
打齐 2019 的累积更新与 NIC/NVMe 厂商驱动。
2.2 vSwitch:用 SET(Switch-Embedded Teaming) 取代传统 LBFO
# 两张物理口做 SET,打开 SR-IOV 和软件 RSC
New-VMSwitch -Name vSwitchSET `
-NetAdapterName "NIC1","NIC2" `
-EnableEmbeddedTeaming $true `
-EnableIov $true
Set-VMSwitch -Name vSwitchSET -EnableSoftwareRsc $true
为什么:SET 是 2019 的推荐做法,性能更好,功能还支持 RDMA/VMMQ 等后续优化;LBFO 已进入维护期。
2.3 管理 vNIC 与 VLAN
Add-VMNetworkAdapter -ManagementOS -Name "vEthernet-Mgmt" -SwitchName "vSwitchSET"
Set-VMNetworkAdapterVlan -ManagementOS -VMNetworkAdapterName "vEthernet-Mgmt" -Access -VlanId 120
3. 存储面:把抖动“摁死”在 NVMe 层与 VHDX 层
3.1 卷与文件系统布局
- 热卷(NVMe0):ReFS,64K 簇,放 数据库 VHDX、日志 VHDX。
- 冷卷(NVMe1):NTFS 或 ReFS(若需要块克隆/后续克隆),放 静态文件、备份、ISO。
- C: 系统与 Hyper-V 程序,VHDX 全放到数据卷(避免系统盘干扰)。
格式化与完整性设置(ReFS):
# 举例:把 NVMe0 格式化为 ReFS 64K
Get-PhysicalDisk | ? MediaType -eq SSD | ft -AutoSize
# 假定卷为 D:
Format-Volume -DriveLetter D -FileSystem ReFS -AllocationUnitSize 65536 -Confirm:$false
# 对 VHDX 根目录关闭完整性流(降低元数据开销)
New-Item -ItemType Directory -Path "D:\VMs"
Set-FileIntegrity -FileName "D:\VMs" -Enable $false -Recursive
注:WS2019 的 ReFS 对 VHDX 非常友好(块克隆、快速克隆),但默认完整性流对小随机写有额外负担,对承载 VHDX 的目录关闭完整性通常能降低写放大。
3.2 VHDX 规格:关键参数与创建
关键 VM 使用固定大小 VHDX(避免动态扩展时的瞬态抖动)。
动态盘如需使用,BlockSize 建议 32MB 以上以优化顺序写(如日志/备份)。
# 固定盘(数据库)
New-VHD -Path "D:\VMs\DB01\DB01_OS.vhdx" -SizeBytes 200GB -Fixed
New-VHD -Path "D:\VMs\DB01\DB01_Data.vhdx" -SizeBytes 800GB -Fixed
New-VHD -Path "D:\VMs\DB01\DB01_Log.vhdx" -SizeBytes 200GB -Fixed
# 动态盘(日志归档/文件)
New-VHD -Path "E:\VMs\Files01\Files01_Data.vhdx" -SizeBytes 2TB -Dynamic -BlockSizeBytes 33554432
把 VHDX 连到 VM(SCSI 控制器),并在 重要磁盘上启用/设置存储 QoS:
Add-VMHardDiskDrive -VMName "DB01" -Path "D:\VMs\DB01\DB01_Data.vhdx" -ControllerType SCSI -ControllerNumber 0 -ControllerLocation 1
# 每 VHDX 设定最小/最大 IOPS(防止某一盘把 NVMe 吃满)
Set-VMHardDiskDrive -VMName "DB01" -ControllerType SCSI -ControllerNumber 0 -ControllerLocation 1 `
-MinimumIOPS 3000 -MaximumIOPS 15000
# Web/日志类 VM 设上限避免夜间批处理拖垮
Set-VMHardDiskDrive -VMName "LOG01" -ControllerType SCSI -ControllerNumber 0 -ControllerLocation 1 `
-MaximumIOPS 8000
经验:把“关键低延迟”的 VM 放到 热卷,同时给“噪声 VM”(例如夜间归档/备份/批处理)设 MaximumIOPS 上限,是抑制争抢最直接有效的手段。
3.3 TRIM/重新修整与碎片管理
NVMe + VHDX 配合,后台定期 ReTrim:
Optimize-Volume -DriveLetter D -ReTrim -Verbose
Optimize-Volume -DriveLetter E -ReTrim -Verbose
3.4 杀毒/备份排除项(常被忽略的大坑)
排除 D:\VMs、E:\VMs、C:\ProgramData\Microsoft\Windows\Hyper-V\、*.vhdx、*.avhdx。
备份代理对 VSS 的冻结时间要控制(我把 DB VM 改为备份 副本,避免在主业务时段冻结)。
4. 网络面:队列、分流与限速“三板斧”
夜间我们的问题更像“网卡发烧”引的“全身炎症”,所以我把网络优化拆三步。
4.1 物理口能力打开:RSS、VMQ、VMMQ、RSC
# 物理 NIC 打开 RSS、RSC、VMQ(10GbE 以上务必)
Enable-NetAdapterRss -Name "NIC1","NIC2"
Enable-NetAdapterRsc -Name "NIC1","NIC2"
Enable-NetAdapterVmq -Name "NIC1","NIC2"
# 合理分配 VMQ 到 CPU,避开 CPU0(中断集中)
Set-NetAdapterVmq -Name "NIC1" -BaseProcessorNumber 2 -MaxProcessors 8
Set-NetAdapterVmq -Name "NIC2" -BaseProcessorNumber 10 -MaxProcessors 8
# VM 侧打开 vRSS/VMMQ(2019)
Get-VMNetworkAdapter -VMName "*" | Set-VMNetworkAdapter -VrssEnabled $true -VmmqEnabled $true
坑点:如果固件较老,打开 VMMQ 反而更慢;升级驱动/固件后再开,不行就只开 vRSS + VMQ。
4.2 vSwitch 带宽模式与 VM 限速/保底
vSwitch 设为 Weight(按权重分配最低带宽),对关键 VM 配 MinimumBandwidthWeight,对批处理/备份 VM 配 MaximumBandwidth 上限。
Set-VMSwitch -Name vSwitchSET -MinimumBandwidthMode Weight
# 核心在线流量(WEB01、API01)权重高
Set-VMNetworkAdapter -VMName "WEB01" -MinimumBandwidthWeight 80
Set-VMNetworkAdapter -VMName "API01" -MinimumBandwidthWeight 80
# 备份/ETL 夜间冲击大的,给上限(单位 Mbps)
Set-VMNetworkAdapter -VMName "BKP01" -MaximumBandwidth 3000
Set-VMNetworkAdapter -VMName "ETL01" -MaximumBandwidth 4000
策略:白天靠权重保底,晚上靠上限兜底;两套一起用,避免“谁都能抢满”。
4.3 SMB/Livemigration 分流与限速(避免抢业务口)
迁移/复制/文件拷贝这类“运维流量”用 独立 vNIC 与 VLAN。
为 SMB 类目限速(Windows 内建):
# Livemigration 走 SMB,且限速(例如 6Gbps)
Set-VMHost -VirtualMachineMigrationPerformanceOption SMB
Set-SmbBandwidthLimit -Category LiveMigration -BytesPerSecond 750000000 # 约 6Gbps
# 文件拷贝类也设限(避免半夜复制狂飙)
Set-SmbBandwidthLimit -Category FileCopy -BytesPerSecond 500000000
可选增强(机房支持 RDMA/RoCEv2 时):
- 安装 DCB,配置 PFC/ETS,把 SMB Direct 跑到独立优先级;
- Enable-NetAdapterRdma + Set-SmbClientConfiguration -EnableMultichannel $true。
我做过 A/B,对跨柜文件同步延迟收敛明显,但要和网络团队配合好 PFC,慎重变更。
5. CPU/内存与 NUMA 亲和
5.1 关闭宿主 NUMA 跨越(更强的一致性)
Set-VMHost -NumaSpanningEnabled $false
解释:混部时更希望每台 VM 尽量停留在一个 NUMA 节点,减少跨节点内存访问带来的延迟波动。
5.2 VM CPU 配额与优先权
关键 VM:设 Reserve(保留百分比)与 RelativeWeight(权重),禁用过高的 Maximum 限制。
非关键 VM:合理 Maximum 限制,避免夜间把 CPU 占满拖慢别人。
# 数据库 VM
Set-VMProcessor -VMName "DB01" -Count 10 -Reserve 40 -RelativeWeight 200
# 批处理 VM
Set-VMProcessor -VMName "ETL01" -Count 8 -Maximum 80 -RelativeWeight 100
5.3 内存模式
低延迟 VM(DB/Cache)用 静态内存;
其他用 动态内存,但把 Minimum/Maximum 收好,避免热扩/回收引起抖动。
# DB 静态内存
Set-VM -Name "DB01" -DynamicMemoryEnabled $false -MemoryStartupBytes 64GB
# Web 动态内存(范围收紧)
Set-VM -Name "WEB01" -DynamicMemoryEnabled $true -MemoryStartupBytes 8GB -MemoryMinimumBytes 8GB -MemoryMaximumBytes 16GB
6. 压测与度量:我怎么确认“真有效”
6.1 基线压测工具与方法
DiskSpd(随机/顺序混合)、VM 内部与宿主直打都要测(隔层观测)。
iPerf3(单流/多流),测 白天与夜间两档。
PerfMon 关键计数器:
- Physical Disk: Avg. Disk sec/Read、Avg. Disk sec/Write(目标 < 2ms,尖峰 < 5ms)
- Hyper-V Virtual Storage Device: Read/Write Latency
- Hyper-V Virtual Network Adapter: Packets/sec、Byte Rate
- NIC: VMQ Dropped Packets、RSS Queue。
6.2 我的一组“前后对比”样本(节选)
存储(DB01 数据盘 4K 随机读写混合,QD=16)
| 指标 | 优化前 | 优化后 |
|---|---|---|
| IOPS | 42,000 | 88,000 |
| 平均延迟 | 3.9 ms | 1.7 ms |
| 99 百分位 | 12.6 ms | 4.8 ms |
网络(多流 iPerf3,宿主↔备份服务器)
| 指标 | 优化前 | 优化后 |
|---|---|---|
| 吞吐(夜间峰值) | 8.2 Gbps | 9.6 Gbps(受限 10G 上限) |
| 丢包(驱动计数) | 偶发升高 | 基本 0 |
| CPU 占用(宿主) | 突刺到 70% | 稳定 40~50% |
解释:主要收益来自 VHDX 固定化 + ReFS 优化 + Minimum/Maximum IOPS 与 VMQ/VMMQ + vSwitch 带宽权重/上限 的组合拳。
7. 夜间资源“打架”的三类典型故障与现场处置
7.1 动态盘扩容导致瞬态卡顿
症状:LOG01 在归档时延迟上到 15ms,WEB01 502。
原因:动态 VHDX 扩容 + 后台零填充。
处置:将 LOG01 的数据盘改为 固定 VHDX,同时给 LOG01 MaximumIOPS=8000;问题消失。
7.2 备份代理抢带宽
症状:BKP01 夜间占满 10G,上游复制超时。
原因:文件复制/重删窗口与业务冲突。
处置:给 BKP01 配 -MaximumBandwidth 3000,同时用 Set-SmbBandwidthLimit -Category FileCopy 限速;并把备份改到 冷卷,避免热卷抖动。
7.3 驱动旧 + 开 VMMQ 反降速
症状:启 VMMQ 后吞吐掉到 6Gbps。
原因:X710 老固件的已知问题。
处置:升级 NIC 驱动与固件 → 恢复;若短期不能升级,先关闭 VMMQ,仅保持 vRSS + VMQ。
8. 可复制的“一键化”收尾脚本(节选)
注意:按你的网卡名、卷盘符、VM 名称替换。
# 1) 电源与补丁(略)
# 2) vSwitch (SET)
New-VMSwitch -Name vSwitchSET -NetAdapterName "NIC1","NIC2" -EnableEmbeddedTeaming $true -EnableIov $true
Set-VMSwitch -Name vSwitchSET -EnableSoftwareRsc $true -MinimumBandwidthMode Weight
# 3) NIC 能力
Enable-NetAdapterRss -Name "NIC1","NIC2"
Enable-NetAdapterRsc -Name "NIC1","NIC2"
Enable-NetAdapterVmq -Name "NIC1","NIC2"
Set-NetAdapterVmq -Name "NIC1" -BaseProcessorNumber 2 -MaxProcessors 8
Set-NetAdapterVmq -Name "NIC2" -BaseProcessorNumber 10 -MaxProcessors 8
# 4) ReFS + 目录完整性关闭
Format-Volume -DriveLetter D -FileSystem ReFS -AllocationUnitSize 65536 -Confirm:$false
New-Item -ItemType Directory -Path "D:\VMs" -Force | Out-Null
Set-FileIntegrity -FileName "D:\VMs" -Enable $false -Recursive
# 5) 关键 VM 磁盘与存储 QoS
New-VHD -Path "D:\VMs\DB01\DB01_Data.vhdx" -SizeBytes 800GB -Fixed
Add-VMHardDiskDrive -VMName "DB01" -Path "D:\VMs\DB01\DB01_Data.vhdx" -ControllerType SCSI -ControllerNumber 0 -ControllerLocation 1
Set-VMHardDiskDrive -VMName "DB01" -ControllerType SCSI -ControllerNumber 0 -ControllerLocation 1 -MinimumIOPS 3000 -MaximumIOPS 15000
# 6) 带宽保底/上限
Set-VMNetworkAdapter -VMName "WEB01" -MinimumBandwidthWeight 80
Set-VMNetworkAdapter -VMName "API01" -MinimumBandwidthWeight 80
Set-VMNetworkAdapter -VMName "BKP01" -MaximumBandwidth 3000
Set-VMNetworkAdapter -VMName "ETL01" -MaximumBandwidth 4000
# 7) Livemigration/SMB 限速
Set-VMHost -VirtualMachineMigrationPerformanceOption SMB
Set-SmbBandwidthLimit -Category LiveMigration -BytesPerSecond 750000000
Set-SmbBandwidthLimit -Category FileCopy -BytesPerSecond 500000000
# 8) NUMA/内存策略
Set-VMHost -NumaSpanningEnabled $false
Set-VM -Name "DB01" -DynamicMemoryEnabled $false -MemoryStartupBytes 64GB
Set-VM -Name "WEB01" -DynamicMemoryEnabled $true -MemoryStartupBytes 8GB -MemoryMinimumBytes 8GB -MemoryMaximumBytes 16GB
# 9) 杀毒排除(以 Defender 为例可用 GUI/策略),此处略
9. 运维“刻度盘”:我日常盯的 8 个指标
- NVMe 延迟 p50/p99;2) 每 VM 的 IOPS 与队列深度;
- vSwitch 端口带宽(保底是否触发);4) BKP/ETL 的上限是否生效;
- VMQ 丢包计数;6) 宿主 CPU NUMA 失衡(某节点 80% 另一个 30%);
- VHDX 增长速率(避免动态盘悄悄吃完);8) 备份窗口与业务峰的重叠度。
10. FAQ:几个你可能会问的取舍
ReFS 还是 NTFS?
纯 VHDX 宿主卷我更倾向 ReFS + 关闭完整性流;小文件密集、需要重删的场景 NTFS 也可。
数据重删开吗?
WS2019 ReFS 支持重删,但对热数据 VHDX 不建议;放冷卷或备份卷更合适。
SR-IOV 要不要开?
单宿主下 SR-IOV 能降延迟,但会弱化 vSwitch 的带宽管理与捕获能力;我一般只对极端低延迟 VM 开,其他用 VMQ/VMMQ + 权重/上限足够。
动态内存会不会抖?
会,在激进收/放时尤甚。关键 VM 用静态,非关键 VM 把 min/max 收紧。
11. 最后的“保命清单”(上线前 5 分钟复核)
- 电源:高性能;C-State 降到最低。
- vSwitch:SET 成功,RSC 打开,BandwidthMode=Weight。
- NIC:驱动/固件版本确认,RSS/VMQ/VMMQ 状态良好。
- 存储:VHDX 放在正确卷、目录完整性关闭、关键盘固定大小。
- QoS:VM 的 MinimumBandwidthWeight/MaximumBandwidth、VHDX 的 Min/Max IOPS 生效。
- 杀毒/备份:排除项 OK,备份窗口不撞业务峰。
- NUMA:宿主禁跨越,关键 VM 静态内存。
- 监控:PerfMon 与告警规则打开(尤其夜间)。
12. 收官感想
那晚在机房,风扇的白噪里我连续做了三轮压测。第三轮时,数据库延迟曲线终于像贴着地面走的“地铁”,不再是坐过山车。资源竞争从“自由搏击”变成了“有序赛道”,白天业务稳了,晚上备份也不再是“别人家的洪水”。
这套方法并不花哨:分层(热/冷)、定额(Min/Max IOPS、带宽)、分流(SMB/Livemigration)、就近(NUMA),再加上几处容易被忽略的小开关(RSC/VMQ/VMMQ、ReFS 完整性流、杀毒排除)。
如果你也在香港或任意拥挤的机房里和“争抢”斗智斗勇,按这套清单走一遍,十有八九能把问题压下去。剩下的一成,我们再一起啃——日志、计数器和一杯深夜的奶茶,通常就够了。