排查 Azure 文件存储性能问题

备注

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

本文列出了与 Azure 文件共享性能相关的常见问题,并介绍可能的原因和解决方法。 若要充分利用此故障排除指南,建议首先阅读了解 Azure 文件存储性能

适用于

文件共享类型 SMB NFS
标准文件共享 (GPv2)、LRS/ZRS
标准文件共享 (GPv2)、GRS/GZRS
高级文件共享 (FileStorage)、LRS/ZRS

常规性能故障排除

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

运行的是旧操作系统

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

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

运行 Windows 8.1 或 Windows Server 2012 R2 的客户端为 I/O 密集型工作负载访问 Azure 文件共享时,经历的延迟可能会高于预期。 请确保已安装 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 文件存储服务的限制。 限制可能会导致客户端性能不佳。

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

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

高延迟、低吞吐量或低 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 名称”属性筛选器 。

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

解决方法

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

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

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

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

    1. 在需要访问 Azure 文件共享的计算机中,使用存储帐户密钥装载文件共享,并将其映射到可用的网络驱动器(例如 Z:)。
    2. 转到磁盘管理并选择操作>创建 VHD
    3. 将“位置”设置为 Azure 文件共享映射到的网络驱动器,根据需要设置“虚拟硬盘大小”,然后选择“固定大小”。
    4. 选择“确定” 。 VHD 创建完成后,它将自动装载,并显示新的未分配磁盘。
    5. 右键单击新的未知磁盘并选择“初始化磁盘”。
    6. 右键单击未分配的区域并创建新的简单卷。
    7. “磁盘管理”中应会出现一个新的驱动器号(例如 E:),表示此 VHD 具有读/写访问权限。 在“文件资源管理器”中,应会在映射的 Azure 文件共享网络驱动器(在本示例中为 Z:)上看到新 VHD。 为了更清晰起见,应显示两个驱动器号:Z: 上的标准 Azure 文件共享网络映射,以及 E: 驱动器上的 VHD 映射。
    8. 与 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 个。 例如,如果你有 2 个 NIC,则可以使用以下 PowerShell cmdlet 将单个 NIC 的最大值设置为 2:Set-SmbClientConfiguration -ConnectionCountPerRssNetworkInterface 2

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

从 Linux 内核版本 5.4 开始,Linux NFS 客户端使用默认值 read_ahead_kb 128 kibibytes (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 上安装的防病毒软件引起的。

解决方法

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 文件,请在虚拟目录中为 allowSubDirConfig 属性指定 false。 更多详细信息请参阅此处

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

另请参阅

联系我们寻求帮助

如果你有任何疑问或需要帮助,请创建支持请求联系 Azure 社区支持。 你还可以将产品反馈提交到 Azure 反馈社区