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

如何在香港服务器 Windows 系统中把 RDMA 和高速网卡“绑”在一起,干掉分布式存储里的延迟

发布人:Minchunlin 发布时间:2025-09-01 11:27 阅读量:936


凌晨 2:17,香港荔枝角机房,我守着四台刚上架的 Windows Server 2022 节点,CSV 卷上的延迟图像心电图一样乱跳:p99 过 8ms,业务的异步复制已经开始掉速。交换机是双上联的 100GbE,理论带宽飘亮,但 SMB3 的 TCP 链路明显吃不满,还把 CPU 烧得通红。

“要么就把 RDMA 搞起来,要么今晚谁也别想下班。”我对同事叹了口气,把手里的咖啡放到机柜门上,开始把 RDMA 和高速网卡硬生生地“绑”在一起。

一、目标与场景

目标:在 Windows 分布式存储(基于 SMB Direct / Storage Spaces Direct, S2D)场景中,将 RDMA(RoCEv2)与 100GbE 网卡联合调优,显著降低延迟、减轻 CPU 占用,并提升 IOPS/吞吐。

平台:香港机房,跨两台 ToR 交换机,L2 同域,DCB(PFC/ETS/ECN)已可用。

业务:Hyper-V 虚机落在 S2D 的 CSV 卷上,后台用 SMB Direct 在节点间复制与重平衡。

二、硬件与软件清单(实测环境)

组件 型号/版本 关键点
服务器 4× 1U 节点(2×Intel Xeon Gold 6330, 512GB RAM) NUMA 2 节点,BIOS 里 C-States 关,Turbo 开
系统盘 2× SATA SSD (RAID1) 系统与数据分离
数据盘 8× NVMe U.2 3.84TB(Mixed Use) S2D: 2 盘做缓存,其余做容量层
网卡 Mellanox ConnectX-5 EN(MCX516A-CDAT, 2×100GbE) 支持 RoCEv2,固件同版本
交换机 2× 100GbE ToR(例:Arista 7050X3 / NVIDIA SN2700 同级) DCBX, PFC(pri 3), ETS, ECN
操作系统 Windows Server 2022 Datacenter (Core) 含 S2D 与 SMB Direct
驱动 Mellanox WinOF-2 驱动(与固件匹配) 保持一致性,避免奇怪的小抖动
协议 SMB Direct (SMB over RDMA) S2D 内部复制与重平衡走 RDMA

经验:固件、驱动、交换机 OS 三者一定要对齐版本,老版本常见 Pause Storm、CNP 行为异常、ECN 标记不一致等坑。

三、网络与 QoS 设计(RoCEv2 + DCB)

3.1 VLAN 与寻址

存储专用 VLAN:与管理、业务流量隔离(如 VLAN 3101),只跑 SMB 445。

每节点两条 RDMA 物理口:分别上联不同 ToR,ECMP/LACP 由上层设计决定;我这里做 L2 多活,不跨 L3。

3.2 DCB 策略(重点)

PFC:仅对 Priority 3 开启(SMB Direct 使用的优先级),其余优先级关闭 PFC,避免“全场拥塞”。

ETS:为 Priority 3 预留 ≥50% 的带宽权重。

ECN:交换机与网卡都启用,避免过度依赖 PFC。

MTU:9000(端到端一致)。

原则:只为 SMB RDMA 开启 PFC。所有优先级开 PFC 的配置极易导致 Pause 风暴(亲测满屋灯光跟过年似的)。

四、Windows 端安装与启用 RDMA

4.1 安装角色/功能(PowerShell)

# 基础功能:DCB, 文件服务, 以及故障排除常用组件
Install-WindowsFeature Data-Center-Bridging, FS-FileServer, RSAT-Feature-Tools -IncludeManagementTools

# 检查 RDMA 能力
Get-NetAdapterRdma

4.2 Mellanox 驱动与高级参数

安装 WinOF-2 对应版本驱动。

确认高级属性:

  • RoCE mode = v2
  • Jumbo Packet = 9014
  • Interrupt Moderation 适中(RDMA 对 CPU 打断敏感)
  • RSS 仅对非 RDMA 流量;RDMA 本身零拷贝,不走 TCP 栈
# 统一命名网卡,避免脚本跑飞
Rename-NetAdapter -Name "Ethernet 3" -NewName "RDMA1"
Rename-NetAdapter -Name "Ethernet 4" -NewName "RDMA2"

# 开启 RDMA
Enable-NetAdapterRdma -Name "RDMA1","RDMA2"

# MTU/巨帧
Set-NetAdapterAdvancedProperty -Name "RDMA1","RDMA2" -RegistryKeyword "*JumboPacket" -RegistryValue 9014

提示:部分 Mellanox 固件的 RoCE/ECN 需用厂商工具(WinMFT)设置;保持与交换机端一致的 ECN 阈值策略。

4.3 Windows DCB(QoS)策略(关键)

# 1) 为 SMB 设置 802.1p 优先级(Priority 3)
New-NetQosPolicy "SMB" -NetDirectPortMatchCondition 445 -PriorityValue8021Action 3

# 2) 开启 PFC,仅对 Priority 3
Enable-NetQosFlowControl -Priority 3
Disable-NetQosFlowControl -Priority 0,1,2,4,5,6,7

# 3) ETS:给 pri 3 分配带宽权重(如 60%)
New-NetQosTrafficClass -Name "SMB" -Priority 3 -BandwidthPercentage 60 -Algorithm ETS

# 4) DSCP(可选,与网络策略对齐)
Set-NetQosDscpState -State Enabled
New-NetQosPolicy "SMB-DSCP" -NetDirectPortMatchCondition 445 -DSCPAction 3

4.4 SMB Direct 校验

# 看看 RDMA 是否可用
Get-SmbClientNetworkInterface | ft InterfaceFriendlyName,RdmaCapable,RssCapable,IpAddresses
Get-SmbServerNetworkInterface | ft InterfaceAlias,RdmaCapable,IPAddress

# 建连后确认:
Get-SmbMultichannelConnection | ft ClientRSSCapable,ServerRdmaCapable,ClientRdmaCapable,ServerName,InterfaceIndex,State

若 ClientRdmaCapable/ServerRdmaCapable = True 且 State = Established,说明 SMB Direct 已走 RDMA。

五、S2D(Storage Spaces Direct)落地步骤摘要

我用的是 4 节点“对等架构”,每节点 NVMe 混合(Cache + Capacity),用 ReFS/CSVFS。

# 1) 建群集(假定已正确解析主机名)
New-Cluster -Name HK-S2D -Node HK01,HK02,HK03,HK04 -StaticAddress 10.10.31.10 -NoStorage
Test-Cluster -Node HK01,HK02,HK03,HK04

# 2) 开启 S2D
Enable-ClusterS2D -Confirm:$false

# 3) 建虚拟磁盘与卷(两层存储示例)
#    先找出存储池与可用层
Get-StoragePool -IsPrimordial $false
Get-StorageTier | ft FriendlyName,MediaType,ResiliencySettingName

#    示例:创建 2 个层(性能/容量)并组合
$perf = Get-StorageTier -FriendlyName *Performance*
$cap  = Get-StorageTier -FriendlyName *Capacity*

New-Volume -FriendlyName "CSV-01" `
  -StorageTierFriendlyNames $perf.FriendlyName,$cap.FriendlyName `
  -StorageTierSizes 2TB,10TB -FileSystem CSVFS_ReFS

小技巧:SMB Multichannel Constraint 用来“钉”住 RDMA 接口,避免偶尔走到管理网卡。

# 以客户端视角约束到对端服务器特定接口(示例)
# 先查 server 的 RDMA 接口 IP
Get-SmbServerNetworkInterface -CimSession HK02

# 钉住:
Set-SmbClientConfiguration -EnableMultiChannel $true
New-SmbMultichannelConstraint -InterfaceIndex 12 -ServerName "HK02"

六、基准与对比(真实跑过的典型数值)

工具:DiskSpd(远端 SMB 共享/CSV 上压测),30s 预热 + 180s 运行;Windows 性能计数器记录 CPU;多轮求中位数。

6.1 4K 随机读(8 线程 * 深度 32)

模式 p50 延迟 p99 延迟 IOPS 节点总 CPU
TCP@100GbE(无 RDMA) 1.8 ms 6.3 ms 520K 48%
RDMA@100GbE(RoCEv2) 0.42 ms 1.1 ms 1.15M 18%

6.2 64K 顺序读(8 线程 * 深度 8)

模式 吞吐 p99 延迟 节点总 CPU
TCP@100GbE(无 RDMA) 7.2 GB/s 4.8 ms 62%
RDMA@100GbE(RoCEv2) 11.8 GB/s 1.7 ms 27%

观察:RDMA 把 TCP 栈绕开后,延迟腰斩不止,CPU 释放立竿见影;多通道(两口 100G)拉满时,瓶颈迅速转到 NVMe 阵列与 S2D 编码层。

七、最容易踩的坑(以及我是怎么在机房把它们填上的)

PFC 开太多

症状:整网时不时“凝固”,RTT 飙到几十毫秒,吞吐断崖式下降。

原因:把所有优先级都开了 PFC,Pause Storm 一来所有流量被连坐。

解决:只为 Priority 3(SMB/RDMA)开 PFC,其余全部关闭;打开 ECN,把轻微拥塞交给 ECN/CNP 去处理。

RoCEv1/ECN 不一致

症状:RDMA 能跑但抖动大,p99 偶发 10ms+。

原因:一侧网卡还是 RoCEv1、交换机/网卡未统一 ECN。

解决:统一 RoCEv2;网卡固件里把 ECN 打开;交换机上设好 ECN 阈值,与队列映射一致。

MTU 不一致

症状:90% 的流量好好的,偶尔某台节点吞吐掉一半。

原因:某一跳设备还停留在 1500 MTU。

解决:端到端 9000;Windows、交换机、上联都核对;ping -f -l 8972 很好用。

混用防火墙策略

症状:SMB 建链偶尔走 TCP,RDMA 连接建立失败。

原因:中途有 L3/主机防火墙对 445 或 DCB/LLDP 压制。

解决:存储 VLAN 内白名单 445/TCP、DCBX/LLDP;Windows 防火墙放行 文件和打印机共享(SMB-In)。

NUMA/RSS 亲和不当

症状:CPU 某一半核心爆表,另一半吃灰。

解决:对非 RDMA 流量设置 RSS Base/Max;RDMA 流量走 NIC 直达,尽量把中断和队列对齐到本地 NUMA。

Get-NetAdapterRss -Name "RDMA1","RDMA2"
Set-NetAdapterRss -Name "RDMA1" -BaseProcessorNumber 0 -MaxProcessorNumber 31
Set-NetAdapterRss -Name "RDMA2" -BaseProcessorNumber 32 -MaxProcessorNumber 63

交换机 Buffer/队列映射

症状:单口 100G 还好,双口并发就开始丢包、CNP 淹没。

解决:把 Priority 3 映射到专属队列,给足 buffer;ECMP/LAG Hash 包含 5 元组,避免倾斜。

八、现场可复用的“拷贝即用”脚本片段

8.1 一次性把 RDMA、QoS、巨帧、校验都配好

$rdmaIf = @("RDMA1","RDMA2")

# RDMA & Jumbo
Enable-NetAdapterRdma -Name $rdmaIf
Set-NetAdapterAdvancedProperty -Name $rdmaIf -RegistryKeyword "*JumboPacket" -RegistryValue 9014

# QoS 基线
if (-not (Get-WindowsFeature Data-Center-Bridging).Installed) {
    Install-WindowsFeature Data-Center-Bridging -IncludeManagementTools
}

# 清理旧策略
Get-NetQosPolicy | Remove-NetQosPolicy -Confirm:$false

# SMB 优先级 & DSCP
New-NetQosPolicy "SMB" -NetDirectPortMatchCondition 445 -PriorityValue8021Action 3
Set-NetQosDscpState -State Enabled
New-NetQosPolicy "SMB-DSCP" -NetDirectPortMatchCondition 445 -DSCPAction 3

# PFC for pri 3 only
Enable-NetQosFlowControl -Priority 3
Disable-NetQosFlowControl -Priority 0,1,2,4,5,6,7

# ETS 权重
New-NetQosTrafficClass -Name "SMB" -Priority 3 -BandwidthPercentage 60 -Algorithm ETS

# 验证
Write-Host "RDMA 接口:"
Get-SmbClientNetworkInterface | ft InterfaceFriendlyName,RdmaCapable,IpAddresses

8.2 S2D 建群集到建卷(最小化示例)
$nodes = "HK01","HK02","HK03","HK04"
New-Cluster -Name HK-S2D -Node $nodes -StaticAddress 10.10.31.10 -NoStorage
Test-Cluster -Node $nodes
Enable-ClusterS2D -Confirm:$false

$perf = Get-StorageTier -FriendlyName *Performance*
$cap  = Get-StorageTier -FriendlyName *Capacity*
New-Volume -FriendlyName "CSV-01" -StorageTierFriendlyNames $perf.FriendlyName,$cap.FriendlyName -StorageTierSizes 2TB,10TB -FileSystem CSVFS_ReFS

九、运维侧的观察与复盘

  • 延迟:RDMA 后,4K 随机读 p50 从 1.8ms 下降到 ~0.4ms,p99 逼近 1ms。
  • CPU:SMB Direct 把大量 copy/stack 开销省掉了,S2D 重平衡时 CPU 峰值从 70% 降到 30% 多一些。
  • 波动:把 ECN 和 PFC 调完之后,抖动比纯 PFC 方案小得多,链路满载时也不会“闷死”。
  • 运维复杂度:RDMA 最大成本是端到端一致性(固件/驱动/DCB 参数);一旦固化成自动化脚本,后续扩容就顺滑了。

十、Checklist(上线前最后 5 分钟)

  • RoCEv2:网卡固件一致、网卡属性确认、驱动版本一致。
  • DCB:PFC=pri 3 only,ETS≥50%,ECN 开。
  • MTU:端到端 9000,一跳不差。
  • SMB:Get-SmbMultichannelConnection 里 RDMA=true。
  • 交换机:优先级/队列映射、Buffer 足量、DCBX on。
  • 监控:p50/p99 延迟、CNP 计数、Pause 帧计数、丢包计数。
  • 回滚:保留一键禁用 RDMA/恢复 TCP 的脚本,变更窗口内演练过。

凌晨 4:05,我把最后一条 Get-SmbMultichannelConnection 输出拍了张照:四条 RDMA 会话稳稳当当。重平衡任务重新跑起来,p99 老老实实趴在 1ms 左右。机房外面开始泛白,同事拍了拍我:“走,去楼下吃碗云吞面,你欠它一夜的面子。”

这次折腾的收获很简单:Windows 场景里,RDMA(RoCEv2)+100GbE 不是“锦上添花”,而是“去掉系统噪音”的一刀。当你的分布式存储把 CPU 和 TCP 栈都当成“路障”时,RDMA 这把刀能把路障削平。剩下的,就是硬盘阵列和代码层真正的实力了。

如果你也在香港、也在半夜和延迟搏斗,不妨把上面的清单和脚本照着走一遍。别怕,一切从 Priority 3 开始。

目录结构
全文