Bash 脚本:读写锁

2023-12-15

想象一下由多台 nix 机器组成的网络。专用节点存储文件并定期调度Task A修改这些文件。其他每个节点的调度Task B同步(rsync)这些文件到本地存储。

Task A可能需要相当长的时间,并且文件收集需要在所有节点上处于一致的状态。因此Task B不应该运行Task A在跑。

一个可能的解决方案是使用读写锁。Task A and Task B将分别在资源上放置写锁和读锁。

我想知道我们如何使用 unix shell 脚本来实现这样的锁定机制。


通常的方法是使用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 服务器。)在这些情况下,可能需要手动干预。在文件服务器上运行一个看门狗进程会很有用,如果读锁定已保持太长时间(对于“太长”的某些定义),该进程会向操作员发出警报。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Bash 脚本:读写锁 的相关文章

  • 在 OSX 和 GNU 中使用“find”删除带有数字的文件名

    我正在尝试搜索一个文件并删除名称中包含数字的类似文件 我的文件 txt from myfile 00 04 version txt myfile 00 txt find E iregex myfile 0 9 1 txt 删除 myfile
  • shell_exec 的输出被截断为 100 个字符

    当在 shell 中运行以下命令时 curl F file filename http 192 168 0 1 产生以下输出 Accuracy 0 0 1 classification Accuracy 0 0 1 classificati
  • 为什么我不能将 sed 的输出重定向到文件

    我正在尝试运行以下命令 someprogram tee dev tty sed s 2 gt output file 但当我去查看时 该文件始终是空白的 如果我删除 gt output file从命令末尾 我可以看到 sed 的输出 没有任
  • 如何删除最后一次出现模式后的所有行?

    我想删除最后一次出现模式之后的所有行 除了模式本身 file txt honor apple redmi nokia apple samsung lg htc file txt 我想要什么 honor apple redmi nokia a
  • 使用 sigaction(),c

    我正在读一些关于sigaction 来源来自我的课程笔记 我不确定我是否理解这段文字 信号掩码仅在以下持续时间内计算和安装 信号处理程序 默认情况下 信号 sig 发生时也会被阻塞 使用 sigaction 为特定信号安装操作后 它会保持安
  • 为什么总是./configure;制作;进行安装;作为 3 个单独的步骤?

    每次从源代码编译某些内容时 都会经历相同的 3 个步骤 configure make make install 我明白 将安装过程分为不同的步骤是有意义的 但我不明白 为什么这个星球上的每个编码员都必须一次又一次地编写相同的三个命令才能完成
  • 了解多个进程的并发文件写入

    从这里 UNIX 中文件追加是原子的吗 https stackoverflow com questions 1154446 is file append atomic in unix 考虑多个进程打开同一个文件并向其追加内容的情况 O AP
  • awk 子串单个字符

    这是columns txt aaa bbb 3 ccc ddd 2 eee fff 1 3 3 g 3 hhh i jjj 3 kkk ll 3 mm nn oo 3 我可以找到第二列以 b 开头的行 awk if substr 2 1 1
  • Bash 解析和 shell 扩展

    我对 bash 解析输入和执行扩展的方式感到困惑 对于输入来说 hello world 作为 bash 中的参数传递给显示其输入内容的脚本 我不太确定 Bash 如何解析它 Example var hello world displaywh
  • 在 bash 中使用单个命令为 shell 变量分配默认值

    我对 bash 3 00 shell 脚本中的变量进行了大量测试 如果未设置变量 则它会分配默认值 例如 if z VARIABLE then FOO default else FOO VARIABLE fi 我似乎记得有一些语法可以在一行
  • 仅打印“docker-container ls -la”输出中的“Names”列

    发出时docker container ls la命令 输出如下所示 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a67f0c2b1769 busybox tail f dev
  • 如何在 Linux 中编写文本模式 GUI? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 当我编写脚本 程序时 我经常想弹出一个简单的文本 gui 来提示输入 我该怎么做 例如 来自 Shel
  • 如何在bash中使用jq从变量中包含的json中提取值

    我正在编写一个 bash 脚本 其中存储了一个 json 值 现在我想使用 Jq 提取该 json 中的值 使用的代码是 json val code lyz1To6ZTWClDHSiaeXyxg redirect to http examp
  • 将相对符号链接转换为绝对符号链接

    如何在 bash 中递归地将相对符号链接转换为绝对符号链接 ln sf readlink f link link
  • 如何判断 Bash 中是否存在文件?

    这会检查文件是否存在 bin bash FILE 1 if f FILE then echo File FILE exists else echo File FILE does not exist fi 我如何只检查文件是否存在not ex
  • 有没有办法让我简化这些回声? [复制]

    这个问题在这里已经有答案了 我仍在学习如何编写 shell 脚本 并且我面临着一个挑战 让我更容易回显 Name1 Name2 Name15 我不太确定从哪里开始 我已经想法 但如果我搞砸了 我不想看起来很傻 有什么帮助吗 我实际上还没有尝
  • OSX bash 最小化窗口

    在 Mac 中并使用 bash shell 我想执行一个包含单个命令 启动 Jupyter Lab 的文件并立即最小化终端窗口 有没有办法在不安装第三方软件的情况下做到这一点 是的 只需使用osascript https ss64 com
  • Linux:在文件保存时触发 Shell 命令

    我想在修改文件时自动触发 shell 命令 我认为这可以通过注册 inotify 挂钩并调用来在代码中完成system 但是是否有更高级别的 bash 命令可以完成此任务 尝试 inotify 工具 我在复制链接时遇到问题 抱歉 但 Git
  • 在 bash 脚本中提取 XML 值 [重复]

    这个问题在这里已经有答案了 我正在尝试从 xml 文档中提取一个值 该文档已作为变量读入我的脚本中 原始变量 data is
  • ssh远程变量赋值?

    以下内容对我不起作用 ssh email protected cdn cgi l email protection k 5 echo k 它只是返回一个空行 如何在远程会话 ssh 上分配变量 Note 我的问题是not关于如何将本地变量传

随机推荐