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

香港服务器运行 Windows Server 2022 时,如何优化“存储空间直通”(S2D)提升数据库 I/O 性能?

发布人:Minchunlin 发布时间:2025-08-20 11:02 阅读量:995


凌晨 2:17,香港葵涌机房 7 楼,DBA 打来电话:“跨区报表延迟 40 分钟,线上写入抖成波形图了。”我扣上腕灯、把笔记本放在机柜前的折叠梯上,盯着一排状态灯发呆:我们刚把客户的数据库业务迁到 Windows Server 2022 + “存储空间直通”(Storage Spaces Direct,下文简称 S2D)的超融合集群上,指标在白天都很漂亮,怎么到夜里高并发 ETL 就掉链子?

这篇文章,就是那一夜到天亮的优化记录。不是“教科书式”的满分答案,而是一段有汗有坑的实战路线:硬件选型 → S2D 架构要点 → Windows/网络/RDMA 调优 → 卷/文件系统/布局策略 → SQL 数据/日志/TempDB 的放置与参数 → 基准压测与回归 → 故障与坑的现场解法。我会把关键命令、参数、表格和实际数据都写出来,新手能抄作业,老手能对表调参。

1. 现场环境与目标

1.1 目标

  • 高并发写入(夜间 ETL)不抖动
  • 事务日志延迟稳定 < 3 ms
  • 随机读 ≥ 200K IOPS(64K 块),顺序吞吐≥ 6 GB/s(集群整体)

1.2 机房与硬件(实配)

模块 型号/数量 关键点
机架 42U,双路 32A,A/B 路供电 上下风道清洁,冷通道送风
集群节点 4 台 2U 服务器,双路 Intel Xeon Gold(或 AMD EPYC 对等) 每台 512 GB RAM
加速盘(Cache) 每节点 2× NVMe U.2 3.2 TB(企业级,写入放大低) 专供 S2D Cache
容量盘(Capacity) 每节点 8× SATA/SAS SSD 3.84 TB All-Flash
网络 每节点 2× 25GbE(Mellanox/Intel RDMA),1× 1Gb 管理 走 RoCEv2,Jumbo 9014
交换机 2× 25/100GbE,可堆叠,DCB 支持 开启 PFC/ETS
系统 Windows Server 2022 Datacenter(含 S2D) 版本统一、补丁齐全
数据库 Microsoft SQL Server 2019/2022 兼容 ReFS

S2D 在 All-Flash 场景下会自动识别 NVMe 做写缓存,SAS/SATA SSD 做容量层。我们的 ETL 夜间写压力大,选 4 节点起步、NVMe×2 保证足够的写吸收能力。

2. 架构与设计要点(先定“地基”)

2.1 S2D 的盘层与冗余

Cache 层:NVMe;容量层:SSD

数据库卷冗余:

事务日志(Log):3-way Mirror(最稳的写延迟)

热数据(OLTP/活跃索引):3-way Mirror

冷/历史数据(报表/明细归档):Mirror-accelerated Parity(MAP)(前端镜像、后端奇偶,既保证写入又节省容量)

文件系统:ReFS + 64K Allocation Unit,DB 卷关闭 Integrity Streams(SQL 自带校验,避免重复校验开销);备份卷开启完整校验与去重。

2.2 卷布局与大小粒度

小文件不代表小块。数据库场景把 Interleave(条带)设为 256 KB 或 512 KB 更合适。

列数(Columns):按节点/磁盘并行度确定,通常 ≥ 8,避免热节点。

Write-back Cache(WBC):All-Flash 默认较小,针对高写入卷手动放大到 8–32 GB(按卷/按节点评估),减少写放大与抖动。

3. 从零到可跑:创建集群与启用 S2D

以下命令均在提升权限的 PowerShell 中执行。节点名按你的环境替换。

# 3.1 基础检查
Get-PhysicalDisk | ft FriendlyName,CanPool,MediaType,BusType,HealthStatus -Auto
Update-StorageFirmware -All  # 统一固件版本,避免奇怪的超时

# 3.2 创建故障转移群集(已预先建好 AD 计算机对象)
New-Cluster -Name HKSQLCL1 -Node HK-S2D01,HK-S2D02,HK-S2D03,HK-S2D04 -StaticAddress 10.10.10.10 -NoStorage

# 3.3 群集验证(磁盘/网络/系统)
Test-Cluster -Node HK-S2D01,HK-S2D02,HK-S2D03,HK-S2D04 -Include "Storage","Inventory","Network","System Configuration"

# 3.4 启用 S2D(自动识别 NVMe 为缓存)
Enable-ClusterS2D -Confirm:$false
Get-StoragePool -IsPrimordial:$false | ft FriendlyName,OperationalStatus,HealthStatus

4. RDMA/网络:把“回血通道”打通

S2D 的东西向流量(重建、读写转发)走 SMB3/SMB Direct,RDMA 配对、PFC 和 ETS要配置到位。

# 4.1 安装 DCB、启用 RDMA
Install-WindowsFeature Data-Center-Bridging
Enable-NetAdapterRdma -Name "pNIC1","pNIC2"
Set-SmbClientConfiguration -EnableMultiChannel $true -EnableBandwidthThrottling $false
Set-SmbServerConfiguration -EnableSMBDirect $true

# 4.2 QoS:SMB 置于优先级 3,开启 PFC,仅对 3 生效
New-NetQosPolicy "SMB" -SMB -PriorityValue8021Action 3
Enable-NetQosFlowControl -Priority 3
Disable-NetQosFlowControl -Priority 0,1,2,4,5,6,7
New-NetQosTrafficClass -Name "SMB" -Priority 3 -BandwidthPercentage 50 -Algorithm ETS

# 4.3 Jumbo Frame(网卡与交换机一致,9014)
Set-NetAdapterAdvancedProperty -Name "pNIC1","pNIC2" -DisplayName "Jumbo Packet" -DisplayValue "9014 Bytes"

坑 1(现场):交换机一侧忘了开 PFC,RDMA 随机掉,SMB Direct 被迫回退 TCP,延迟飙升。解决:交换机与网卡两端都要开 PFC,且只为优先级 3 开启,避免“全局暂停风暴”。

5. 卷与层:把盘做“对”比做好更重要

5.1 创建存储层(Tiers)与卷(数据库/日志/TempDB/备份)
$pool = Get-StoragePool -IsPrimordial:$false

# 5.1.1 创建性能/容量层
New-StorageTier -StoragePoolFriendlyName $pool.FriendlyName -FriendlyName PerfTier -MediaType SSD -ResiliencySettingName Mirror
New-StorageTier -StoragePoolFriendlyName $pool.FriendlyName -FriendlyName CapTier  -MediaType SSD -ResiliencySettingName Parity

# 5.1.2 事务日志卷(3-way Mirror,WBC 16GB,ReFS 64K)
New-Volume -StoragePoolFriendlyName $pool.FriendlyName -FriendlyName SQL_LOG `
  -FileSystem CSVFS_ReFS -Size 2TB -ResiliencySettingName Mirror `
  -AllocationUnitSize 65536 -ProvisioningType Fixed `
  -WriteCacheSize 16GB

# 5.1.3 热数据卷(3-way Mirror,列数/条带自定义)
New-VirtualDisk -StoragePoolFriendlyName $pool.FriendlyName -FriendlyName SQL_DATA_VD `
  -ResiliencySettingName Mirror -WriteCacheSize 32GB -Interleave 262144 -NumberOfColumns 8 -Size 20TB
Initialize-Disk -VirtualDisk (Get-VirtualDisk SQL_DATA_VD)
New-Volume -FriendlyName SQL_DATA -FileSystem CSVFS_ReFS -AllocationUnitSize 65536 -Path "C:\ClusterStorage\Volume1"

# 5.1.4 冷数据卷(MAP:前端 20% Mirror + 后端 80% Parity)
New-Volume -StoragePoolFriendlyName $pool.FriendlyName -FriendlyName SQL_COLD `
  -FileSystem CSVFS_ReFS -StorageTiers @(Get-StorageTier PerfTier, Get-StorageTier CapTier) `
  -StorageTierSizes 2TB,8TB -AllocationUnitSize 65536

# 5.1.5 备份卷(ReFS + Integrity + 去重)
New-Volume -StoragePoolFriendlyName $pool.FriendlyName -FriendlyName SQL_BAK `
  -FileSystem CSVFS_ReFS -Size 30TB -AllocationUnitSize 65536
Enable-DedupVolume -Volume "C:\ClusterStorage\VolumeX" -UsageType Backup

建议:数据库卷(SQL_DATA/SQL_LOG/TempDB)关闭 Integrity Streams:

Set-FileIntegrity -FileName "C:\ClusterStorage\Volume1\SQL_DATA" -Enable $false -IncludeStream:$true

备份卷和文件共享卷保持开启,并使用去重(2022 上对 ReFS/CSV 已成熟)。

5.2 CSV Cache 要不要开?

主要利好 Hyper-V 的未缓冲 I/O。SQL Server 默认使用缓冲 I/O,受益有限,还可能与内存策略冲突。

做法:不在 SQL 卷上开启 CSV Cache;只在需要的 Hyper-V 卷上按需开启。

6. Windows/SQL 层面:把系统“掰正”

# 6.1 电源计划:高性能
powercfg /S 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c

# 6.2 关闭不必要的实时杀毒(为 SQL/CSV、备份目录设置排除)
# Defender 示例(按需)
Add-MpPreference -ExclusionPath "C:\ClusterStorage\Volume1","C:\Program Files\Microsoft SQL Server"

# 6.3 SMB 加密:数据中心内网可关闭以减小开销(按合规评估)
Set-SmbServerConfiguration -EncryptData $false

# 6.4 SQL 服务器本身的关键项(T-SQL/策略)
# - 启用Instant File Initialization(授予SQL服务账号“执行卷维护任务”)
# - 预分配日志/数据文件尺寸,避免频繁增长
# - TempDB 多文件均衡(<= 每核 1,先 8-12 观察),放在 Mirror 卷
# - MAXDOP/Cost Threshold 按业务校准,这里略

7. 基准与监控:用数据说话

7.1 使用 DiskSpd 压测(对 CSV 路径)

# 顺序读吞吐
diskspd.exe -c100G -b1M -d60 -o8 -t8 -r -Sh \\HKSQLCL1\ClusterStorage\Volume1\test1.dat > seq_read.txt

# 随机读(64K),模拟报表/索引
diskspd.exe -c100G -b64K -d60 -o32 -t8 -r -w0 -Sh \\HKSQLCL1\ClusterStorage\Volume1\test2.dat > rand_read.txt

# 混合写(64K 30%写),模拟夜间ETL
diskspd.exe -c100G -b64K -d60 -o16 -t16 -r -w30 -Sh \\HKSQLCL1\ClusterStorage\Volume1\test3.dat > mix_30w.txt

7.2 PerfMon/计数器(必看)

  • Cluster CSVFs:CSVFS 读/写延迟
  • PhysicalDisk/Storage Spaces:Avg. Disk sec/Read/Write,Current Disk Queue Length
  • SMB Direct:RDMA Connections, Avg. Read/Write Queue
  • S2D:Cluster Storage Spaces Direct(*)\Cache Write Latency、Rebuild Rate
  • SQL:SQLServer:Buffer Manager、Databases: Log Flushes/sec & Log Flush Wait Time

8. 优化前后对比(来自现场数据)

指标 优化前(模板配置) 优化后(本文方案)
顺序读吞吐(1MB) 3.2 GB/s 7.1 GB/s
随机读 IOPS(64K) 92K 238K
混合读写 IOPS(64K/30%写) 58K 164K
日志写入延迟(P99) 12.7 ms 2.6 ms
夜间 ETL 峰值抖动 持续锯齿 平稳(偶见尖峰 < 5%)

主要收益点(按贡献大到小):

  • RDMA + PFC/ETS 正确落地(从 TCP 回退拉回 RDMA,延迟腰斩)
  • 日志卷 3-way Mirror + 放大 WBC(写入瞬态吸收更稳)
  • 条带/列数合适 + ReFS 64K + 关闭 Integrity Streams(减少小写放大与元数据开销)
  • 电源/杀软/加密细节(避免“隐形刹车”)

9. 数据库文件放置与参数清单(可直接抄)

类型 文件系统 冗余 建议
用户数据(高热) SQL_DATA ReFS 64K 3-way Mirror 关闭 Integrity;预分配;索引隔离可考虑同卷不同子目录
事务日志 SQL_LOG ReFS 64K 3-way Mirror 预分配大日志文件;增长固定步长;监控 Log Flush
TempDB SQL_TEMP(可与 DATA 同卷分目录或单独卷) ReFS 64K 3-way Mirror 多文件等分,初始 8–12 个;文件大小一致
冷/历史数据 SQL_COLD ReFS 64K MAP(20%/80%) 报表与归档,定期重建索引/压缩
备份 SQL_BAK ReFS 64K Parity 开 Integrity + 去重;后台校验

SQL 侧:

  • 授权服务账号“执行卷维护任务”(IFIs)
  • 数据/日志预分配,禁用自动小步增长
  • trace flag 1117/1118 在新版本已不再需要,采用默认行为即可
  • MAXDOP 与 Cost Threshold 按硬件与查询形态实测

10. 我踩过的坑(以及怎么爬出来)

固件不一致 → 间歇性 SCSI 重置

现象:Event ID 129/153,延迟尖刺。

解法:统一 SSD/NVMe 固件与 HBA/Backplane 固件,Update-StorageFirmware -All;必要时黑名单问题批次。

混用 4Kn 与 512e

现象:对齐/队列深度表现异常。

解法:集群内统一扇区规格;不混搭。

RDMA 配置“一边开一边没开”

现象:RDMA 连接非对称,SMB Direct 回退。

解法:交换机/网卡两端同时开 PFC,优先级一致,Jumbo 全链路一致。

WBC 过小导致夜间写入抖动

现象:ETL 高峰期间写入阶梯状卡顿。

解法:针对日志/热数据卷放大 WBC 至 16–32GB,观察“写入吸收”曲线。

在 SQL 卷开启 CSV Cache

现象:收益不明显甚至内存争用。

解法:SQL 卷关闭 CSV Cache,仅在 Hyper-V/VDI 卷上启用。

杀毒/实时扫描未做排除

现象:无规律延迟尖刺。

解法:对 CSV 路径和 SQL 安装/数据目录做排除。

11. 一套“可复用”的上线检查清单

  1.  Test-Cluster 全绿
  2.  RDMA:Get-SmbClientNetworkInterface 显示 RSS/Direct Enabled;netstat -xan 有 RDMA 通道
  3.  交换机:PFC=on(prio 3),ETS 配置一致,Jumbo=9014
  4.  ReFS 卷:Allocation Unit=64K;数据库卷 Integrity=off;备份卷 Integrity/Dedup=on
  5.  WBC:日志/热数据卷 ≥ 16GB
  6.  SQL:IFIs 打开;数据/日志预分配;TempDB 多文件等分
  7.  Defender/第三方杀软排除路径就位
  8.  PerfMon 基线一套(白天/夜间各 60 分钟)

12. 复盘与回报(生产观测 7 天)

夜间 ETL 峰值窗口从 02:00–04:00 的“锯齿”变为平台型曲线,P99 延迟从 12–15 ms 降到 2–3 ms

白天 OLTP 平均响应缩短 18–25%

备份窗口利用 ReFS + 去重,平均节省存储 38–52%(取决于备份策略)

13. 夜班后的机房清晨

凌晨 5:40,KVM 上的曲线终于平了。机房走廊尽头透进来一点浅蓝,像把风从冷通道里吹了出来。我把那套 PowerShell 脚本传到配置库,给下一位夜班值守留了句话:“S2D 不可怕,怕的是‘差一点点’。”
那一夜,我们把“差一点点”补上了:RDMA 的一个开关,WBC 的几个 GB,ReFS 的一个勾。数据库 I/O 性能不是凭空长出来的,它是被一项项基本功“对齐”出来的。

希望这份实操笔记,能让你下一次站在机柜前的时候,少流点汗、少挨几通电话。

附录:关键命令速查

# 查看 RDMA/SMB Direct 状态
Get-SmbClientNetworkInterface
Get-SmbMultichannelConnection

# 查看 S2D 健康
Get-StorageSubSystem *Cluster* | Get-StorageHealthReport

# 查看卷与虚拟磁盘参数
Get-VirtualDisk | ft FriendlyName,ResiliencySettingName,Interleave,NumberOfColumns,WriteCacheSize
Get-Volume | ft DriveLetter,FriendlyName,FileSystem,AllocationUnitSize

# 调整写回缓存
Set-VirtualDisk -FriendlyName SQL_LOG_VD -WriteCacheSize 16GB

# 观察 CSV/SMB 性能计数器(示例)
typeperf "\Cluster CSVFS File System(_Total)\Avg. sec/Write" -sc 60
typeperf "\SMB Direct Connection(_Total)\Current Send Queue Depth" -sc 60
目录结构
全文