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

香港服务器使用Windows Server 2019时,如何针对Samsung PM1733 NVMe SSD优化文件系统I/O调度?

发布人:Minchunlin 发布时间:2025-08-31 09:10 阅读量:798


凌晨两点,香港机房的机柜门刚开,一排 2U 机器的橙绿灯在风里眨眼。我这次要优化的是一台落到香港节点的内容分发/虚拟化混合宿主:Windows Server 2019,数据盘是两块 Samsung PM1733(U.2,PCIe 4.0 x4,3.84TB,1 DWPD,支持双端口与 PLP)。按规格单盘顺序读最高 7 GB/s、随机读最高 150 万 IOPS,属于当年的顶级企业盘;并且带电容掉电保护(PLP),对服务器端写缓存策略的放开很关键。

业务方的诉求很朴素:

  • VHDX/镜像仓库 + 日志与小文件混部;
  • 白天主要大文件顺序读写、夜里虚拟化备份/合并产生大量小块随机;
  • 目标:把 4K 随机延迟拉低(P99 < 1ms),把 128K 顺序带宽打满,别再让 CPU 在 I/O 上空转。

环境与基线

硬件(节选)

规格
机型 2U 单节点(双路 Xeon/或单路 EPYC,PCIe Gen4 背板)
系统盘 SATA DOM
数据盘 Samsung PM1733 3.84TB × 2,U.2,PCIe 4.0 x4,1 DWPD,PLP
网卡 25GbE × 2(iWARP/RDMA 关闭,本次与磁盘无关)

软件

版本/说明
OS Windows Server 2019 Datacenter(最新补丁)
NVMe 驱动 Microsoft StorNVMe(系统自带)
测试工具 DiskSpd(微软出品)

基线测试(未优化,单盘直通卷)

使用 DiskSpd 进行 warmup 后测试(命令见下文),仅示例一组结果(实际请以你现场为准):

场景 指标 数值(未优化)
4K 随机读(8 线程,QD=64,总 QD=512) IOPS / 平均延迟 ~860k / 0.95 ms
4K 随机写(8×64) IOPS / 平均延迟 ~230k / 2.6 ms
128K 顺序读(8×4) 带宽 ~5.4 GB/s
128K 顺序写(8×4) 带宽 ~3.0 GB/s

先讲原理:在 Windows 上“调度 I/O”意味着什么?

和 Linux 上能切换 I/O 调度器不同,Windows Server 的磁盘 I/O 路径是“应用 → 文件系统/缓存管理器 → 卷管理 → Storport/StorNVMe → 控制器/设备”。NVMe 设备天生多队列、每核一队;要把盘喂满,更关键的是线程模型与 outstanding I/O(队列深度)的匹配,外加合适的文件系统与缓存策略。微软在 SDC 的演讲与文档里也一再强调使用 DiskSpd 进行路径压测与调优验证。

步骤一:固件/驱动与设备状态确认

查看 NVMe 盘固件与插槽信息

Get-PhysicalDisk | Select FriendlyName, BusType, MediaType, Size, HealthStatus
Get-Disk | Select Number, FriendlyName, FirmwareVersion, OperationalStatus
# 查看固件槽位/活动镜像(NVMe 支持多固件插槽)
$pd = Get-PhysicalDisk | ? {$_.FriendlyName -match "SAMSUNG"}
$pd | Get-StorageFirmwareInformation

其中 Get-StorageFirmwareInformation 能显示 NVMe 固件槽、活动镜像与可写槽位,便于后续升级校验。

必要时升级固件

企业盘建议使用三星数据中心工具(Samsung DC Toolkit)或厂商工具链批量刷写,支持命令行与离线模式(生产前做,注意维护窗口与备份)。

示例(工具命令片段,具体以手册为准):

DCToolkit --disk 1 --firmware-update --path <fw-file>

说明:PM1733 自带 PLP(掉电保护),这对后续启用更激进的写缓存策略是前提条件之一。

步骤二:电源与节能策略(别让 CPU 把 I/O“省”没了)

将电源计划切换为 高性能(禁用可能的节能抖动)。

powercfg /setactive SCHEME_MIN    # 高性能

(也可以用 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c 这个 GUID 直接激活。)

在“高性能”计划中,将 PCI Express → 链路状态电源管理 设为“关闭”(图形界面操作,避免链路省电影响 NVMe 时延)。

步骤三:写缓存策略(配合 PLP)

在 设备管理器 → 磁盘驱动器 → PM1733 → 属性 → 策略 中:

勾选 “启用设备上的写入缓存”;

结合 PLP 与机柜 UPS 条件,可考虑勾选 “关闭 Windows 对设备的写入缓存缓冲区刷新”,以获得更激进的写合并与更低写放大。(没有 PLP/UPS 时不要勾选这条!)

步骤四:文件系统与簇大小(NTFS / ReFS 的取舍)

怎么选?

以虚拟化/大文件顺序 I/O 为主(VHDX、镜像仓库):

  • NTFS:簇 64K,简单直接,工具兼容性最好;
  • ReFS:默认簇 4K 对大多数场景合适;大顺序 I/O 可考虑 64K(尤其大块顺序写为主)。

SQL/日志盘:官方与业界长期建议 NTFS 64K(数据库页对齐/减少簇管理开销)。

格式化示例(PowerShell)

# NTFS 64K(适合 VHDX/SQL/大文件)
Format-Volume -DriveLetter X -FileSystem NTFS -AllocationUnitSize 65536 -NewFileSystemLabel 'DATA_NTFS_64K'

# ReFS 64K(顺序 I/O 偏重时考虑;否则默认4K)
Format-Volume -DriveLetter Y -FileSystem ReFS -AllocationUnitSize 65536 -NewFileSystemLabel 'DATA_REFS_64K'

验证簇大小/扇区信息

fsutil fsinfo ntfsinfo X:
fsutil fsinfo sectorinfo X:

关注 Bytes Per Cluster(簇)、以及物理扇区信息(某些现代盘/控制器的原子扇区可能为 4K)。

步骤五:ReFS 的完整性流(Integrity Streams)与虚拟化/备份

ReFS 提供 Integrity Streams,可对用户数据计算校验并在镜像/校验环境下自修复,但它会带来额外的 CPU 与 I/O 放大。在承载 VHD/VHDX、备份仓库 等热点大文件时,通常建议关闭完整性流:

# 关闭整卷默认(根目录)
Get-Item 'Y:\' | Set-FileIntegrity -Enable $false
# 已有文件批量关闭
Get-ChildItem -Recurse 'Y:\' | Set-FileIntegrity -Enable $false

(根据工作负载再选择性开启。)

步骤六:多盘并行时的 Storage Spaces(条带、列数与对齐)

若你有 多块 PM1733 做条带或镜像,创建 Storage Spaces 的时候要把三件事对齐:

  • Interleave(条带块大小):默认 256KB(可用 PowerShell 创建时指定)。
  • 列数(NumberOfColumns):决定同时条带的盘数,与吞吐正相关(创建时指定)。
  • 卷的簇大小:最好让“数据条带总宽度 = 列数×Interleave”能被文件系统簇整除,减少跨条带写放大。
  • 例如 4 列 × 256KB = 1MB,那么用 NTFS 64K 或 ReFS 64K 都能良好对齐。
  • Parity(校验)卷写入慢的老痛点,很多时候就是条带/簇不对齐导致的。

创建示例(双盘 Simple 条带,仅演示)

$pool = Get-StoragePool -IsPrimordial:$false
New-VirtualDisk -StoragePoolFriendlyName $pool.FriendlyName `
  -FriendlyName NVMe_Simple `
  -ResiliencySettingName Simple `
  -NumberOfColumns 2 `
  -Interleave 262144 `
  -UseMaximumSize
Initialize-Disk -VirtualDisk (Get-VirtualDisk NVMe_Simple)
New-Volume -FriendlyName DATA -FileSystem NTFS -AllocationUnitSize 65536 -DriveLetter X

步骤七:监控与压测方法(Perfmon + DiskSpd)

建议的 Perfmon 计数器(物理盘或目标卷):

  • PhysicalDisk\Avg. Disk sec/Read / Write(时延);
  • PhysicalDisk\Disk Bytes/sec(吞吐);
  • PhysicalDisk\Avg. Disk Queue Length(队列深度);
  • CPU:Processor(_Total)\% Processor Time。

这些是官方/厂商文档中常用的衡量项。

DiskSpd 常用命令模板(X 盘为测试卷;-Sh 关闭系统缓存,-L 打印延迟分布):

:: 预热(顺序写,避免读放大)
diskspd -c50G -b128K -d20 -Sh -w100 -L X:\pre.dat

:: 4K 随机读,8 线程 * 每线程 QD=64(总 QD=512),持续60秒
diskspd -b4K -r -d60 -o64 -t8 -Sh -L X:\test.dat

:: 4K 随机写(注意写放大)
diskspd -b4K -r -d60 -o64 -t8 -w100 -Sh -L X:\test.dat

:: 128K 顺序读
diskspd -b128K -d60 -o4 -t8 -Sh -L X:\test.dat

:: 128K 顺序写
diskspd -b128K -d60 -o4 -t8 -w100 -Sh -L X:\test.dat

工具下载与使用说明见微软官方仓库。

优化后的对比(示例,思路与比例更重要)

在完成高性能电源计划、写缓存策略(基于 PLP)、NTFS 64K/或 ReFS 64K(按场景)、以及**(如有)Storage Spaces 条带/列对齐** 后,我在这台香港节点上得到的 样本结果(同样的测试模型):

场景 指标 未优化 优化后
4K 随机读(8×64) IOPS / 平均延迟 ~860k / 0.95 ms ~1.20M / 0.70 ms
4K 随机写(8×64) IOPS / 平均延迟 ~230k / 2.6 ms ~310k / 1.9 ms
128K 顺序读(8×4) 带宽 ~5.4 GB/s ~6.6–6.9 GB/s
128K 顺序写(8×4) 带宽 ~3.0 GB/s ~3.6–3.8 GB/s

这些数字受 CPU 代际、主板背板、驱动栈与线程模型影响很大,但提升方向与幅度在多台节点上是一致的:电源/缓存/文件系统对齐到位后,延迟与吞吐都能上一个台阶。PM1733 作为 PCIe 4.0 盘,本身的上限就摆在那里。

典型坑与现场解法

“写缓存缓冲区刷新”要不要关?

有 PLP + UPS → 可考虑关闭(提升写聚合与顺序写性能)。

无 PLP 或对一致性极敏感 → 不要关。

操作入口与 PLP 说明参考上文链接。

ReFS 完整性流导致 VHDX/备份仓库写入抖动

关闭目标路径的 Integrity Streams,写入延迟会明显稳定(尤其合并/块克隆场景)。

Storage Spaces Parity 写慢

很多案例是 Interleave、列数与簇大小没对齐(见“步骤六”);Parity 本身写放大更大,业务允许的话尽量用 Mirror 或 Simple + 上层做冗余。

扇区大小/对齐

用 fsutil fsinfo sectorinfo 确认 PhysicalBytesPerSectorForAtomicity/Performance 为 4096;遇到异常时先查控制器/固件兼容性再动注册表。(Windows 11 上与部分 NVMe 的 4Kn 行为曾经影响 SQL 安装,虽然本机是 Server 2019,但检查一遍心里更有底。)

线程/队列不合理

NVMe 多队列的优势需要多线程+足够 QD才能吃到;DiskSpd 的 -t 与 -o 是你最该先动的两个旋钮。微软与 SNIA 的资料里也用它做评估基准。

附:我用的检查/格式化/压测脚本片段(可直接抄)

# 0. 电源计划:高性能
powercfg /setactive SCHEME_MIN

# 1. 盘/固件信息
Get-PhysicalDisk | Select FriendlyName, BusType, MediaType, Size, HealthStatus
Get-Disk | Select Number, FriendlyName, FirmwareVersion, OperationalStatus
(Get-PhysicalDisk | ? {$_.BusType -eq 'NVMe'}) | Get-StorageFirmwareInformation

# 2. 新卷(NTFS 64K)
Initialize-Disk -Number 2 -PartitionStyle GPT
New-Partition -DiskNumber 2 -UseMaximumSize -DriveLetter X
Format-Volume -DriveLetter X -FileSystem NTFS -AllocationUnitSize 65536 -NewFileSystemLabel 'DATA_NTFS_64K'

# 3. 扇区/簇确认
fsutil fsinfo ntfsinfo X:
fsutil fsinfo sectorinfo X:

# 4. DiskSpd 示例(4K 随机读)
diskspd -b4K -r -d60 -o64 -t8 -Sh -L X:\test.dat

(DiskSpd 下载与说明:微软官方  仓库;PowerShell 存储/固件 cmdlet 见微软文档。)

做完这一切,Perfmon 上那条“Avg. Disk sec/Read/Write”曲线更平了,P99 尖刺也不再扎眼。广州同事凌晨发来消息说夜间备份合并时间从 1 小时出头降到了 40 分钟以内;CDN 汇总任务也不再卡在 I/O 等待。
我把机柜门关上,冷风被挡回了冷通道,风声一下子小了。掏出口袋里那张小纸条,勾掉最后一项“ReFS 完整性流确认”。电梯里,手机嗡了一下:白天的变更单回执“性能已恢复,用户无感”。这类事,第一次你会觉得只是调参;做多了,就知道它其实是在替团队把确定性从机房带回会议室。

目录结构
全文