NFS清理缓存的命令?

24

我在NFS客户端属性缓存方面遇到了问题。我正在使用一些服务器,其中一个是NFS服务器,其他的是NFS客户端服务器。

所有服务器都是Debian(Linux的lenny,2.6.26-2-amd64),版本如下。

 % dpkg -l | grep nfs
ii  libnfsidmap2                        0.20-1                     An nfs idmapping library
ii  nfs-common                          1:1.1.2-6lenny1            NFS support files common to client and server
ii  nfs-kernel-server                   1:1.1.2-6lenny1            support for NFS kernel server
在NFS服务器中,/etc/exports文件的内容如下:
/export-path   192.168.0.0/255.255.255.0(async,rw,no_subtree_check)
在 NFS 客户端中,/etc/fstab 内容如下所示:
server:/export-path     /mountpoint   nfs rw,hard,intr,rsize=8192,async 0 0

如您所见,"async"选项用于多客户端访问性能。不过有时会导致虚假缓存错误。

由于我正在维护许多服务器(并且我没有更改挂载选项的强大权限),我不想修改/etc/exports或/etc/fstab。如果我有一个可以使用用户权限“清理”NFS客户端属性缓存的命令行工具,那就足够了。

请告诉我是否有这样的命令。

谢谢,


(添加)

我所说的“虚假缓存错误”,是指

 % ls -l /data/1/kabe/foo                  
ls: cannot access /data/1/kabe/foo: No such file or directory
 % ssh another-server 'touch /data/1/kabe/foo' 
 % ls -l /data/1/kabe/foo
ls: cannot access /data/1/kabe/foo: No such file or directory
有时会发生这样的情况。 问题不在于文件内容,而是文件属性(=dentries信息),因为NFS声称它保证开关一致性(Close-to-Open consistency)。

我在研究解决此问题的可能方案时发现了这个问题(+1)。如果NFS不能提供一致性,我更喜欢没有本地缓存或者非常短的本地缓存到期时间。千兆局域网不应该是太大的障碍,因此我不希望有太多的性能损失。理想的解决方案是服务器监视文件系统的更改并在缓存需要被刷新时通知客户端,但我认为NFS不支持这种功能。 - Tronic
由于带宽在这里并不重要,而是延迟,因此千兆局域网仍然会对性能产生一定影响。顺便说一下,lookupcache=none使我的git clone时间从2.7秒增加到了20秒。 - Torsten Bronger
5个回答

27

根据你对 "false-caching errors" 的理解,执行 sync 可能会得到你需要的结果。这将刷新所有文件系统缓存。

如果需要,您还可以使用 /proc/sys/vm/drop_caches 清除内核中的 VM 缓存。

# To free pagecache
echo 1 > /proc/sys/vm/drop_caches

# To free dentries and inodes
echo 2 > /proc/sys/vm/drop_caches

# To free pagecache, dentries and inodes
echo 3 > /proc/sys/vm/drop_caches

谢谢您的回复。我在我的问题中补充了我所说的“错误缓存”是什么意思。这个问题不仅仅通过sync就能解决。我认为您提出的第二个建议命令是可行的,我会尝试一下。 - Tomoya Kabe
1
我有同样的问题,我想在特定文件夹上进行同步,假设我没有root权限,因此无法运行建议的命令。 - Zamir

15

在一个特定的进程中,调用opendir()closedir()来打开和关闭父目录会使NFS缓存失效。我在编写作业调度程序时使用了这个功能,非常非常有用。你也可以试试!

这是相关代码的行号(显示上下文中的使用):https://github.com/earonesty/grun/blob/master/grun#L820

这是我解决问题的唯一方法:如果作业#1已经完成,需要某些输出文件的作业#2会在这些文件可见的情况下启动。


非常感谢您提出的建议。 - mob
2
opendir() 肯定有效,而 sync 则不行。一个简单的 ls -la /data/1/kabe/ >/dev/null 就可以解决问题。 - famzah
4
我刚刚通过实验证实了这一点,它确实是非常有用的知识,所以感谢@erik-aronesty。我在nfs客户端的挂载选项中找不到任何提及此事的内容。你是否知道你是如何发现它的? - nickform
1
为了方便像我一样对Windows感到困惑的未来访问者,同样的实验在Linux上确认可行,但在Windows上则无法实现,即它不能与Windows的NFS客户端配合使用(今天在一个完全打过补丁的Windows Server 2016 Datacenter上进行了测试)。 - nickform
@nickform 是的,这已经在Linux上进行了测试。如果您能让Windows版本正常工作,那么您会很好奇哪个API起了作用。 - Erik Aronesty
1
这对我来说几乎可以工作,但在压力测试下还不够可靠。d = opendir(...)(void)readdir(d)closedir(d) 这个顺序似乎是完全可靠的。当然,readdir 会增加一次与 NFS 服务器的往返调用。 - Nemo

7
据我所知,syncasync选项并不是属性缓存的来源。 Async允许服务器延迟保存数据到服务器文件系统,例如在NFS服务器故障的情况下它会影响写持久性,但如果NFS服务器稳定,则async不会影响NFS客户端。
有一个lookupcache=positive的NFS挂载选项,可以用于防止负面查找缓存,例如当文件实际存在于服务器上时,NFS返回“没有该文件或目录”。请参见man nfs中的Directory entry caching

2
您正在看到NFS属性缓存的效果。请参阅man nfs,并查看DATA AND METADATA COHERENCE
默认情况下,NFS将属性缓存最少30秒(acregminacdirmin),最多60秒(acregmaxacdirmax)。您可以使用actimeo一起覆盖所有这些设置,或者使用noac完全禁用属性缓存。使用noac挂载选项后,OP所描述的行为将消失,但会影响性能。
如果您只是想查找新文件的外观,则lookupcache=positive很有用,但删除仍将通过属性缓存进行。

lookupcache=positive 的工作方式略有不同:如果指定了 pos 或 positive,则客户端假定正条目在其父目录的缓存属性过期之前都是有效的,但始终在应用程序使用它们之前重新验证负条目(来自文档:https://linux.die.net/man/5/nfs)。 - slava

-2

清除NFS服务器上的/var/lib/nfs/rmtab文件。

以下命令用于清除与内存相关的问题。但这也非常危险。有时它会导致托管在该服务器上的应用程序崩溃。

# sync

# To free pagecache
echo 1 > /proc/sys/vm/drop_caches

# To free dentries and inodes
echo 2 > /proc/sys/vm/drop_caches

# To free pagecache, dentries and inodes
echo 3 > /proc/sys/vm/drop_caches

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