我注意到 NFS 上有很多文件的目录
ls *
然后按 Ctrl-C 可能需要一段时间(比如 20 秒)ls 才会回来。
为什么?可以修复 ls 命令以提高响应速度吗?
答案1
当您运行时ls *
,首先发生的事情是 shell 获取当前目录的列表。如果目录很大并且服务器很慢,这可能需要一段时间。
一旦 shell 获得了当前目录中的文件名列表,它就会对该列表进行排序(与任何网络交互相比,这非常快),然后调用ls
.该ls
命令依次查找每个文件并检索其元数据(stat
调用)检查是否是一个目录;如果文件是目录,则ls
列出其内容而不是目录本身。
当您按Ctrl+时C,不会中断当前的 NFS 操作。您不能在任何地方中断文件系统操作,因为这可能会使系统处于不一致的状态。即使读取文件也可能会更新其访问时间。大多数时候,按照人类标准,对文件的基本读取或写入操作都是瞬时的,但 NFS 是一个例外,尤其是在慢速网络上传输大量数据的情况下。
因此按Ctrl+C只会生效:
- 如果 shell 当前正在生成文件名列表,则在完全检索该列表时;
ls
当服务器提供元数据时,如果已启动并且当前正在获取有关文件的元数据;- if
ls
已经启动并且当前正在列出一个目录,当列表被完全检索时,或者至少在它的一部分之后。
这不是命令的错误ls
(该命令甚至可能尚未启动)。这甚至不是 shell 的错:这是 NFS 的错。 NFS 相当慢。
答案2
假设:通过 NFS 遍历目录可能会一次性加载比您预期更多的数据。服务器端 IO 过多,导致单个 NFS 调用需要超过 20 秒。 mount withintr
选项可能允许 Ctrl-C 中断正在进行的呼叫。
Google 发现了一个 NFS 调用列表,其中包括 READDIRPLUS。基本上是 readdir + 然后是每个文件的 stat 。还有 getacl。换句话说,有一个 NFS 调用基本上可以做到这一点ls -l
(对于一定数量的文件)。而不是为每个文件发送单独的统计请求。
谷歌搜索 nfs readdirplus - 这看起来很合理。第一个结果是(付费)错误报告。
RHEL6:NFSv3 READDIRPLUS 极大地减慢了 NFS 目录的通配速度,从而导致性能问题
- 使用标准挂载的 RHEL 6.2,包含超过 3000 个目录的目录中的 glob 需要 218 秒(近四分钟)。
- 使用nordirplus选项挂载同一目录以禁用readdirplus调用,同一目录上的glob仅需要1.7秒
所以这似乎是一个有趣的调查方向。
编辑:请注意,您的示例ls *
也是通配符的使用。 ls .
会避免全球。如果这对您的具体问题有影响,可能是因为通配符发生在 shell 中,而不是 ls 中,这可能会影响 Ctrl-C 的处理方式。我怀疑这是否重要,但我觉得这是一个有趣的问题。
答案3
ls
该命令在 NFS 目录上运行缓慢可能有多种原因。
- 该目录可能不会自动挂载。
- 这些机器可能不在同一网络中。
然而,这是一个更普遍的想法,而不是特定的网络文件系统。要列出不排序的文件,您可以尝试ls -U
列出不排序的文件。从 的手册页来看ls
,
-U 不排序;按目录顺序列出条目。与 one_per_line 格式“-1”结合使用,它将立即显示文件并且没有内存限制。
有几种变体可以避免排序。您可以检查系统的手册页并尝试以下任一选项。
ls -f
ls -U
ls --sort=none
答案4
如果您有 ls 的别名也可能会导致速度变慢,请尝试 \ls 甚至 \ls -altr 或 ls 的任何其他选项。