排查 Azure 文件存储 性能问题

适用于: ✔️ SMB 和 NFS Azure 文件共享

备注

本文中引用的 CentOS 是 Linux 分发版,将达到生命周期结束(EOL)。 请根据您的使用情况进行规划。 有关详细信息,请参阅 CentOS 生命周期指南

本文列出了与 Azure 文件共享性能相关的常见问题,并介绍可能的原因和解决方法。 若要从此故障排除指南中获取最大价值,请先阅读“了解Azure 文件存储性能”。

常规性能故障排除

首先,排除一些可能导致您出现性能问题的常见原因。

运行的是旧操作系统

如果客户端虚拟机(VM)Windows 8.1或Windows Server 2012 R2 或较旧的 Linux 发行版或内核运行,则访问Azure文件共享时可能会遇到性能问题。 升级客户端 OS 或应用以下部分中的修补程序。

Windows 8.1 和 Windows Server 2012 R2 的注意事项

访问 I/O 密集型工作负荷Azure文件共享时,运行 Windows 8.1 或 Windows Server 2012 R2 的客户端可能会遇到更高的延迟。 请确保已安装 KB3114025 修补程序。 此修补程序提升了创建和关闭句柄的性能。

若要检查是否已安装修补程序,请运行以下脚本:

reg query HKLM\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters\Policies

如果已安装修补程序,将看到以下输出:

HKEY_Local_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters\Policies {96c345ef-3cac-477b-8fcd-bea1a564241c} REG_DWORD 0x1

备注

从 2015 年 12 月开始,Azure 市场中的 Windows Server 2012 R2 映像默认包含修补程序KB3114025。

工作负荷受到限制

达到文件共享的 I/O 操作数(IOPS)、入口或出口限制时,系统会限制请求。 例如,如果客户端超过基线 IOPS,则Azure 文件存储服务会限制它。 限流可能会导致客户端性能下降。

若要了解标准文件共享和高级文件共享的限制,请参阅文件共享和文件缩放目标。 根据你的工作负载情况,通常可以通过将文件共享从 HDD(标准)迁移到 SSD(高级)来避免限流。

若要详细了解共享级别或存储帐户级别的限制如何导致高延迟、低吞吐量和常规性能问题,请参阅 “共享”或“存储帐户”受到限制

高延迟、低吞吐量或低 IOPS

原因 1:文件共享或存储账户被限流

若要确认共享或存储帐户是否受到限制,请在门户中访问和使用Azure指标。 你还可以创建警报,在共享被限流或即将被限流时通知你。 有关详细信息,请参阅通过创建警报来排查Azure 文件存储问题。

重要

对于标准存储帐户,限流发生在存储帐户级别。 对于高级文件共享,限制发生在共享级别。

  1. 在 Azure 门户中转到你的存储帐户。

  2. 在左侧窗格的“监视”下,选择“指标”。

  3. 选择File作为你的存储帐户范围的度量标准命名空间。

  4. 选择“事务”作为指标。

  5. 添加 响应类型的筛选器,然后检查是否限制任何请求。

    对于标准文件共享,如果请求在客户端帐户级别受到限制,则会记录以下响应类型:

    • 客户账户请求限流错误
    • 客户账户带宽限制错误

    对于高级文件共享,如果某个请求在共享级别受限,则会记录以下响应类型:

    • SuccessWithShareEgressThrottling
    • 成功共享入口流量限制
    • 成功启用共享IOPS限流
    • ClientShareEgressThrottlingError
    • ClientShareIngressThrottlingError
    • 客户端共享IOPS节流错误

    如果使用 Kerberos 对受限制的请求进行身份验证,则可能会看到指示身份验证协议的前缀,例如:

    • Kerberos成功与共享资源出口限流
    • Kerberos成功共享入口限制

    若要详细了解每个响应类型,请参阅指标维度

    显示“响应类型”属性筛选器的屏幕截图。

解决方案

如果使用的是高级文件共享,请增加预配的文件共享大小,以便提高 IOPS 限制。 若要了解详细信息,请参阅了解高级文件共享的配置

原因 2:元数据或命名空间工作负载繁重

如果大多数请求都是以元数据为中心的操作(例如createfileopenfileclosefilequeryinfoquerydirectory),则与读/写操作相比,可能会遇到更高的延迟。

要检查您的大多数请求是否以元数据为主,请按照原因 1 中所述的步骤 1-4 操作。 对于步骤 5,请不要添加“响应类型”筛选器,而是添加“API 名称”属性筛选器 。 有关详细信息,请参阅 按元数据 IOPS 监控利用率

显示 API 名称属性筛选器的屏幕截图。

解决方法

  • 检查是否可以修改应用程序以减少元数据操作的数量。

  • 如果使用高级 SMB Azure 文件共享,请使用元数据缓存

  • 在同一存储帐户中将文件共享划分为多个文件共享。

  • 将虚拟硬盘 (VHD) 添加到文件共享上,并从客户端装载 VHD,以便对数据执行文件操作。 此方法适用于单个编写器/读取器方案或包含多个读取器且无编写器的方案。 由于文件系统归客户端所有,而不是Azure 文件存储,因此元数据操作是本地的。 安装程序提供的性能与本地直连的存储的性能类似。 但是,由于数据位于 VHD 中,因此无法通过除 SMB 装载以外的任何其他方式(例如 REST API 或 Azure 门户)访问它。 1.从需要访问Azure文件共享的计算机中,装载共享并将其映射到可用的网络驱动器(例如 Z:)。

    1. 转到磁盘管理并选择操作>创建 VHD
    2. 将“位置”设置为 Azure 文件共享映射到的网络驱动器,根据需要设置“虚拟硬盘大小”,然后选择“固定大小”。
    3. 选择“确定” 。 VHD 创建完成后,它会自动装载,并显示一个新的未分配磁盘。
    4. 右键单击新的未知磁盘并选择“初始化磁盘”。
    5. 右键单击未分配的区域并创建新的简单卷。
      1. 你会在 磁盘管理 中看到出现一个新的驱动器号,它代表此具有读/写访问权限的 VHD(例如 E:)。 在文件资源管理器中,你会在已映射的 Azure 文件共享的网络驱动器上看到新的 VHD(本示例中为 Z:)。 为了清楚起见,存在两个驱动器号:Z:上的标准Azure文件共享网络映射,以及 E: 驱动器上的 VHD 映射。
      2. 与映射到 Azure 文件共享的驱动器(Z:)相比,在 VHD 映射驱动器(E:)上的文件上执行高负载元数据操作时,性能要好得多。 如果需要,可以断开映射的网络驱动器(Z:)的连接,并仍然访问装载的 VHD 驱动器(E:)。
    • 若要在 Windows 客户端上装载 VHD,还可以使用 Mount-DiskImage PowerShell cmdlet。
    • 若要在 Linux 上装载 VHD,请参阅 Linux 发行版的文档。 下面是一个示例

原因 3:单线程应用程序

如果使用的应用程序是单线程的,则此安装程序可能会导致 IOPS 吞吐量明显低于最大可能的吞吐量,具体取决于预配的共享大小。

解决方案

  • 通过增加线程数来提高应用程序的并行度。
  • 切换到支持并行度的应用程序。 例如,对于复制操作,可以在 Windows 客户端中使用 AzCopy 或 RoboCopy,或者在 Linux 客户端中使用 parallel 命令。

原因 4:SMB 通道数超过 4 个

如果您使用 SMB 多通道,并且通道数超过 4 个,这种情况会导致性能下降。 若要确定连接计数是否超过 4 个,请使用 PowerShell cmdlet Get-SmbClientConfiguration 查看当前的连接计数设置。

解决方案

为每个 NIC 配置 SMB 的 Windows 设置,以确保总通道数不超过 4 个。 例如,如果有两个 NIC,可以使用以下 PowerShell cmdlet 将每个 NIC 的最大值设置为 2 个: Set-SmbClientConfiguration -ConnectionCountPerRssNetworkInterface 2

原因 5:预读大小太小(仅限 NFS)

从 Linux 内核 5.4 版本开始,Linux NFS 客户端使用的默认 read_ahead_kb 值为 128 二进制千字节(KiB)。 此小值可能会减少大型文件的读取吞吐量。

解决方案

read_ahead_kb 内核参数值增加到 15 个兆字节(MiB)。 若要更改此值,请在 Linux 内核设备管理器 udev 中添加规则来持久设置预读大小。 执行以下步骤:

  1. 在文本编辑器中,通过输入并保存以下文本来创建 /etc/udev/rules.d/99-nfs.rules 文件:

    SUBSYSTEM=="bdi" \
    , ACTION=="add" \
    , PROGRAM="/usr/bin/awk -v bdi=$kernel 'BEGIN{ret=1} {if ($4 == bdi) {ret=0}} END{exit ret}' /proc/fs/nfsfs/volumes" \
    , ATTR{read_ahead_kb}="15360"
    
  2. 在控制台中,通过以超级用户身份运行 udevadm 命令并重新加载规则文件和其他数据库来应用 udev 规则。 若要使 udev 知道新文件,只需运行此命令一次。

    sudo udevadm control --reload
    

请求的延迟很高

原因

客户端 VM 可能位于与文件共享不同的区域中。 高延迟的其他原因包括客户端或网络导致的延迟。

解决方案

  • 从与文件共享位于同一区域的 VM 运行应用程序。
  • 对于存储帐户,请在 Azure 门户中通过Azure Monitor查看事务指标 SuccessE2ELatencySuccessServerLatency。 SuccessE2ELatency 与 SuccessServerLatency 指标值之间的高差表示网络或客户端可能导致的延迟。 请参阅 Azure 文件存储监视数据参考中的事务指标

客户端无法达到网络支持的最大吞吐量

原因

一个潜在原因是对标准文件共享缺乏 SMB 多通道支持。 目前,Azure 文件存储仅支持在单个通道上使用标准文件共享,因此从客户端 VM 到服务器只有一个连接。 此单一连接在客户端 VM 上使用单个核心,因此可从 VM 实现的最大吞吐量受单个核心的限制。

解决方法

Linux VM 上装载的 Azure 文件共享的性能低下

原因 1:缓存

性能低下的一个可能原因是禁用了缓存。 如果反复访问文件,则缓存非常有用。 否则,可能是产生开销。 检查是否在使用缓存,然后再禁用它。

原因 1 的解决方案

若要检查是否禁用了缓存,请查找 cache= 条目。

Cache=none 表示缓存已禁用。 使用默认装载命令或者在装载命令中显式添加 cache=strict 选项来重新装载共享,确保默认缓存或“strict”缓存模式已启用。

在某些应用场景中,serverino 装载选项可能会导致 ls 命令针对每个目录条目运行 stat。 当列出大型目录时,此行为会导致性能降级。 可在 /etc/fstab 条目中检查装载选项:

//azureuser.file.core.windows.net/cifs /cifs cifs vers=2.1,serverino,username=xxx,password=xxx,dir_mode=0777,file_mode=0777

还可以通过运行 sudo mount | grep cifs 命令并检查其输出,检查所用的选项是否正确。 下面是一个示例输出:

//azureuser.file.core.windows.net/cifs on /cifs type cifs (rw,relatime,vers=2.1,sec=ntlmssp,cache=strict,username=xxx,domain=X,uid=0,noforceuid,gid=0,noforcegid,addr=192.168.10.1,file_mode=0777, dir_mode=0777,persistenthandles,nounix,serverino,mapposix,rsize=1048576,wsize=1048576,actimeo=1)

如果不存在 cache=strictserverino 选项,请通过运行文档中的装载命令卸载并再次装载 Azure 文件存储。 然后,重新检查 /etc/fstab 条目是否具有正确的选项。

原因 2:限制

你可能遇到限流,你的请求可能被发送到队列中。 可以利用 Azure Monitor 中的 Azure 存储指标对此进行验证。 你还可以创建通知警报,在共享被限制速度或即将限制速度时收到提醒。 请参阅通过创建警报排查 Azure 文件存储问题

原因 2 的解决方案

确保您的应用程序在 Azure 文件 的缩放目标内。 如果使用的是标准 Azure 文件共享,可考虑转换到高级版。

原因 3:Azure 文件共享达到容量

如果 Azure 文件共享接近达到其容量,一个重要步骤是确定最大的文件和目录以优化存储。 此步骤可帮助你了解哪些文件和文件夹使用的空间最多。

解决方法

若要全面了解整个共享的存储使用情况,请装载共享的根目录。 此操作可以全面检查文件和目录的大小。 在文件共享的根目录中运行以下命令,以标识最大的文件和目录:

	cd /path/to/mount/point
	du -ah --max-depth=1 | sort -rh | head -n 20

此命令按大小降序显示 20 个最大文件和目录。 此显示提供了存储消耗的清晰概述。

如果无法装载共享的根目录,请使用 Azure 存储资源管理器或第三方工具分析存储使用情况。 这些工具提供了对文件和目录大小的类似洞察,而无需挂载共享。

Linux 客户端上的吞吐量低于 Windows 客户端上的吞吐量

原因

出现此问题的原因是如何在 Linux 上实现 SMB 客户端。

解决方法

  • 跨多个 VM 分散负载。
  • 在同一 nosharesock VM 上,使用具有选项的多个装入点,并将负载分散到这些装入点。
  • 在 Linux 上,请尝试使用一个选项 nostrictsync 进行装载,以避免每次 fsync 调用时强制进行 SMB 刷新。 对于 Azure 文件存储,此选项不会干扰数据一致性,但它可能会导致目录列表(ls -l 命令)上的过时文件元数据。 使用 stat 命令直接查询文件元数据将返回最 up-to日期文件元数据。

涉及大量打开/关闭操作的元数据密集型工作负载的延迟较高

原因

缺少目录租约支持。

解决方法

  • 避免在短时间内频繁打开和关闭同一目录。
  • 对于 Linux VM,请指定“actimeo=<sec>”作为装载选项,以延长目录条目缓存超时。 默认情况下,超时值为 1 秒,因此较大的值(例如 30 秒)可能会有所帮助。
  • 对于 CentOS Linux 或 Red Hat Enterprise Linux (RHEL) VM,请将系统升级到 CentOS Linux 8.2 或 RHEL 8.2。 对于其他 Linux 发行版,请将内核升级到 5.0 或更高版本。

文件和文件夹的枚举速度变慢

如果客户端计算机没有足够的缓存或内存用于大型目录,则可能会出现此问题。

若要解决此问题,请 DirectoryCacheEntrySizeMax 调整注册表值,以允许在客户端计算机上缓存更大的目录列表:

  • 位置:HKEY_LOCAL_MACHINE\System\CCS\Services\Lanmanworkstation\Parameters
  • 值名称:DirectoryCacheEntrySizeMax
  • 值类型:DWORD

例如,将其 0x100000 设置为并查看性能是否提高。

在 Azure 文件共享之间复制文件速度缓慢

尝试将文件传输到 Azure 文件服务时,可能会发现速度缓慢。 如果没有特定的最小 I/O 大小要求,请使用 1 MiB 作为 I/O 大小以获得最佳性能。

在 Windows 中将文件复制到 Azure 文件以及从中复制文件时速度缓慢

  • 如果您知道要通过写入来扩展的文件的最终大小,并且当文件中尚未写入的尾部为零值时,您的软件不会出现兼容性问题,请预先设置文件大小,而不要让每次写入都成为扩展写入操作。

  • 使用正确的复制方法:

    • 请使用 AzCopy 在两个文件共享之间进行任何传输。
    • 在本地计算机上的文件共享之间使用 Robocopy

过多的 DirectoryOpen/DirectoryClose 调用

原因

如果最频繁的 API 调用中包括 DirectoryOpen/DirectoryClose 调用,而你预计客户端不会发出这么多的调用,则问题可能是 Azure 客户端 VM 上安装的防病毒软件引起的。

解决方法

更新Microsoft Defender防病毒反恶意软件平台。 从 Microsoft 更新目录下载更新

SMB 多通道未被触发

原因

最近对Windows SMB 客户端或帐户 SMB 多通道配置设置所做的更改,而无需重新装载。

解决方案

  • 对Windows SMB 客户端或帐户 SMB 多通道配置设置进行任何更改后,卸载共享,等待 60 秒,然后重新装载共享以触发多通道。
  • 对于Windows客户端 OS,请生成具有高队列深度(例如 QD=8)的 IO 负载,例如,复制文件以触发 SMB 多通道。 对于服务器 OS,在 QD=1 时触发 SMB 多通道,这意味着一旦启动对共享的任何 IO,就会触发 SMB 多通道。

解压缩文件时性能降低

根据使用的确切压缩方法和解压缩操作,解压缩操作可能会在Azure文件共享上执行比本地磁盘慢得多。 这种较慢的性能经常发生,因为解压缩工具在执行压缩存档解压缩的过程中执行大量元数据操作。 为了获得最佳性能,请将压缩的存档从Azure文件共享复制到本地磁盘,将其解压缩到本地磁盘,然后使用 Robocopy(或 AzCopy)等复制工具将其复制回Azure 文件存储共享。 通过使用多个线程并行复制数据,Robocopy 等复制工具可以补偿相对于本地磁盘Azure 文件存储元数据操作性能的降低。

文件共享托管的网站出现高延迟

原因

文件共享上的文件更改通知数过高可能会导致高延迟。 此问题通常发生在文件共享上具有深层嵌套目录结构的网站上。 常见方案是 IIS 托管的 Web 应用程序,其中默认配置中的每个目录都设置了文件更改通知。 客户端注册的共享上的每个更改(ReadDirectoryChangesW)都会将更改通知从文件服务推送到客户端。 此过程会占用系统资源,并且随着更改数量的变化而恶化。 此条件可能会导致共享限制,从而导致客户端延迟较高。

若要确认,请使用门户中Azure指标。

  1. 在 Azure 门户中转到你的存储帐户。
  2. 在左侧菜单中的“监视”下,选择“指标”。
  3. 选择File作为你的存储帐户范围的度量标准命名空间。
  4. 选择“事务”作为指标。
  5. 添加 ResponseType 的筛选器,并检查是否有任何请求具有响应代码 SuccessWithThrottling(对于 SMB 或 NFS)或 ClientThrottlingError(对于 REST)。

解决方案

  • 如果不使用文件更改通知,请禁用它(首选)。

    • 通过更新 FCNMode 来禁用文件更改通知。
    • 通过在注册表中设置 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\W3SVC\Parameters\ConfigPollMilliSeconds 来将 IIS 工作进程 (W3WP) 轮询间隔更新为 0,然后重启 W3WP 进程。 若要了解有关此设置的详细信息,请参阅 IIS 的许多部分使用的常见注册表项
  • 增加文件更改通知的轮询频率以减少通知次数。

    根据要求将 W3WP 工作进程轮询间隔更新为更高的值(例如 10 或 30 分钟)。 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\W3SVC\Parameters\ConfigPollMilliSeconds设置 ,并重启 W3WP 进程。

  • 如果网站的映射物理目录具有嵌套目录结构,请尝试限制文件更改通知的范围以减少通知量。 默认情况下,IIS 使用物理目录(虚拟目录连接的目标目录)中的 Web.config 文件的配置,以及该物理目录中的任何子目录中的配置。 如果不想在子目录中使用 Web.config 文件,请在虚拟目录中为 false 属性指定 allowSubDirConfig。 更多详细信息请参阅此处

    将 Web.ConfigallowSubDirConfigIIS 虚拟目录设置设置为false从范围中排除映射的物理子目录。

另请参阅