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

香港服务器使用 Windows Server 2022 时,如何调优存储 QoS 策略,保障关键应用的磁盘 I/O 优先级?

发布人:Minchunlin 发布时间:2025-08-23 08:42 阅读量:768


清晨 6:40,我在铜锣湾机房的冷通道里被一阵报警声迎面拍醒。夜班同事把 KVM 推给我:“SQL 的延迟又飙到了 80ms,电商 API 跟着抖,似乎是报表 VM 在扫全库。”我戴上耳机、蹲在第 3 排第 7 柜前,风扇像飞机起飞,手心里全是冷风吹出的干燥感。这不是第一次被“吵闹的邻居”拖慢关键业务,但这次我决定从根上把它管住——用 Windows Server 2022 的存储 QoS(Storage QoS) 给关键应用 硬性安排 I/O 优先级。

下面是一整套我落地的做法与踩过的坑,既给新手提供一步一步的“能复刻”流程,也给老手提供在香港高密机房环境里可操作的“深水区”经验。

一、现场环境与硬件清单(真实可复刻)

目标:保障 SQL01(关键业务数据库 VM)的磁盘 I/O 优先级,抑制 BI-ETL、FullScan 等报表 / 批处理 VM 在高峰期“抢占” I/O。

机房/基础设施

  • 位置:香港、铜锣湾,单柜 42U,2×10A 供电,冷/热通道隔离
  • 运营商:本地三线 BGP,跨境链路单独 QoS(网络层)

主机与存储(Hyper-V + S2D)

集群:4 节点 Windows Server 2022 Datacenter(Core) + Hyper-V + Storage Spaces Direct(S2D)

服务器:Dell PowerEdge R740xd(2U)

  • CPU:2× Intel Xeon Gold 6248R(3.0GHz,24C/48T)
  • 内存:384GB
  • NIC:Mellanox ConnectX-5 25GbE ×2(RoCEv2,SMB Direct)

磁盘(每节点)

  • NVMe(Cache):4× 1.6TB U.2 NVMe
  • SSD(容量层):8× 3.84TB SAS SSD
  • 文件系统:ReFS,CSV
  • S2D 布局:Mirror-accelerated Parity(热写入走镜像,冷数据落奇偶)

关键 VM(示例)

  • SQL01:16 vCPU / 128GB RAM,VHDX:Data 1TB(4K 对齐)、Log 256GB(64K 格)
  • API01:8 vCPU / 32GB RAM,系统+应用盘
  • BI-ETL:12 vCPU / 64GB RAM,报表与全库扫描
  • BG-Tasks:备份、全文索引、批处理等

SLA(我们要兜住的底线)

  • SQL01:P99 读延迟 ≤ 5ms,写延迟 ≤ 10ms
  • API01:P99 总体 ≤ 8ms
  • 其他 VM:不得压制关键 VM 的 IOPS,但允许峰值受限

说明:Windows 的 存储 QoS 是基于 8KB 归一化 I/O 计算 IOPS 的。也就是说,你设定的 MinimumIops/MaximumIops 都是以 8KB 为基准的“等效 IOPS”。

二、方案选型:主机级 QoS vs 集中式(S2D/SOFS)QoS

Windows Server 2022 提供两种思路:

主机级(Host-initiated)QoS:

在 Hyper-V 主机上直接对 VM 的 VHDX 设定最小/最大 IOPS。

  • 适合:单机/小规模;VHDX 不在 SOFS 共享上。
  • 命令:Set-VMHardDiskDrive -MinimumIOPS/-MaximumIOPS

集中式(Cluster/SOFS)QoS(推荐):

  • 在 S2D / SOFS 集群中创建 QoS 策略(Dedicated/Aggregate),在主机上将策略绑定到 VM 的 VHDX;
  • 支持全局视角的“最小保底 + 最大封顶”,对CSV/SMB 上的 VHDX 精准生效;
  • 命令:New-StorageQosPolicy、Set-VMHardDiskDrive -QoSPolicyID ...、Get-StorageQosFlow。
  • 我这套环境是 S2D,选用了集中式 QoS。但下面两个方案我都会给到完整步骤,方便你按场景选。

三、上手前的“基线”:量化你现在到底差在哪儿

1)性能计数器(PerfMon)建议

  • \LogicalDisk(*)\Avg. Disk sec/Read、\Avg. Disk sec/Write、\Disk Transfers/sec
  • \Hyper-V Virtual Storage Device(*)\Average Read Latency、\Average Write Latency
  • \SMB Client Shares(*)\Avg. Read/Write Latency
  • \Cluster CSVFS(*)\Redirected I/O(排查 CSV 是否重定向)
  • \Process(SQLSERVR)\IO Data Bytes/sec(业务视角)

2)一次可复现的压测(DiskSpd)

在干扰源和被保障两类 VM 各运行一轮,记录前后变化。(以下示例在非业务高峰期执行)

# 8KB 随机读写 30%,并发 8 线程,每线程队列深度 32,持续 60s
# 不使用系统缓存(-Sh),输出延迟分布(-L)
.\diskspd.exe -b8K -d60 -r -w30 -t8 -o32 -Sh -L D:\test.dat 10G

我上现场时的基线(节选)

VM 指标 峰前(无 QoS) 峰时(无 QoS)
SQL01 P99 读延迟 4.2ms 78.3ms
SQL01 P99 写延迟 6.1ms 92.7ms
BI-ETL 吞吐(等效 IOPS) 15k 45k
API01 平均响应时间(上层 APM) 25ms > 300ms

结论:典型 噪声邻居(Noisy Neighbor);峰时 BI-ETL 抢占 I/O,SQL01 延迟爆炸。

四、确定 QoS 目标值(不是“拍脑袋”)

我按业务侧给的 SLA,结合底层 NVMe/SSD 的能力与峰值同时在线的 VM 数,给出以下归一化(8KB)目标:

  • SQL01-Data:MinIOPS = 10,000,MaxIOPS = 40,000
  • SQL01-Log:MinIOPS = 3,000,MaxIOPS = 10,000(日志以顺写为主,但要稳)
  • API01:MinIOPS = 2,000,MaxIOPS = 8,000
  • BI-ETL / BG-Tasks(聚合上限):总 MaxIOPS = 20,000(避免抢占)

小技巧:Min 总和请 ≤ 物理可用 IOPS 的 60–70%,留出波动与瞬时突发的喘息空间。Max 的总和可以超过物理能力,但关键是 Min 的兜底。

五、实施路径 A:主机级(Host)QoS(适合小规模/非 SOFS)

若你的 VHDX 在本地存储或非 SOFS 共享,且没有 S2D 集群,可用这一条。

1)对关键盘设定最小/最大 IOPS

# Data 盘(举例:SCSI 控制器 0 的 Location 1)
Set-VMHardDiskDrive -VMName "SQL01" -ControllerType SCSI -ControllerNumber 0 -ControllerLocation 1 `
  -MinimumIOPS 10000 -MaximumIOPS 40000

# Log 盘(Location 2)
Set-VMHardDiskDrive -VMName "SQL01" -ControllerType SCSI -ControllerNumber 0 -ControllerLocation 2 `
  -MinimumIOPS 3000 -MaximumIOPS 10000

# API01
Get-VMHardDiskDrive -VMName "API01" | Set-VMHardDiskDrive -MinimumIOPS 2000 -MaximumIOPS 8000

2)为“吵闹的邻居”封顶

Get-VMHardDiskDrive -VMName "BI-ETL"    | Set-VMHardDiskDrive -MaximumIOPS 20000
Get-VMHardDiskDrive -VMName "BG-Tasks*" | Set-VMHardDiskDrive -MaximumIOPS 15000

3)校验

Get-VMHardDiskDrive -VMName "SQL01" | ft Path,MinimumIOPS,MaximumIOPS

这一方案简单直接,但无法聚合多个 VM 的总上限(每盘单独封顶),跨主机/跨卷全局视角弱。

六、实施路径 B:集中式(S2D/SOFS)存储 QoS(推荐)

适用于 VHDX 存在 CSV/SMB 共享(S2D 或 SOFS),能够 统一创建策略 并 在主机上绑定 到具体盘。

1)在存储集群(SOFS/S2D 任一节点)创建策略

# 进入存储集群节点(或通过 PS Remoting)
# 专用策略(Dedicated):一盘一个“配额”与“保底”
New-StorageQosPolicy -Name "SQL-Data" -PolicyType Dedicated -MinimumIops 10000 -MaximumIops 40000
New-StorageQosPolicy -Name "SQL-Log"  -PolicyType Dedicated -MinimumIops 3000  -MaximumIops 10000
New-StorageQosPolicy -Name "API-Vol"  -PolicyType Dedicated -MinimumIops 2000  -MaximumIops 8000

# 聚合策略(Aggregate):多个 VHDX/VM 共享“总上限”
New-StorageQosPolicy -Name "Batch-Group" -PolicyType Aggregate -MaximumIops 20000

Get-StorageQosPolicy | ft Name,PolicyId,PolicyType,MinimumIops,MaximumIops

2)在 Hyper-V 主机上绑定策略到具体 VHDX

# 拿到策略 ID
$polData = Get-StorageQosPolicy -Name "SQL-Data"
$polLog  = Get-StorageQosPolicy -Name "SQL-Log"
$polAPI  = Get-StorageQosPolicy -Name "API-Vol"
$polBatch= Get-StorageQosPolicy -Name "Batch-Group"

# 绑定 SQL01 的 Data、Log 盘(用精确的控制器位置)
Get-VMHardDiskDrive -VMName "SQL01" -ControllerType SCSI -ControllerNumber 0 -ControllerLocation 1 `
  | Set-VMHardDiskDrive -QoSPolicyID $polData.PolicyId

Get-VMHardDiskDrive -VMName "SQL01" -ControllerType SCSI -ControllerNumber 0 -ControllerLocation 2 `
  | Set-VMHardDiskDrive -QoSPolicyID $polLog.PolicyId

# API01 绑定
Get-VMHardDiskDrive -VMName "API01" | Set-VMHardDiskDrive -QoSPolicyID $polAPI.PolicyId

# 把 BI-ETL 与 BG-Tasks 丢进“聚合上限”
Get-VMHardDiskDrive -VMName "BI-ETL"    | Set-VMHardDiskDrive -QoSPolicyID $polBatch.PolicyId
Get-VMHardDiskDrive -VMName "BG-Tasks*" | Set-VMHardDiskDrive -QoSPolicyID $polBatch.PolicyId

3)实时监控流(Flow)是否达标

Get-StorageQosFlow |
  select InitiatorName,FilePath,PolicyId,Status,MinimumIops,MaximumIops,CurrentIops,AverageLatency |
  ft -AutoSize

Status 若显示 InsufficientThroughput,说明物理层无法满足 Min,要么调小 Min,要么加盘/加节点。

七、验证:压测 + 业务观测的双闭环

压测回放(节选)

场景 SQL01 P99 读延迟 SQL01 P99 写延迟 BI-ETL IOPS(等效)
无 QoS(峰时) 78.3ms 92.7ms 45k
主机级 QoS(只封顶) 12.1ms 15.7ms 20k
集中式 QoS(Min+Max 生效) 4.6ms 7.2ms ≤20k(聚合)

业务监控(APM)

  • API01 的请求 P95 从 220ms 回落到 40–60ms;
  • CFO 最关心的结算模块延迟,峰时稳定在 80ms 以内(应用层),不再随报表扫库抖动。

八、生产可用的“看板级”脚本(简洁可抄)

下面脚本每 5 秒输出关键 VM 的 QoS 达标情况;必要时你可以把它改成事件日志+邮件告警。

$critical = @("SQL01","API01")
while ($true) {
  $flows = Get-StorageQosFlow |
    where {$_.InitiatorName -in $critical} |
    select @{n='VM';e={$_.InitiatorName}},
           @{n='IOPS';e={$_.CurrentIops}},
           @{n='Min';e={$_.MinimumIops}},
           @{n='Max';e={$_.MaximumIops}},
           @{n='AvgLat(ms)';e={[math]::Round($_.AverageLatency,2)}},
           Status
  cls
  $flows | ft -AutoSize
  Start-Sleep -Seconds 5
}

九、那些“看上去不像坑、但很要命”的坑(现场处置纪要)

策略不生效

原因:VHDX 不在 CSV/SMB(SOFS) 上;或用了直通磁盘/物理盘。

处理:把 VHDX 放到 CSV/SMB 共享。直通盘不受 QoS 控制,尽量避免。

RDMA 没开,SMB 直连打回传统 TCP

症状:CPU 飙高,延迟飘;Get-SmbMultichannelConnection 看不到 RDMA。

处理:确认 DCB(PFC/ETS)一致、交换机 RoCEv2 配置正确、NIC 固件/驱动匹配。

电源计划是“平衡”而非“高性能”

症状:偶发延迟“锯齿”,CPU C-State 过深。

处理:设 高性能;BIOS 里关深 C-State,开 Performance Profile。

ReFS + 即时完整性扫描

症状:后台校验与业务抢 I/O。

处理:把重扫描窗口挪到业务低谷;备份/校验避开高峰。

NVMe/SAS 固件与 HBA 模式

症状:队列深度被“锁小”,Min 达不到。

处理:检查 HBA IT(直通)模式,统一固件;队列深度至少 128 起。

单位搞错:IOPS vs MB/s

提示:QoS 的 Min/Max 是 8KB 等效 IOPS,不要填成 MB/s 上限。

动态 VHDX 在高水位扩容瞬间延迟抖

处理:关键盘尽量用 固定大小(Fixed)VHDX,或预扩到足够空间。

过度承诺 Min(Min 总和 > 物理能力)

症状:大量 InsufficientThroughput;全场都不快乐。

处理:重新盘点物理 IOPS,Min 控制在 60–70%,逐步上调。

十、经验性参数与“口袋表”

QoS 策略口袋表(本例)

策略名 类型 MinIOPS MaxIOPS 适用对象
SQL-Data Dedicated 10000 40000 SQL01 数据盘
SQL-Log Dedicated 3000 10000 SQL01 日志盘
API-Vol Dedicated 2000 8000 API01 系统/应用盘
Batch-Group Aggregate 20000 BI-ETL、BG-Tasks

建议的监控阈值

  • Get-StorageQosFlow.Status != OK —— 触发告警
  • AverageLatency > 15ms(关键 VM)—— 黄色预警
  • Min 满足率 < 95%(自定义指标)—— 黄色预警

十一、FAQ:几个关键实现细节

Min 什么时候“起作用”?

当系统检测到存在 I/O 竞争时会优先满足 Min,调度器会在几秒内收敛,不是瞬时值。

Max 是硬上限吗?

是的。达到 Max 后,额外 I/O 会被节流,不再向下压关键 VM 的 Min。

Aggregate(聚合)怎么理解?

多个盘/VM 共享一个“总帽子”。比如把所有报表/备份放到 Batch-Group,它们“互相抢”,但永远不越过 20k IOPS 的总阀。

和应用层限速(比如 SQL Resource Governor)怎么配合?

建议 存储层守“硬线”,应用层做“精细配额”。存储层先确保关键 VM 不被拖垮。

十二、收尾:把“吵闹的邻居”变成“安静的同住者”

早上 9:30,我们在冷通道旁的折叠桌上看监控曲线慢慢变平。SQL01 的延迟像被按住的一根琴弦,再也不抖。BI 的报表照跑,但再也不可能把关键业务拖下水。我拍了拍 KVM 车,跟同事说:“以后报表想闹也闹不起来了,该干嘛干嘛。”

这就是 Windows Server 2022 存储 QoS 真正的价值:

不靠“希望”,靠 策略;不靠“人盯人”,靠 系统级调度。

附录 · 一键复查清单(可直接执行/核对)

# 1) 确认 RDMA 与 SMB 直连
Get-SmbMultichannelConnection | ft ClientIP,ServerIp,ServerName,ClientInterfaceIndex,RDMA

# 2) 列出所有 QoS 策略
Get-StorageQosPolicy | ft Name,PolicyId,PolicyType,MinimumIops,MaximumIops

# 3) 查看关键 VM 的盘与策略绑定
Get-VMHardDiskDrive -VMName "SQL01" | ft Path,ControllerType,ControllerLocation,MinimumIops,MaximumIops,QosPolicyID

# 4) 实时流量与状态
Get-StorageQosFlow |
  select InitiatorName,FilePath,PolicyId,Status,MinimumIops,MaximumIops,CurrentIops,AverageLatency |
  sort InitiatorName | ft -AutoSize

# 5) 电源与 CPU 状态(确保高性能)
powercfg /GETACTIVESCHEME

如果你也在香港,面对高密机房、有限供电、跨境突发流量、以及“吵闹的邻居”,不妨照着这套做一遍。先定好 Min 的底线,再给不重要的 VM 戴好 Max 的“安全帽”。当你在冷通道里把最后一条脚本敲下去、曲线重新收敛的那一刻,你会知道:这不是“玄学调优”,这是真正可验证、可复制的工程化治理。

目录结构
全文