问题描述

当您使用两个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文件系统,默认情况下Kernel对文件和目录的属性维护了一份metadata缓存,文件和目录属性(包括许可权、大小、和时间戳)缓存的目的是减少NFSPROC_GETATTR远程过程调用(RPC)的需求。
  • tail -f命令的实现是通过sleepfstat观察文件属性(主要是文件大小)的变化,然后读入文件并输出。可见,tail -f命令是否能实时输出文件内容主要取决于fstat的结果,由于metadata cache的存在,fstat轮询到的并不是实时的文件属性。因此,即使在NFS服务器端文件已经更新,但使用tail -f命令却无法知道文件已经改动,于是输出就会出现延时。

解决方法

使用mountnoac选项可以关闭文件和目录属性的缓存。

mount -t nfs4 -o noac /mnt/

适用于

  • 文件存储NAS