问题描述
当您使用两个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
命令的实现是通过sleep和fstat观察文件属性(主要是文件大小)的变化,然后读入文件并输出。可见,tail -f
命令是否能实时输出文件内容主要取决于fstat的结果,由于metadata cache的存在,fstat轮询到的并不是实时的文件属性。因此,即使在NFS服务器端文件已经更新,但使用tail -f
命令却无法知道文件已经改动,于是输出就会出现延时。
解决方法
使用mount的noac选项可以关闭文件和目录属性的缓存。
mount -t nfs4 -o noac /mnt/
适用于
- 文件存储NAS