通常的方法是使用flock utility,它是 util-linux 包的一部分。 FreeBSD 和 NetBSD 软件包、aiui 以及可能还有其他软件包也可用。 (对于 MacOSX,请参阅这个问题.)
The flock
命令可以执行读(“共享”)锁和写(“独占”)锁。它是基于flock(2)
系统调用,因此是合作社锁定(又名咨询锁定),但在大多数应用程序中都可以正常工作(但请参阅下面的文件是远程的情况)。
上面链接的手册页中有使用示例。最简单的用例是
flock /tmp/lockfile /usr/local/bin/do_the_update
flock /tmp/lockfile -s /usr/local/bin/do_the_rsync
两者都获得锁定/tmp/lockfile
,然后执行指定的命令(大概是一个shell脚本)。第一个命令获得排他锁;我本可以用-x
选项。第二个命令获取共享锁。
由于问题实际上涉及到需要网络锁,所以有必要指出的是flock()
在网络文件系统上可能不可靠。通常,目标文件应始终是本地的。
即使在非分布式应用程序中,您也需要考虑失败的可能性。例如,假设您在本地进行 rsync 以创建副本。如果主机在 rsync 处理过程中崩溃,您将得到不完整或损坏的副本。 rsync 可以从中恢复,但不能确定当主机重新启动时,rsync 是否会在文件被修改之前启动。这不应该是一个问题,但你绝对需要考虑到这一点。
在分布式应用程序中,情况更加复杂,因为整个系统很少出现故障。您可能会遇到不同服务器或网络本身的独立故障。
建议锁定不是持久的。如果锁定文件的主机在保持锁定的情况下崩溃并重新启动,则重新启动后将不再保持锁定。另一方面,如果持有锁的远程服务器崩溃并重新启动,它可能不知道自己持有锁,在这种情况下锁将永远不会被释放。
如果两台服务器 100% 知道彼此的状态,这不会是问题,但很难区分网络故障和主机故障。
您需要评估风险。与本地情况一样,如果文件服务器在 rsync 正在进行时崩溃,它可能会重新启动并立即开始修改文件。如果文件服务器关闭时远程 rsync 没有失败,它们将继续尝试同步,并且生成的副本将损坏。使用 rsync,这应该会在下一个同步周期自行解决,但在此期间您会遇到问题。您需要确定这件事有多严重。
您可以使用持久锁来防止文件服务器在启动时启动变元。每个 rsync 服务器在启动 rsync 之前在主机上创建自己的锁文件(并且在知道文件存在之前不会启动 rsync),并在释放读锁之前删除该文件。如果rsync服务器重新启动并且其指示符文件存在,则它知道在rysnc期间发生了崩溃,因此它必须删除指示符文件并重新启动rsync。
这会工作得很好most但如果 rsync 服务器在 rsync 期间崩溃并且从未重新启动,或仅在很长一段时间后重新启动,则可能会失败。 (或者,同等地,如果网络故障长时间隔离 rsync 服务器。)在这些情况下,可能需要手动干预。在文件服务器上运行一个看门狗进程会很有用,如果读锁定已保持太长时间(对于“太长”的某些定义),该进程会向操作员发出警报。