NFS 挂载的客户端缓存以及如何使用 noac 选项
阿里云建议:如果需要使用多台 ECS 同时编辑一个文件,请使用 NFSv4 协议挂载
现象:
用户两台 ECS 挂载同一个 NFS 文件系统,在 ECS-A 上 append 写文件,在 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/
老佳遇到的问题:
我用 nas 挂在 k8s 容器中作为pod 容器( java 项目)日志目录使用,终端日志是实时输出的,写入日志文件的日志总是有延迟,不能实时写入。
参数按照上面调整,还是没有解决,一头雾水。后来才发现是 java 项目的日志插件,用的是异步机制。。。
以下是挂载参数,还有个 rsize 和 wsize 也是会影响性能的,这里没有体现
3695049908-per51.cn-shanghai.nas.aliyuncs.com:/uat-logs on /home/shared_disk/tomcat_logs type nfs4 (rw, relatime,sync,vers=4.0,namlen=255,acregmin=0,acregmax=0,acdirmin=0,acdirmax=0,hard, noac,noresvport,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=10.0.199.202,local_lock=none,addr=10.5.1.62)
共 0 条评论