NAS读取延时问题及NFS缓存机制

丶灬走出姿态 提交于 2020-07-28 17:58:43

业务场景:

  1. 前台通过RPC调用后台,在NAS指定路径生成图片
  2. 前台直接到NAS盘中获取该图片,在浏览器中进行展示

问题:

前台tomcat报出404错误,提示找不到该资源

问排查过程:

  1. 分别登录前后台服务器,进入上述图片路径,ls 图片名 检查图片是否存在。发现前后台服务器均能看到该图片。
  2. 在后台服务器上使用 mv 图片名 test ,将图片改名为test。再次 ls 检查,发现后台服务器上原图片已变为test,但前台服务器上任然只能看到原图片,无法看到test。间隔50s再次检查,发现前台服务器上原图片也已变为test。
  3. 小结:在后台服务器上对NAS盘内文件进行变更,无法被前台服务器立即捕获到。
  4. 检查磁盘加载配置 cat /etc/fstab 发现对应NAS盘加载配置为
XXX.XX.XXX.XX:/XXX_NAS_0001 /appnas nfs vers=3,rsize=1048576,wsize=1048576,hard,intr 0 0

man nfs查看/etc/fstab的说明文档,发现这样一段话

ac / noac

Selects whether the client may cache file attributes. If neither option is specified (or if ac is specified), the client caches file attributes.

To improve performance, NFS clients cache file attributes. Every few seconds, an NFS client checks the server's version of each file's attributes for updates. Changes that occur on the server in those small intervals remain undetected until the client checks the server again. The noac option prevents clients from caching file attributes so that applications can more quickly detect file changes on the server.

In addition to preventing the client from caching file attributes, the noac option forces application writes to become synchronous so that local changes to a file become visible on the server immediately. That way, other clients can quickly detect recent writes when they check the file's attributes.

Using the noac option provides greater cache coherence among NFS clients accessing the same files, but it extracts a significant performance penalty. As such, judicious use of file locking is encouraged instead. The DATA AND METADATA COHERENCE section contains a detailed discussion of these trade-offs.

大意是

  • 默认使用 ac 选项,开启缓存。客户端每间隔几秒取检查一次变更状态,这样就不能及时获取到文件更新状态;
  • 使用noac选项将会关闭缓存,因此需要检查文件属性的每个操作都被强制返回服务器,这就使得客户可以快速查看到文件更改;
  • 启用noac会导致性能下降,鼓励使用文件锁来代替它。

临时解决方案

在NAS盘挂载选项中添加 noac

使用root权限修改 /etc/fatab, 添加 noac选项

XXX.XX.XXX.XX:/XXX_NAS_0001 /appnas nfs vers=3,rsize=1048576,wsize=1048576,hard,intr,noac 0 0

使用 umount/ mount 重新挂载NAS盘。测试后确认问题暂时解决。

问题剖析

1. NFS缓存机制

(转自https://www.ibm.com/developerworks/cn/linux/l-cn-nfs/index.html)

如上图所示,NFS 文件系统使用 read,writeback,dirty 和 commit 四个队列,每个队列的单元数据结构都是 nfs_page,每个 nfs_page 都有一个 page 变量指向页高速缓存。

  1. 读方法 nfs_readpage 首先使用异步方式读取数据,如果异步方式失效,才使用同步方式,nfs_readpage_async 所读的数据都进入 read 队列中。
  2. 写方法 nfs_writepage 如果写数据超过一页(缺省是 4096 字节),使用异步方式提交数据,否则使用同步方式。nfs_writepage_async 所写的数据首先进入 writeback 队列,如果数据发生更改,则进入 dirty 队列,如果将更改的数据提交到 NFS 服务器上,则进入 commit 队列。这些队列或者因为超时,或者因为单元数量多于最大值,将被释放掉。

小结:读取数据时先读缓存,若缓存中没有该数据,则采用同步方式读取,所有操作都被强制返回服务器。

2. 根据缓存机制再次进行测试分析

测试前先在前后台服务器上挂载测试用的NAS盘,cd进入测试的NAS盘路径。注意不要使用noac选项,此时默认为ac模式。

  1. 在后台服务器NAS路径中创建文件dd if=/dev/zero of=test count=5 bs=1M
  2. 在前台服务器上查看该文件ls test,发现可以查看到
  3. 快速在前台服务器上执行ls test1, 此时必然报没有该文件。再到后台服务器上执行mv test test1,将test改为test1
  4. 快速再前台服务器上执行ls testls test1, 发现可以读到test, 但无法读到test1。即读的结果与第一次相同,与实际情况不符。

小结:对同一文件,第一次读取因为没有缓存(即异步方式读取失败),故采用同步方式读取(不读缓存),因此可以立即获取到变更。若紧接着进行第二次读取,因为此时存在缓存,异步方式可以读取成功,故不会进行同步读取。若在此过程中,在其它客户端对文件进行了操作,则变更无法被获取到。直到 nfs_writepage 写数据超过一页并提交,客户端检查到版本发生变化时,才会进行更新。

3. 再次对业务场景进行分析

了解清楚缓存逻辑后,再次询问相关开发人员,对业务场景进行分析。最后得知:

该业务场景允许用户在登录状态下,连续刷新页面。每次刷新都会重新向后台发起请求,重新生成图片(图片名称保持不变),前台再重新到NAS中获取并展示该图片。 小结分析:后台服务器对NAS中同一文件进行连续重新生成操作,同时在前台服务器上进行连续读。这就意味着,在获取到变更状态之前,前台服务器读到的都是缓存。

但是这样就带来了一个新的问题:第一次读取时,该文件被加载到了缓存中。后续就算缓存中不是最新的文件,也应当可以读取到第一版缓存中的文件。那为什么会出现“无法找到该资源”的情况呢?

再次回顾缓存机制: “nfs_writepage_async 所写的数据首先进入 writeback 队列,如果数据发生更改,则进入 dirty 队列,如果将更改的数据提交到 NFS 服务器上,则进入 commit 队列。”

如果文件已经删除了,那后续的修改实际上没有意义的,队列也就失去了价值。此处猜测,对于删除操作(REMOVE),会直接提交到NFS服务器,并写入到客户端缓存。以下进行测试验证:

测试前依旧注意使用默认的ac模式,cd进入测试的NAS盘路径。

  1. 在后台服务器NAS路径中创建文件dd if=/dev/zero of=test count=5 bs=1M
  2. 在前台服务器上查看该文件ls test,发现可以查看到
  3. 在后台服务器上连续执行
rm test
dd if=/dev/zero of=test count=5 bs=1M
  1. 迅速在在前台服务器上查看该文件ls test,发现报错
ls: cannot access test: No such file or directory

如此一来就证实了以上的猜想。

最终解决方案

  1. 为了避免影响NAS性能,继续使用默认的ac异步模式
  2. 业务上避免对同一文件的连续读写操作。具体的方式为:
  • 对于连续重新生成同一文件的场景:通过加时间戳等方式,每次生成不同的文件名,同时设置定时任务,定期清理,或在业务流程中增加删除规则;
  • 对于不同服务器连续修改NAS内同一文件的场景,增加文件锁机制。
参考文档:
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!