python os.path.exists()对于存在的nfs挂载目录文件失败

时间:2014-01-22 19:39:31

标签: python linux django ubuntu-12.04 nfs

我基本上有一个网站服务器和另一个只存储文件的网站服务器。文件服务器通过挂载其中一个目录连接到主文件服务器。该网站运行Django所以我主要处理python。无论如何,我似乎遇到了一些问题,即文件被报告为不存在,即使它们实际存在。

基本上当我打电话时

filepath = '/path/to/file/on/nfs/share'
exists = os.path.exists(filepath)
即使文件确实存在,

exists 也是假的,我知道这样做是因为我将时间戳打印到日志文件中,该日志文件确切地显示了它的创建时间。我不确定会出现什么问题,但我知道os.path.exists的文档说

  

在某些平台上,如果未授予对所请求文件执行os.stat()的权限,则此函数可能返回False,即使路径实际存在。

我知道情况并非如此,因为这两个文件共享相同的组和组号,它们在两台服务器上共享相同的组号。它可能是陈旧的缓存还是类似的东西?

我的安装是通过fstab自动完成的。

Client side, the settings are:
filehost:/filefolder /localfolder nfs defaults,rsize=32768,wsize=32768

Server side, the settings are:
/filefolder webserver(rw,sync,no_root_squash,no_subtree_check)

修改

所以,我想更多的信息/细节。我正在运行一个Python子进程,在远程目录中生成一个文件。发出请求时,它会启动子进程并返回文件的预期位置。

在前端,有一个ping的url,它调用该文件的os.path.exists(),然后它通过ajax加载资源。

可疑的问题是,有时这个pinger会报告该文件在实际存在后几秒钟内不可用。这也是我认为可能存在过时缓存问题的原因。

所有文件及其中的目录都是所有者/组www-data,以及由django实例化的任何子进程。此问题似乎也不完全可重复。有时它会很快发挥作用,而其他时间会比预期的时间长几秒

1 个答案:

答案 0 :(得分:3)

这是由于找到了here的NFS缓存:

  

属性缓存缓存struct stat中的所有内容,因此可以从缓存中返回stat()和fstat()调用。如果需要查看文件的最新大小或mtime(或其他字段),则需要在stat()调用之前刷新文件的属性缓存。

     

请注意,如果缓存了文件句柄,stat()将返回该缓存文件的信息(因此结果与fstat()相同)。如果需要stat()具有给定文件名的最新文件,请先刷新文件句柄缓存。

我认为它的stat失败导致文件尚未进入缓存。 我在NFS手册页中找到了这个:

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.

但是那里也有警告,所以我只是忍受延迟:

  

使用noac选项可以在访问相同文件的NFS客户端之间提供更高的缓存一致性,但它会显着降低性能。因此,鼓励明智地使用文件锁定。 DATA AND METADATA COHERENCE部分包含对这些权衡的详细讨论。