当我将数据转储到 NFS 挂载目录中时,读取文件模式(例如ls -l
)比读取普通文件列表(例如)慢几个数量级ls --color=never
。我想知道为什么。
如果没有向该目录写入任何内容,ls -l
则几乎立即返回。但是,如果我随后使用例如创建一些 IO dd if=/dev/zero of=dd.img count=100M && rm dd.img
,ls -l
则会挂起长达半分钟,但ls --color=never
或getdents
几乎立即返回。换句话说,一旦读取文件模式,ls
就会停滞,但前提是我同时写入同一目录。我在使用不同 NFS 选项安装的几个目录中看到了这种行为。
客户端运行的是 CentOS 6.1 客户端(内核版本 2.6.32-358.2.1.el6.x86_64)。我不知道服务器运行的是什么(某些专有高性能系统),而且我没有管理员权限。我的问题只是,在某些情况下是否会出现这种行为,如果是,是哪种情况?
非常感谢,
安德烈亚斯
答案1
getdents
并且ls --color=never
只需要读取目录。
ls -l
并且ls --color=auto
需要读取目录
以及所有目录条目对应的 inode. (ls -l
,因为它需要获取模式、链接数、所有者、大小和修改日期,因为它显示这些字段,并且ls --color=auto
,因为它需要获取模式(可能还有链接数和大小),因为它部分地从文件类型(普通文件、目录、fifo、符号链接等)、可写性、可执行性、setuid、setgid 和粘滞位(可能还有链接数和大小)确定颜色。)
从远程服务器获取大量信息可能需要花费大量时间,尤其是当服务器距离较远或本身速度较慢(包括负载过重)时。客户端通常会缓存结果,因此,当用户请求已检索的信息时,客户端可以显示缓存(保存)的结果,而不必再次获取它们。
如果没有任何内容写入目录,
ls -l
将几乎立即返回。
我怀疑 NFS 客户端(CentOS 系统的一部分)会询问 NFS 服务器“发生了什么事?”,然后服务器会回复“我很无聊。好久没有发生任何事情了。”因此客户端知道可以安全地向您显示缓存的信息。
但是,如果我随后创建(...一个文件...),
ls -l
将会挂起长达半分钟,...
客户端询问“发生了什么事?”,服务器回复“这边情况有变。”因此客户端知道其缓存无效,因此需要重新读取目录和所有 inode(通过服务器)。这也适用于ls --color=auto
。
…但
ls --color=never
或getdents
几乎立即返回。
由于这些命令不需要 inode 信息,因此唯一需要重新读取的是目录本身,这花费的时间要少得多。