在 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.
根据文档,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.