如何修复不断累积的 NFS DELEG 锁,导致需要对客户端进行硬关闭?

如何修复不断累积的 NFS DELEG 锁,导致需要对客户端进行硬关闭?

我们传统的生产系统有一个数据服务器和一个计算客户端,它们通过 NFSv4 进行交互;两者都在 VMWare 虚拟化上运行。

我们已经确定,随着计算客户端软件的运行,在几天的时间里,lslocks | wc数据服务器上的 DELEG 锁的数量(以 衡量)会随着时间的推移而增加。

DELEG READ 锁的数量可能会瞬间激增至 100,000;从长远来看,DELEG 锁的数量会增加。几乎没有 DELEG WRITE 锁。当数据服务器上的 DELEG 锁数量达到约 15,000 个左右时,计算客户端几乎无法响应;大多数进程处于“D”状态。平均负载保持中等,但 CPU 利用率从约 90% 降至 10% 或更低。

即使几分钟后,终止计算客户端上的作业也不会减少锁定计数。从命令行关闭或重新启动通常会挂起;卸载 NFS 文件系统和 /tmp 可能会失败。

硬重置通常会导致重启时无法挂载 NFS 挂载点;但数据服务器上的锁定计数将大幅下降。硬关机加上 2 分钟的等待将允许虚拟机重新启动,包括所有 NFS 挂载点。

数据服务器运行的是 SLES 12 ( 4.1.16-2.g1a0d915-default);它有 12 个 vCPU 和 128GB RAM,大量使用 SSD 和 HD 支持的 SAN。nfs-kernel-server 的数据服务器版本是1.3.0-9.1。数据服务器每天计算大约 10 万个数据文件。其中一些文件被服务器本身覆盖和重命名,但主文件或主文件的临时副本应该可用。客户端代码知道这一点,并在需要时进行故障转移。

计算客户端运行的是 Debian Stable Stretch ( 4.9.0-6-amd64)。它有 24 个 vCPU 和 128 GB RAM。nfs-common 客户端版本是1:1.3.4-2.1。通过 NFS,读取这些数据文件,包括每天生成的 100k 个活跃文件集以及历史生成的文件。单个文件可能同时被多个进程读取。大多数文件由小型 bash 脚本访问,这些脚本一次访问 1 或 2 个文件并重塑数据以供上游使用。这些脚本由 python 和 perl 中的程序调用,其生命周期为数小时。

数据服务器有如下导出:

/mnt/ssd  172.26.188.199(rw,wdelay,root_squash,no_subtree_check,sec=sys,rw,secure,root_squash,no_all_squash)

计算客户端具有如下 fstab 条目:

172.26.188.198:/mnt/ssd           /mnt/ssd        nfs     defaults        3 3

计算客户端的架构比数据服务器更直接。运行 SLES 的早期 VM 实例也遇到过类似的问题;这促使对操作系统和计算作业进行彻底改革。这有助于减少问题,但并不能消除问题。

下一个明显的步骤是将现有的数据服务器移植到新的操作系统,但这是一个艰巨的任务,而且收益不确定。由于该行为涉及两个运行不同 Linux 版本和不同软件的不同计算客户端盒,我们怀疑问题一定是以下之一:服务器操作系统或 NFS 版本、客户端的高频重叠访问模式、数据服务器的文件重写模式(如果将数据服务器完全从 NFS 服务器中分离出来,nfsd 内部状态可能会得到纠正)、NFS 中可能存在的错误或我们配置它的方式存在错误。我也不愿意忽视我们的以太网或 SAN 中可能存在的问题,但目前认为这些问题不太可能出现。

除了彻底检修服务器、切换到分布式文件系统或设置定期重启间隔之外,哪些短期修复可能有助于保持数据服务器上的 DELEG 锁计数较低?

答案1

为了解决这个问题,我们尝试过更换文件服务器(仍然是 NFSv4)、硬件和内核版本(现在 NAS 上的 Linux 4.2.8 从 x86/VMWare/SLES 上的 4.1.16 改为 4.2.8)。尽管进行了这些更改,NFS4 DELEG 锁的累积仍然发生 —— 大概这是一个根植于纯本地(直接)存储的软件结构的问题。最终,我们放弃了 NFSv4,现在使用NFSv3诺洛克选项;出于性能原因,我们还使用了 noatime、nodiratime、noacl。锁不再累积,导致之前出现的灾难性减速。

相关内容