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

Is it safe to use flock on AWS EFS to emulate a critical section?

根据文档,AWS EFS (Amazon Elastic File System) 支持文件锁定:

Amazon EFS provides a file system interface and file system access semantics (such as strong data consistency and file locking).

在本地文件系统(例如 ext4)上,flock can be used in shell scripts to create a critical section. For example, this answer描述我过去使用的模式:

#!/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

能否在 EFS 上应用相同的模式?亚马逊提到他们正在使用 NFSv4 协议,但它提供与 ext4 上的 flock 相同的保证吗?

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

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

更新:小规模实验

当然不是证明,但在我的测试中它适用于多个实例。现在,我假设该模式可以安全使用。尽管如此,还是很高兴知道它在理论上是否合理。

应该可以。

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


根据您的用例,您必须了解 gotchas of file locking on Linux,尽管其中大部分都不是特定于 NFS 的。例如,上面的模式是在进程级别运行的,如果要同步多个线程就不能使用。

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

它不应该在这里应用,因为它在较新的内核中得到了改进。查看 flock 命令的 source code,您可以确认它仍然使用 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.
         */

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

Since we may be simulating flock() locks using NFS byte range locks, we can't rely on the VFS having checked the file open mode for us.