有关在 NFS Azure 文件共享中使用大型目录的建议
本文提供有关使用包含大量文件的 NFS 目录的建议。 通常,将文件分散到多个目录来减少单个目录中的文件数是一个良好做法。 但是,在某些情况下,无法避免使用大型目录。 在处理装载在 Linux 客户端上的 NFS Azure 文件共享上的大型目录时,请考虑以下建议。
文件共享类型 | SMB | NFS |
---|---|---|
标准文件共享 (GPv2)、LRS/ZRS | ![]() |
![]() |
标准文件共享 (GPv2)、GRS/GZRS | ![]() |
![]() |
高级文件共享 (FileStorage)、LRS/ZRS | ![]() |
![]() |
以下装载选项特定于枚举,可在处理大型目录时降低延迟。
指定 actimeo
会将所有 acregmin
、acregmax
、acdirmin
和 acdirmax
设置为相同的值。 如果未指定 actimeo
,则 NFS 客户端会为每个选项使用默认值。
建议在处理大型目录时将 actimeo
设置为 30 到 60 秒。 将值设置在此范围内,可使属性在客户端的属性缓存中保持较长的有效时间,从而允许操作从缓存中获取文件属性,而不是通过网络提取它们。 这可以在缓存属性过期而操作仍在运行的情况下减少延迟。
下图比较了在单个目录中有 100 万个文件的工作负载中,使用默认挂载和设置 actimeo
值为 30 完成不同操作所需的总时间。 在我们的测试中,某些操作的总完成时间缩短了高达 77%。 所有操作都是用未别名化的 ls 完成的。
Nconnect
是一个客户端装载选项,可用于在客户端与 Azure 高级文件服务之间使用多个 TCP 连接进行 NFSv4.1。 建议使用 nconnect=4
的最佳设置,以减少延迟并提高性能。 对于使用来自多个线程的异步或同步 I/O 的工作负荷,Nconnect
尤其有用。 了解详细信息。
指定命令和操作的方式也可能会影响性能。 使用 ls
命令列出大型目录中的所有文件是一个很好的示例。
备注
某些操作(如递归 ls
、find
和 du
)需要文件名和文件属性,因此它们将目录枚举(用于获取条目)与每个条目的统计信息(用于获取属性)组合在一起。 建议在可能运行此类命令的装入点上为 actimeo 使用更高的值。
在某些 Linux 分发版中,shell 会自动为 ls
命令(如 ls --color=auto
)设置默认选项。 这会更改 ls
通过网络工作的方式,并将更多操作添加到 ls
执行。 为了避免性能降低,我们建议使用未别名化的 ls。 可以通过以下三种方式之一实现该操作:
使用命令
unalias ls
移除别名。 这只是当前会话的临时解决方案。对于永久更改,可以在用户的
bashrc/bash_aliases
文件中编辑ls
别名。 在 Ubuntu 中,编辑~/.bashrc
以移除ls
的别名。你可以直接调用
ls
二进制文件,例如/usr/bin/ls
,而不是调用ls
。 这允许你使用ls
,而无需任何可能位于别名中的选项。 可以通过运行命令which ls
找到二进制文件的位置。
在与其他命令一起使用 ls
时,如果不在意 ls
返回文件的顺序,则可以防止 ls
对其输出进行排序,从而提高性能。 对输出进行排序会增加巨大开销。
可以使用具有 ls
的 -f
或 -U
选项来防止对输出排序,而不是运行 ls -l | wc -l
来获取文件总数。 区别在于,-f
还会显示隐藏的文件,-U
不会。
例如,如果在 Ubuntu 中直接调用 ls
二进制文件,则会运行 /usr/bin/ls -1f | wc -l
或 /usr/bin/ls -1U | wc -l
。
下图比较了使用未别名化、未排序 ls
与已排序 ls
的输出结果所需的时间。
从 NFS 文件共享复制数据或从 NFS 文件共享备份到另一个位置时,为了获得最佳性能,我们建议使用共享快照作为源,而不是使用活动 I/O 的实时文件共享。 备份应用程序应直接在快照上运行命令。 有关详细信息,请参阅 NFS 文件共享快照。
开发将大型目录与 NFS 文件共享配合使用的应用程序时,请遵循这些建议。
跳置文件属性。 如果应用程序只需要文件名,而不需要文件属性(如文件类型或上次修改时间),则可以使用多个调用对系统进行调用,例如具有良好缓冲区大小的
getdents64
。 这将获取指定目录中的条目,但不包括文件类型,从而通过避免不需要的额外操作来加快操作速度。交错统计信息调用。 如果应用程序需要属性和文件名,我们建议将统计信息调用与
getdents64
交错进行,而不是使用getdents64
获取文件结束前的所有条目,然后对所有返回的条目执行 statx。 交错统计信息调用会指示 NFS 客户端同时请求文件及其属性,从而减少对服务器的调用数。 与高actimeo
值结合使用时,这可以显著提高性能。 例如,在每个getdents64
后放置 statx 调用,而不是[ getdents64, getdents64, ... , getdents64, statx (entry1), ... , statx(n) ]
:[ getdents64, (statx, statx, ... , statx), getdents64, (statx, statx, ... , statx), ... ]
。增加 I/O 深度。 如果可能,我们建议将
nconnect
配置为非零值(大于 1),并在多个线程之间分配操作,或使用异步 I/O。 这将使异步操作能够受益于与文件共享的多个并发连接。强制使用缓存。 如果应用程序正在查询仅装载了一个客户端的文件共享上的文件属性,请使用具有
AT_STATX_DONT_SYNC
标志的 statx 系统调用。 此标志可确保从缓存中检索缓存属性,而无需与服务器同步,从而避免为了获取最新数据而进行的额外网络往返来。