在 AWS EFS 上使用 flock 来模拟关键部分是否安全?

Phi*_*ßen 6 linux nfs filelock amazon-web-services amazon-efs

根据文档,AWS EFS(亚马逊弹性文件系统)支持文件锁定:

Amazon EFS 提供文件系统接口和文件系统访问语义(例如强数据一致性和文件锁定)。

在本地文件系统(例如 ext4)上,flock可用于在 shell 脚本中创建临界区。例如,这个答案描述了我过去使用的一种模式:

#!/bin/bash
(
  # Wait for lock on /var/lock/.myscript.exclusivelock (fd 200) for 10 seconds
  flock -x -w 10 200 || exit 1

  # Do stuff

) 200>/var/lock/.myscript.exclusivelock
Run Code Online (Sandbox Code Playgroud)

可以在 EFS 上应用相同的模式吗?Amazon 提到他们使用的是 NFSv4 协议,但它是否提供与flockext4相同的保证?

如果不是,您如何强制执行一个操作以专门在附加到同一 EFS 卷的所有 EC2 实例上运行?如果它适用于进程就足够了,因为我不打算运行多个线程。

还是我误解了 NFSv4 中提供的锁定支持?不幸的是,我不知道协议的细节,但是在分布式系统中提供原子性比在本地机器上要困难得多。

更新:小规模实验

当然,这不是证明,但在我的测试中,它适用于多个实例。目前,我认为该模式可以安全使用。不过,很高兴知道它在理论上是否合理。

Phi*_*ßen 5

它应该有效。

flock问题中的模式中使用的命令应该适用于所有 NFS 文件系统。这意味着,它也适用于实现 NFSv4 协议的 EFS。在实践中,到目前为止,我在使用它来同步不同 EC2 实例上的 shell 脚本时也没有遇到任何问题。


根据您的使用案例,您必须了解Linux 上文件锁定的陷阱,尽管其中大部分都不是 NFS 特定的。例如,上面的模式在进程级别上操作,如果要同步多个线程,则不能使用。

在阅读过程中,我遇到了一些老问题。在 2.6.12 之前的内核中,NFS 和系统调用似乎存在问题flock(例如,请参阅Linux 上的集群与 lockf)。

它不应该适用于此,因为它已在较新的内核中得到改进。查看该命令的源代码flock,您可以确认它仍然使用flock系统调用,但它可能由安全fcntl系统调用实现:

while (flock(fd, type | block)) {
  ...
  case EBADF:       /* since Linux 3.4 (commit 55725513) */
        /* Probably NFSv4 where flock() is emulated by fcntl().
         * Let's try to reopen in read-write mode.
         */
Run Code Online (Sandbox Code Playgroud)

注意:解决方法参考Linux内核中的这个commit可以找到:

由于我们可能使用 NFS 字节范围锁来模拟集群()锁,因此我们不能依赖 VFS 为我们检查文件打开模式。

  • 不幸的是,我可能刚刚发现了一个不起作用的情况。我在周末让两个 EC2 实例运行,一个持有一群,另一个等待获取它。似乎在某个时刻,持有集群的机器失去了与 NFS 服务器的连接(131090ms。Dec 2 05:04:32 ip-172-31-30-242 kernel: [105059.038603] nfs: server fs-e05dfc48 。 efs.us-west-2.amazonaws.com 未响应,超时)。此时,其他系统似乎能够获取锁,而原始系统似乎仍然拥有该锁。两个系统都带锁。 (5认同)
  • 是的,就我而言,我试图用它来防止多个节点承担“领导者”角色,这种角色将持续很长时间。它似乎不适合这种用例,因为 NFS 似乎可以回收锁,就像我看到的一个节点短暂失去与服务器的连接的情况一样。 (2认同)