问题现象

当您用 ECS 挂载同一个 NFS 文件系统,在 ECS-A 上追加写文件,在 ECS-B 上用 tail -f观察文件内容的变化。在ECS-A 写完之后,在 ECS-B 看到文件内容变化会有 10-30 秒的延时。然而相同的场景下,如果直接在 ECS-B 上打开文件(比如 vi)可以立即看到更新的内容。

原因

该现象与 mount 的选项以及 tail -f 实现相关。

用户使用的 mount 命令为:mount -t nfs4 /mnt/

对于在 ECS-B 上以这一方式 NFS mount 的文件系统,默认情况下 kernel 对文件和目录的属性维护了一份 metadata缓存,文件和目录属性(包括许可权、大小、和时间戳)缓存的目的是减少 NFSPROC_GETATTR 远程过程调用(RPC)的需求。

tail -f 的实现是 sleep+fstat 来观察文件属性(主要是文件大小)的变化,然后读入文件并输出。可见,tail -f 是否能实时输出文件内容主要取决于 fstat 的结果,由于 metadata cache 的存在,fstat 轮询到的并不是实时的文件属性。因此,即使在NFS服务器端文件已经更新了,但 tail -f 却没法知道文件已经改动了,于是输出就会出现延时。

解决方法

使用 mount 的 noac 选项可以 disable 文件和目录属性的缓存。

mount -t nfs4 -o noac /mnt/