确保客户端文件状态与NFS服务器同步

13

我正在寻找解决NFS客户端中旧数据的正确方式。考虑以下情况:

  • 两个服务器挂载了同一个NFS共享存储,其中有一些文件。
  • 1号服务器上的客户端应用程序删除了一些文件。
  • 2号服务器上的客户端应用程序尝试访问已删除的文件并因“过期的NFS文件句柄”而失败(没有什么奇怪的,这是预期的错误)。

(还可能有用的是,出于性能原因,缓存挂载选项在两个服务器上都很高。)

我想要理解的是:

  • 有可靠的方法检查文件是否存在吗?在上述场景中,对文件进行lstat返回成功,并且应用程序仅在尝试移动文件后失败。
  • 如何手动将客户端目录内容与服务器同步?
  • 在使用NFS时如何编写可靠的文件管理代码的一些常规建议?

谢谢。

3个回答

19
  • 有可靠的方法可以检查文件是否存在吗?在上述情况中,文件上的lstat返回成功,应用程序仅在尝试移动文件后失败。

这是正常的NFS行为。

  • 如何手动将客户端目录的内容与服务器同步?

这是不可能的,因为NFS假装是一个普通的POSIX兼容文件系统。

我曾经尝试过编写close() / open()来尝试缓解NFS客户端缓存的影响。在我的案例中,我需要读取写入到另一个服务器上的文件的信息。但即使重新打开的技巧几乎没有任何效果。而且我不能在写入端添加fdatasync(),因为这会减慢整个应用程序。

我对NFS的经验至今为止就是:你无能为力。对于关键的代码路径,我只是编码重试返回ESTALE的文件操作。

  • 如何编写可靠的文件管理代码以应对NFS的情况?

不管怎么骂我,如果您的客户想要可靠性,那么他们不应该使用NFS。

例如,我的公司推广使用适当的分布式文件系统(我有意省略品牌),如果客户希望获得可靠性。我们的核心软件不能保证在NFS上运行,并且我们不支持此类配置。但是,在我们的情况下,我们确实需要保证一旦数据写入FS,它们就在所有其他节点上可访问。

可以通过协调来实现NFS的一致性,但代价是性能降低,使NFS几乎无法使用。(请检查其挂载选项。)NFS像疯狂缓存以隐藏它是一个服务器文件系统的事实。要使所有操作一致,NFS客户端必须为每个小操作同步访问NFS服务器,绕过本地缓存。那将永远不会很快。

但是既然我们在谈论Linux,就可以建议软件的用户评估可用的集群文件系统。例如,RedHat现在正式支持GFS。我听说过人们使用CodaFS,但对此没有确切信息。


谢谢。你已经确认了我自己的NFS研究结果中的大部分。我想我会编写一堆ESTALE检查代码,因为我们没有计划迁移到其他存储。目前我不会接受这个答案,希望有人能提供更多相关主题的信息。 - begray
1
十年后,这个回复仍然是有效和相关的。对于“如果您的客户想要可靠性,那么他们不应该使用NFS”的评论点赞:D - Calabacin

7
我曾成功地在包含该文件的目录上执行 ls -l 命令。

1
这对我来说非常有效,实用的技巧确实很棒! - user5244399
1
解决了我的问题。有点可悲的技巧,但还是很不错的。 - rfay

5
您可以尝试使用“noac”挂载选项。
从nfs手册中:
除了防止客户端缓存文件属性外,“noac”选项还强制应用程序写入同步,以便本地对文件的更改立即在服务器上可见。这样,其他客户端在检查文件属性时可以快速检测到最近的写操作。
使用“noac”选项可以在访问相同文件的NFS客户端之间提供更大的缓存一致性,但会带来显着的性能损失。因此,建议谨慎使用文件锁定。
您可以有两个挂载点,一个用于需要同步的关键快速更改数据,另一个挂载点用于其他数据。
此外,请查看NFS锁定及其限制。
至于一般建议:

如果需要截断一个正在被多个主机并发读取的文件,一种方法是将内容写入临时文件,然后使用rename函数将该文件重命名为最终位置。

在同一文件系统上,此操作应该是原子的。


好的,这提出了一个好主意:在Serverfault上发布问题。开发人员没有办法以编程方式影响NFS(最多只能使用解决方法),而管理员必须更经常地处理NFS和运行在其上面的应用程序。因此,后者拥有更多的经验,并可能提供更多的建议。 - Dummy00001
链接的NFS锁定文章现在已经消失了,你有没有替代品? - Tim Post

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接