注意

本文档适用于 Ceph 的开发版本。

RBD 排他锁

排他锁是一种旨在防止多个进程以非协调方式访问同一 Rados 块设备 (RBD) 的机制。排他锁广泛用于虚拟化(防止虚拟机相互覆盖写入)和 RBD 镜像(在基于日志的镜像中,它们是日志记录的先决条件;在基于快照的镜像中,它们是快速生成增量差异的先决条件)。

对于新创建的镜像,默认启用 exclusive-lock 特性。可以通过 rbd_default_features 配置选项或 rbd create 命令的 --image-feature--image-shared 选项来覆盖此默认设置。

注意

许多镜像特性,包括 object-mapfast-diff,都依赖于排他锁。禁用 exclusive-lock 特性将对某些操作的性能产生负面影响。

为了保持多客户端访问,exclusive-lock 特性实现了客户端之间的自动协作式锁转换。它确保在任何给定时间只有一个客户端可以写入 RBD 镜像,从而保护内部镜像结构(例如对象映射、日志或 PWL 缓存)免受并发修改。

排他锁对用户而言大多是透明的

  • 每当客户端(librbd 进程,或者如果是 krbd 客户端,则是客户端节点的内核)需要处理对已启用排他锁的 RBD 镜像的写入时,它首先会获取该镜像上的排他锁。如果锁已被其他客户端持有,则会要求该客户端释放它。

  • 每当持有 RBD 镜像排他锁的客户端收到释放锁的请求时,它会停止处理写入、清空其缓存并释放锁。

  • 每当持有 RBD 镜像排他锁的客户端正常终止时,锁也会正常释放。

  • 正常释放 RBD 镜像上的排他锁(无论是应请求还是由于客户端终止)使另一个后续客户端能够获取锁并开始处理写入。

警告

默认情况下,exclusive-lock 特性不会阻止两个或多个并发运行的客户端打开同一 RBD 镜像并轮流写入(无论是否在同一节点上)。实际上,它们的写入只是随着锁以协作方式来回自动转换而被线性化。

注意

要禁用客户端之间的自动锁转换,可以在获取排他锁时指定 RBD_LOCK_MODE_EXCLUSIVE 标志。这由 rbd device map 命令的 --exclusive 选项公开。

注意

exclusive-lock 特性与 RBD 咨询锁(rbd lock addrbd lock rm 命令)不兼容。

Blocklisting(封禁)

有时,先前持有 RBD 镜像排他锁的客户端不会正常终止,而是突然死亡。这可能是因为客户端进程收到了 KILLABRT 信号,或者因为客户端节点经历了硬重启或遭遇了电源故障。在这种情况下,锁永远不会正常释放。这意味着任何新出现的并试图写入镜像的客户端必须打破先前持有的排他锁。

然而,进程(或内核线程)可能会挂起或仅仅是与 Ceph 集群失去网络连接一段时间。在这种情况下,打破锁可能会带来灾难性后果:挂起的进程或连接问题可能会自行解决,原始进程随后可能与在此期间启动的进程竞争,从而以非协调和破坏性的方式访问 RBD 数据。

如果无法以标准的正常方式获取锁,则接管进程不仅会打破锁,还会封禁(blocklist)先前的锁持有者。这是在新客户端进程和 Ceph Monitor 之间协商的。

  • 收到封禁请求后,监视器会指示相关的 OSD 不再为旧客户端进程提供请求;

  • 在相关的 OSD 映射更新完成后,新客户端可以打破先前持有的锁;

  • 在新客户端获取锁后,它可以开始写入镜像。

因此,封禁是一种存储级资源 fencing(隔离)的形式。

注意

为了使封禁生效,客户端必须具有 osd blocklist 能力。此能力包含在 profile rbd 能力配置文件中,该配置文件通常应设置给所有使用 RBD 的 Ceph 客户端身份

由 Ceph 基金会为您呈现

Ceph 文档是由非营利性 Ceph 基金会 资助和托管的社区资源。如果您希望支持这项工作和我们的其他努力,请考虑 立即加入