在本深度解析系列的第一部分和第二部分中,我们剖析了 Ceph RGW 的核心基础:无状态前端、专用 RADOS 存储池、桶索引机制以及 head/tail 数据布局。我们探讨了 Ceph 对象网关 (RGW) 如何通过动态桶分片实现大规模可扩展性,以及包括垃圾回收和生命周期管理在内的后台进程如何自动化数据治理。
现在,我们将转向企业数据保护的两个关键功能:S3 对象版本控制 和 S3 对象锁定。这些功能将 Ceph 对象网关 (RGW) 从一个简单的对象存储转变为一个强大的数据保护平台,能够满足法规遵从性要求,防止意外删除,并支持不可变存储模式。
在本次深度解析的第三部分中,我们将首先从 S3 API 的角度探讨版本控制和对象锁定的概念。然后,我们将深入揭示 RGW 如何在内部实现这些功能,重点关注一个关键的架构组件:对象逻辑头 (OLH)。理解这一机制是理解 RGW 如何在保持我们期望的性能特征的同时高效维护版本历史的关键。
对象版本控制是一种机制,允许用户保留、检索和恢复存储在桶中的每个对象的每个版本。当启用版本控制时,每次对象修改 (PUT) 或删除都会创建一个新的、不可变的记录,而不是覆盖或删除现有数据。
如果没有版本控制,对象存储遵循“后写者胜”模型。上传一个与现有对象具有相同键的对象会静默替换它。DELETE 操作会永久删除对象。虽然简单,但此模型无法防止:
版本控制通过维护每个对象的完整历史记录来解决所有这些问题。当与 RGW 归档区域
(结合使用时,版本化对象可以在实现上述所有功能的同时,使生产桶保持精简高效。
状态 行为 未版本化 (默认) 对象的版本 ID 为null。覆盖会替换数据;删除会永久删除数据。 已启用 每次 PUT 都会创建一个具有唯一版本 ID 的新版本。 已暂停 新写入会获得null版本 ID,但现有版本会保留。
一旦在桶上启用了版本控制,就永远不能完全禁用它,只能暂停。这是一个有意的设计选择,旨在防止意外或恶意破坏版本历史。
当启用版本控制时,每次对对象的写入都会生成一个唯一的、系统分配的 版本 ID。此 ID 是一个不透明的字符串,唯一标识对象的版本。当客户端发出 GET 请求而不指定版本 ID 时,RGW 会返回 当前版本:该对象最近写入的版本。
当您在版本化桶中删除对象(不指定版本 ID)时,RGW 不会删除任何数据。相反,它会创建一个特殊的零字节对象,称为 删除标记*。此标记成为当前版本,导致后续的 GET 请求返回 404 Not Found 错误;尽管所有以前的版本都保持不变。
要从版本化桶中永久删除数据,您必须通过指定其版本 ID 来显式删除每个版本:
不!删除标记是永久元数据,用于保留删除历史。它们会无限期存在,除非显式移除:
为什么这很重要:在高流失率工作负载(频繁的 PUT/DELETE 循环)中,删除标记会静默积累,导致:
一个让很多用户忽略的关键细节是:每个版本都是对象的完整、独立副本。与文件系统快照或增量备份不同,S3 版本控制不存储版本之间的差异。当你上传一个 1 GB 的文件,然后修改一个字节,你的集群中现在存储了两个 1 GB 的对象。然而,可以使用分层存储将旧版本转移到更具成本效益的存储。
工作负载模式 启用版本控制后的影响 频繁少量更新的大文件 存储量迅速倍增 具有追加操作的日志文件 每次追加都会创建完整副本 每日覆盖的数据库转储 N 天 = N 个完整副本 配置文件频繁更新 可管理 (小文件)
最佳实践:在启用桶的版本控制之前,分析您的工作负载模式。版本控制非常适合不经常更改但需要保护的对象(文档、图像、备份)。对于不断更改的对象(日志、指标、临时文件)可能会很昂贵。
版本化桶的另一个考虑因素是 RGW 如何管理桶索引。正如本系列 第二部分 所讨论的,RGW 将桶索引条目分布到多个分片中以保持性能。然而,版本控制引入了一个约束:单个对象的所有版本条目必须驻留在同一个桶索引分片上。
分片分布不均:即使使用哈希分片,一个具有数千个版本的单个对象也可能创建“热点”,其中一个分片包含的条目明显多于其他分片。这破坏了分片旨在提供的均匀分布。
大 omap 警告:对象的每个版本都需要多个索引条目:对于具有 N 个版本的对象,大约需要 2 + 2N 个条目。由于所有这些条目都必须驻留在同一个分片上,因此一个经过大量版本控制的单个对象可以将分片推过 RADOS “大对象警告”阈值:
未来改进:RGW 开发团队正在积极改进有序桶索引,这将允许单个对象的版本条目跨越多个索引分片。这一架构更改将有效消除当前每个对象版本数量的实际限制(目前受 omap 大小限制,在最坏情况下约为 100,000)。这项工作是本系列博客 第二部分 讨论的更广泛的有序桶索引计划的一部分。
虽然版本控制可以防止意外更改,但它并不能阻止特权用户故意删除所有版本。S3 对象锁定 通过实现 一次写入多次读取 (WORM) 语义提供额外的保护层。一旦对象被锁定,在锁定过期之前,它不能通过 S3 端点删除或覆盖,即使是 RGW 管理员帐户也无法删除或覆盖。
对象锁定有一个关键的先决条件:必须启用版本控制。这种紧密耦合的存在是因为对象锁定保护的是特定的 *象版本,而不仅仅是对象键。
在 Ceph Tentacle 之前,对象锁定 只能 在桶创建时启用。这是一个重要的操作限制:如果您创建了一个没有对象锁定的桶,而后来需要 WORM 保护,您唯一的选择是创建一个新桶并迁移所有数据。
从 Ceph Tentacle 开始,您现在可以在现有版本化桶上启用对象锁定 (ceph/ceph)。这消除了一个主要的操作痛点,允许您在不进行数据迁移的情况下为生产桶添加合规性保护。
模式 行为 治理 普通用户无法删除受保护对象。但是,具有s3:BypassGovernanceRetention权限的用户可以覆盖锁定。适用于可能需要例外的内部策略。 合规 绝对不可变。任何用户,包括 RGW 管理员,都不能通过 S3 端点删除对象或缩短保留期。即使桶所有者也无法覆盖。法规遵从性(SEC 17a-4、FINRA 等)要求。
保留期指定锁定保持有效的时间。一旦设置为合规模式,此期间不能缩短;只能延长。
除了基于时间的保留,对象锁定还支持 *法律保留*,这是一个无论保留设置如何都能防止删除的标志。法律保留作为二元开关(开/关),*不需要* 保留期;它一直有效,直到明确移除。例如,这适用于诉讼场景,在这种场景中,数据必须无限期保留,直到法律程序结束。
重要提示:一个对象可以同时拥有保留期和法律保留。对象将一直受到保护,直到这两个条件都被清除。
对于受监管行业的组织,Ceph 的对象锁定实现已由 Cohasset Associates 独立评估,这是一家专门从事记录管理和信息治理的咨询公司。他们 2023 年 10 月的合规性评估(证实,Ceph 与对象锁定符合以下电子记录保存要求:
SEC 规则 17a-4(f) 和 18a-6(e):经纪自营商和基于证券的掉期实体不可重写、不可擦除记录格式 (WORM) 要求
理解对象锁定保护什么以及不保护什么至关重要。对象锁定强制在 S3 API 层进行。当 DELETE 请求到达对象网关 (RGW) 端点时,网关会检查锁定状态,如果对象受到保护,则拒绝操作。这意味着:
这并非 Ceph 独有的限制;它是任何软件强制保护固有的。对象锁定在应用程序层(S3 API)保护您的数据,但拥有底层存储基础设施根访问权限的人员完全在不同的信任边界上操作。
当与基础设施层的适当访问控制相结合时,对象锁定可针对 S3 层威胁提供强大保护并满足法规要求(SEC 17a-4 等)。RADOS 绕过场景需要特权集群访问,应通过单独的机制严格控制和审计。
现在我们了解了 API 语义,接下来我们将探讨 RGW 如何在底层实现版本控制。这就是对象逻辑头 (OLH) 变得至关重要的地方。
考虑一个简单的 GET 请求:GET /bucket/photo.jpg。在未版本化的桶中,这是明确的:只有一个具有该键的对象。但是,如果启用了版本控制,“photo.jpg”可能具有数十个版本。RGW 应该返回哪一个?
幼稚的解决方案是扫描所有版本并选择时间戳最新的版本。但这会对性能产生深远影响:
OLH 是一种机制,用于跟踪哪个版本实例是对象的“当前”版本。当您在没有版本 ID 的情况下访问 hoto.jpg 时,RGW 会使用 OLH 来确定要返回哪个版本实例。
注意:“现有算法使用 OLH Epochs,每个名称的新版本都会递增,用于将版本从最新到最旧进行排序。”
这种基于 Epochs 的方法即使在并发写入场景中也能确保一致的排序,并且对于版本可能无序到达的多站点复制至关重要。
![]()
OLH 机制包含一个 `olh_log`,用于记录版本历史的修改。更改不会直接更新 OLH 指针,而是先记录下来,然后应用。这种基于日志的方法:
olh_log 由 RGW 代码库中的 apply_olh_log() 等函数处理,这些函数评估待处理的更改并相应地更新当前版本指针。
随后的 GET 请求(不带版本 ID)将解析为删除标记并返回 404,而直接的版本访问仍然适用于所有以前的版本。
请注意 versioned_epoch 如何建立排序。我们的三个版本的纪元分别为 2、3 和 6;OLH 指向纪元 6,证实它是当前版本。
当我们删除 `eport.pdf 而不指定版本 ID 时,会创建一个删除标记:
OLH 现在指向一个新实例,其中 delete_marker: true 且纪元为 7。删除标记的实例条目确认它是一个零字节标记:
高效查找:不带版本 ID 的 GET 请求可以快速解析到当前版本,而无需扫描所有版本
多站点兼容性:`lh_log`设计支持版本可能在不同区域并发创建的复制场景
正如我们在 第二部分 中讨论的,生命周期管理通过基于策略的规则自动化数据治理。启用版本控制后,生命周期策略获得了管理版本历史的额外功能。
此策略无限期保留当前版本,保留最近三个非当前版本,并在 90 天后永久删除更旧的非当前版本:
版本必须至少是 NoncurrentDays(90 天)的非当前版本,并且
当生命周期策略和对象锁定都处于活动状态时,对象锁定优先。如果生命周期规则尝试删除锁定的对象版本,则删除将被阻止:
RGW 基于策略的云迁移功能允许您使用生命周期策略将数据分层到外部 S3 兼容端点(公共云、磁带网关等)。当对象锁定处于活动状态时,锁定的对象会在云迁移期间自动跳过,以保留 WORM 契约。
这种行为是有意的:从 Ceph 的角度来看,云迁移是一种 *破坏性* 操作:迁移后,本地副本通常会被移除并替换为存根。允许对锁定的对象执行此操作将违反不可变性保证。
这确保了合规性数据保留在您的 Ceph 集群上,直到保留期到期,无论可能适用的任何云分层策略。
每个对象版本都会在桶索引中创建额外的条目。一个桶如果有一百万个对象,平均每个对象有十个版本,则有 1000 万个索引条目。请相应地规划分片数量:
请注意,截至 2025 年 12 月,正在进行一项工作,旨在增强动态重分片以考虑版本化对象。运行早期版本的集群应将版本控制纳入其手动分片计数或动态重分片阈值。
RGW 支持 MFA 删除,这需要多因素身份验证才能永久删除对象版本或更改桶的版本控制状态。
启用后,任何在未提供有效 MFA 代码的情况下尝试永久删除版本的操作都将失败,并显示 ccessDenied。
通过本次深度解析的第三部分,我们探讨了 Ceph RGW 如何实现企业数据保护的两个基石功能。版本控制 提供了每个对象的完整历史记录,从而能够从意外修改和删除中恢复。对象锁定 增加了 WORM 语义,以实现法规遵从性和勒索软件保护。
这些功能的核心是 对象逻辑头 (OLH),这是一种优雅的架构解决方案,通过一层间接高效地维护版本历史。
结合第二部分中的生命周期管理功能,您现在对 RGW 的数据治理堆栈有了完整的了解:
如有相关问题,请在文章后面给小编留言,小编安排作者第一时间和您联系,为您答疑解惑。





