SMB 服务器上 CPU 使用率过高的问题

本文探讨如何排查 SMB 服务器上 CPU 使用率过高的问题。

由于存储性能问题,CPU 使用率过高

存储性能问题可能会导致 SMB 服务器上的 CPU 使用率过高。 在进行故障排除之前,请确保 SMB 服务器上安装了最新的更新汇总,以消除srv2.sys中的任何已知问题。

在大多数情况下,你会注意到系统进程中 CPU 使用率过高的问题。 在继续之前,请使用进程资源管理器来确保 srv2.sysntfs.sys 消耗过多的 CPU 资源。

存储区域网络 (SAN) 方案

在总体级别上,SAN 整体性能可能看起来正常。 但是,在处理 SMB 问题时,单个请求响应时间是最重要的。

通常,此问题可能是由 SAN 中某种形式的命令队列引起的。 可以使用 Perfmon 捕获 Microsoft-Windows-StorPort 跟踪,并对其进行分析,以准确确定存储响应能力。

磁盘 IO 延迟

磁盘 IO 延迟测量的是创建磁盘 IO 请求与完成该请求之间的时间延迟。

在 Perfmon 中测量的 IO 延迟包括在硬件层中花费的所有时间,再加上在 Microsoft 端口驱动程序队列 (Storport.sys for SCSI) 中花费的时间。 如果正在运行的进程生成大型 StorPort 队列,那么测量到的延迟会增加。 这是因为 IO 必须等待才能调度到硬件层。

在 Perfmon 中,以下计数器显示物理磁盘延迟:

  • “物理磁盘性能对象” -> “Avg. Disk sec/Read counter” - 这显示了平均读取延迟。
  • “物理磁盘性能对象”-> “平均磁盘秒/写入计数器”- 这显示了平均写入延迟。
  • “物理磁盘性能对象”-> “平均磁盘秒/传输计数器” - 这显示了读取和写入的组合平均值。

“_Total”实例是计算机中所有物理磁盘的延迟平均值。 彼此实例表示单个物理磁盘。

注意

不要将这些计数器与 Avg. Disk Transfers/sec 混淆。它们是完全不同的计数器。

Windows 存储堆栈

本部分简要介绍了 Windows 存储堆栈。

应用程序创建 IO 请求时,会将请求发送到堆栈顶部的 Windows IO 子系统。 接下来,IO 沿着堆栈一路传输到硬件“磁盘”子系统。 然后,响应向上一路传回。 在此过程中,每个层执行其功能,然后将 IO 交给下一层。

显示存储堆栈流的示意图。

Perfmon 每秒不会创建任何性能数据。 相反,它使用由 Windows 中的其他子系统提供的数据。

对于“物理磁盘性能对象”,数据是在存储堆栈中的“分区管理器”级别捕获的。

当我们测量上一部分中提到的计数器时,我们测量的是请求在“分区管理器”级别以下花费的所有时间。 当分区管理器沿着堆栈向下发送 IO 请求时,我们会记录其时间戳。 当请求返回时,我们将再次记录其时间戳并计算时间差。 时间差就是延迟。

通过这样做,我们将计算在以下组件中花费的时间:

  • 类驱动程序 - 它管理设备类型,例如磁盘、磁带等。
  • 端口驱动程序 - 它管理传输协议,例如 SCSI、FC、SATA 等。
  • 设备微型端口驱动程序 - 这是存储适配器的设备驱动程序。 它由设备制造商提供,例如 Raid 控制器和 FC HBA。
  • 磁盘子系统 - 这包括设备微型端口驱动程序下面的所有内容。 这可以像连接到单个物理硬盘的电缆那样简单,也可以像存储区域网络那样复杂。 如果确定问题是由此组件引起的,可以联系硬件供应商,获取有关故障排除的详细信息。

磁盘队列

磁盘子系统在给定时间可以接受的 IO 量有限。 多余的 IO 将排队,直到磁盘可以再次接受 IO 为止。 在 Perfmon 物理磁盘延迟度量中,会考虑 IO 在低于“分区管理器”级别的队列中花费的时间。 随着队列的增长和 IO 必须等待更长时间,测量到的延迟也会增加。

“分区管理器”级别以下有多个队列,如下所示:

  • Microsoft 端口驱动程序队列 - SCSIport 或 Storport 队列
  • 制造商提供的设备驱动程序队列 - OEM 设备驱动程序
  • 硬件队列 - 例如磁盘控制器队列、SAN 交换机队列、阵列控制器队列和硬盘队列

我们还会考虑硬盘为主动服务 IO 所花费的时间,以及请求返回到“分区管理器”级别以便被标为“已完成”所花费的行程时间。

最后,我们必须特别注意端口驱动程序队列(针对 SCSI Storport.sys)。 在将 IO 移交给制造商提供的设备微型端口驱动程序之前,端口驱动程序是最后一个接触 IO 的 Microsoft 组件。

如果设备微型端口驱动程序由于其队列或其下的硬件队列饱和而无法再接受任何 IO,我们将开始在端口驱动程序队列上累积 IO。 Microsoft 端口驱动程序队列的大小仅受可用系统内存 (RAM) 限制,并且可能会变得非常大。 这会导致测量到的延迟较大。

枚举文件夹导致 CPU 使用率过高

要排查此问题,请禁用基于存取的枚举 (ABE) 功能。

若要确定已启用 ABE 的 SMB 共享,请运行以下 PowerShell cmdlet:

Get-SmbShare | Select Name, FolderEnumerationMode

Unrestricted = ABE 已禁用。
AccessBase = 已启用 ABE。

可以在服务器管理器中启用 ABE。 请导航至“文件和存储服务”>共享”,右键单击共享,选择“属性”,转到“设置”,然后选择“启用基于存取的枚举”。

显示“服务器管理器设置”下的“启用基于访问的枚举”选项的屏幕截图。

此外,还可将 ABELevel 调低到更低级别(1 或 2)来提高性能。

当枚举速度缓慢时,可以通过控制台或 RDP 会话在本地打开文件夹来检查磁盘性能。