租户端 存储 文件存储 常见问题 文件内容更新不同步问题解决(元数据缓存以及noac选项使用)

文件内容更新不同步问题解决(元数据缓存以及noac选项使用)

最近更新时间: 2023-03-15 17:31:24

问题现象
两台 Linux 云主机挂载同一个 NFS 文件系统,在云主机 A 上使用 append 方式写文件,在云主机 B 上用 tail -f 观察文件内容的变化。在 云主机 A 上写完之后,10-30 秒的延时后在云主机 B 上才能看到更新后的内容。但在相同的场景下,如果直接在 云主机 B 上打开文件(例如使用 vi 命令)则可立即看到更新的内容。
问题出现原因
与 NFS 协议 mount 命令的选项以及 tail -f 的实现相关,
用户使用此挂载命令:
sudo mount -t nfs -o vers=4,noresvport <挂载点IP>:/ <待挂载目标目录>
当云主机 B 以 NFS mount 命名挂载的文件系统,默认情况下 kernel 维护了一份文件和目录属性的 metadata 缓存。文件和目录属性包括许可权、大小、和时间戳记等,缓存的目的是减少 NFSPROC_GETATTR 远程过程调用(RPC)的次数。
tail -f 的实现是通过 sleep+fstat 来观察文件属性(主要是文件大小)的变化,然后读入文件并输出。因此,fstat的结果决定了 tail -f是否能实时输出文件内容。但是,由于文件及目录的 metadata 缓存的存在,fstat 轮询到的并不是实时的文件属性,因此, NFS 服务器端文件虽然已经更新,但 tail -f 却没法知道文件已经发生了变化,因此输出会有延时。
解决办法
使用 mount 命令挂载文件系统时增加 noac 选项可以禁用文件和目录属性的缓存。挂载命令如下:
sudo mount -t nfs -o vers=4 noac <挂载点IP>:/ <待挂载目标目录>
sudo mount -t nfs -o vers=3 noac,nolock,proto=tcp <挂载点IP>:/ <待挂载目标目录>