新钛云服已累计为您分享897篇技术干货
简 介
在本深度解析系列的第一部分和第二部分中,我们剖析了 Ceph RGW 的核心基础:无状态前端、专用 RADOS 存储池、桶索引机制以及 head/tail 数据布局。我们探讨了 Ceph 对象网关 (RGW) 如何通过动态桶分片实现大规模可扩展性,以及包括垃圾回收和生命周期管理在内的后台进程如何自动化数据治理。
现在,我们将转向企业数据保护的两个关键功能:S3 对象版本控制 和 S3 对象锁定。这些功能将 Ceph 对象网关 (RGW) 从一个简单的对象存储转变为一个强大的数据保护平台,能够满足法规遵从性要求,防止意外删除,并支持不可变存储模式。
在本次深度解析的第三部分中,我们将首先从 S3 API 的角度探讨版本控制和对象锁定的概念。然后,我们将深入揭示 RGW 如何在内部实现这些功能,重点关注一个关键的架构组件:对象逻辑头 (OLH)。理解这一机制是理解 RGW 如何在保持我们期望的性能特征的同时高效维护版本历史的关键。
S3 对象版本控制:概念与原理
对象版本控制是一种机制,允许用户保留、检索和恢复存储在桶中的每个对象的每个版本。当启用版本控制时,每次对象修改 (PUT) 或删除都会创建一个新的、不可变的记录,而不是覆盖或删除现有数据。
为什么版本控制很重要
如果没有版本控制,对象存储遵循“后写者胜”模型。上传一个与现有对象具有相同键的对象会静默替换它。DELETE 操作会永久删除对象。虽然简单,但此模型无法防止:
意外覆盖:用户上传损坏的文件覆盖关键数据集
意外删除:脚本中的错误导致对生产数据发出 DELETE 命令
恶意行为:被泄露的凭证用于销毁数据
审计要求:法规要求保留历史记录
版本控制通过维护每个对象的完整历史记录来解决所有这些问题。当与 RGW 归档区域
(https://ceph.io/en/news/blog/2025/rgw-multisite-replication_part7) 结合使用时,版本化对象可以在实现上述所有功能的同时,使生产桶保持精简高效。
版本控制状态
每个桶都有以下三种版本控制状态之一:
状态 行为 未版本化 (默认) 对象的版本 ID 为null。覆盖会替换数据;删除会永久删除数据。 已启用 每次 PUT 都会创建一个具有唯一版本 ID 的新版本。 已暂停 新写入会获得null版本 ID,但现有版本会保留。
一旦在桶上启用了版本控制,就永远不能完全禁用它,只能暂停。这是一个有意的设计选择,旨在防止意外或恶意破坏版本历史。
版本 ID 和当前版本
当启用版本控制时,每次对对象的写入都会生成一个唯一的、系统分配的 版本 ID。此 ID 是一个不透明的字符串,唯一标识对象的版本。当客户端发出 GET 请求而不指定版本 ID 时,RGW 会返回 当前版本:该对象最近写入的版本。
]删除标记:软删除
当您在版本化桶中删除对象(不指定版本 ID)时,RGW 不会删除任何数据。相反,它会创建一个特殊的零字节对象,称为 删除标记*。此标记成为当前版本,导致后续的 GET 请求返回 404 Not Found 错误;尽管所有以前的版本都保持不变。
}恢复已删除对象
恢复很简单:要么删除删除标记,要么将特定版本复制回当前位置:
--bucket my-bucket --key report.pdf永久删除
要从版本化桶中永久删除数据,您必须通过指定其版本 ID 来显式删除每个版本:
--version-id "5ch0kwnw2Nv1l5JctIrUFDY1zd55.va"常见误解:“删除标记”
问题:“如果我删除对象的所有版本,垃圾回收过程会自动删除删除标记吗?”
不!删除标记是永久元数据,用于保留删除历史。它们会无限期存在,除非显式移除:
1. 生命周期策略:
}2. 手动删除:$ aws s3api delete-object --version-id
为什么这很重要:在高流失率工作负载(频繁的 PUT/DELETE 循环)中,删除标记会静默积累,导致:
桶索引膨胀(数百万个没有数据的条目)
严重的 ListObjects 性能下降
解决方法:为版本化桶配置生命周期策略,以定期清理过期的删除标记。
关键考虑事项:每个版本都是完整副本
一个让很多用户忽略的关键细节是:每个版本都是对象的完整、独立副本。与文件系统快照或增量备份不同,S3 版本控制不存储版本之间的差异。当你上传一个 1 GB 的文件,然后修改一个字节,你的集群中现在存储了两个 1 GB 的对象。然而,可以使用分层存储将旧版本转移到更具成本效益的存储。
此设计对特定工作负载具有重大影响:
工作负载模式 启用版本控制后的影响 频繁少量更新的大文件 存储量迅速倍增 具有追加操作的日志文件 每次追加都会创建完整副本 每日覆盖的数据库转储 N 天 = N 个完整副本 配置文件频繁更新 可管理 (小文件)
示例:日志追加反模式
考虑一个应用程序,它全天将日志条目追加到 S3 对象中:
# 消耗的存储空间:~528 MB (所有版本之和)对于涉及频繁修改大对象的工作负载,请考虑以下替代方案:
使用唯一键:写入 app-2025-01-15-10.log、app-2025-01-15-11.log 而不是覆盖
选择性禁用版本控制:对追加密集型和版本控制关键型数据使用单独的桶
激进的生命周期策略:使用具有短保留期的 NoncurrentVersionExpiration
最佳实践:在启用桶的版本控制之前,分析您的工作负载模式。版本控制非常适合不经常更改但需要保护的对象(文档、图像、备份)。对于不断更改的对象(日志、指标、临时文件)可能会很昂贵。
操作注意事项:桶索引分片与多版本
版本化桶的另一个考虑因素是 RGW 如何管理桶索引。正如本系列 第二部分 所讨论的,RGW 将桶索引条目分布到多个分片中以保持性能。然而,版本控制引入了一个约束:单个对象的所有版本条目必须驻留在同一个桶索引分片上。
这种设计有几个影响:
分片分布不均:即使使用哈希分片,一个具有数千个版本的单个对象也可能创建“热点”,其中一个分片包含的条目明显多于其他分片。这破坏了分片旨在提供的均匀分布。
大 omap 警告:对象的每个版本都需要多个索引条目:对于具有 N 个版本的对象,大约需要 2 + 2N 个条目。由于所有这些条目都必须驻留在同一个分片上,因此一个经过大量版本控制的单个对象可以将分片推过 RADOS “大对象警告”阈值:
每个对象的版本数 大致索引条目数 阈值级别 1,000 ~2,002 低 50,000 ~100,002 中等 100,000 ~200,002 超出阈值
当分片超过 200,000 个条目
(默认的 osd_deep_scrub_large_omap_object_key_threshold)时,Ceph 会发出 LARGE_OMAP_OBJECTS 健康警告。
未来改进:RGW 开发团队正在积极改进有序桶索引,这将允许单个对象的版本条目跨越多个索引分片。这一架构更改将有效消除当前每个对象版本数量的实际限制(目前受 omap 大小限制,在最坏情况下约为 100,000)。这项工作是本系列博客 第二部分 讨论的更广泛的有序桶索引计划的一部分。
S3 对象锁定:不可变存储
虽然版本控制可以防止意外更改,但它并不能阻止特权用户故意删除所有版本。S3 对象锁定 通过实现 一次写入多次读取 (WORM) 语义提供额外的保护层。一旦对象被锁定,在锁定过期之前,它不能通过 S3 端点删除或覆盖,即使是 RGW 管理员帐户也无法删除或覆盖。
对象锁定先决条件
对象锁定有一个关键的先决条件:必须启用版本控制。这种紧密耦合的存在是因为对象锁定保护的是特定的 *象版本,而不仅仅是对象键。
历史局限性(Tentacle 之前)
在 Ceph Tentacle 之前,对象锁定 只能 在桶创建时启用。这是一个重要的操作限制:如果您创建了一个没有对象锁定的桶,而后来需要 WORM 保护,您唯一的选择是创建一个新桶并迁移所有数据。
Ceph Tentacle 新功能
从 Ceph Tentacle 开始,您现在可以在现有版本化桶上启用对象锁定 (ceph/ceph)。这消除了一个主要的操作痛点,允许您在不进行数据迁移的情况下为生产桶添加合规性保护。
保留模式:治理与合规
对象锁定支持两种保留模式,每种模式具有不同的强制特征:
模式 行为 治理 普通用户无法删除受保护对象。但是,具有s3:BypassGovernanceRetention权限的用户可以覆盖锁定。适用于可能需要例外的内部策略。 合规 绝对不可变。任何用户,包括 RGW 管理员,都不能通过 S3 端点删除对象或缩短保留期。即使桶所有者也无法覆盖。法规遵从性(SEC 17a-4、FINRA 等)要求。
保留期
保留期指定锁定保持有效的时间。一旦设置为合规模式,此期间不能缩短;只能延长。
}'法律保留:无限期保护
除了基于时间的保留,对象锁定还支持 *法律保留*,这是一个无论保留设置如何都能防止删除的标志。法律保留作为二元开关(开/关),*不需要* 保留期;它一直有效,直到明确移除。例如,这适用于诉讼场景,在这种场景中,数据必须无限期保留,直到法律程序结束。
--legal-hold Status=OFF重要提示:一个对象可以同时拥有保留期和法律保留。对象将一直受到保护,直到这两个条件都被清除。
监管合规:第三方验证
对于受监管行业的组织,Ceph 的对象锁定实现已由 Cohasset Associates 独立评估,这是一家专门从事记录管理和信息治理的咨询公司。他们 2023 年 10 月的合规性评估(https://www.ibm.com/downloads/cas/PJZN8VE3) 证实,Ceph 与对象锁定符合以下电子记录保存要求:
SEC 规则 17a-4(f) 和 18a-6(e):经纪自营商和基于证券的掉期实体不可重写、不可擦除记录格式 (WORM) 要求
FINRA 规则 4511(c):该规则在格式和介质要求方面援引 SEC 规则 17a-4
CFTC 规则 1.31(c)-(d):商品期货交易公司基于原则的要求
理解对象锁定保护边界
理解对象锁定保护什么以及不保护什么至关重要。对象锁定强制在 S3 API 层进行。当 DELETE 请求到达对象网关 (RGW) 端点时,网关会检查锁定状态,如果对象受到保护,则拒绝操作。这意味着:
对象锁定保护的内容:
通过 S3 客户端(aws cli、SDK、应用程序)意外删除
泄露的 S3 凭证恶意删除
任何用户(包括桶所有者和 RGW 管理员帐户,在合规模式下)删除
针对 S3 API 的流氓脚本或勒索软件进行程序化批量删除
对象锁定不保护的内容:
直接的 RADOS 级别操作 (rados rm、radosgw-admin bucket rm --purge-objects)
存储介质的物理销毁
具有 Ceph 管理凭证的用户执行的集群级管理操作
# 这完全绕过了对象锁定——数据消失了这并非 Ceph 独有的限制;它是任何软件强制保护固有的。对象锁定在应用程序层(S3 API)保护您的数据,但拥有底层存储基础设施根访问权限的人员完全在不同的信任边界上操作。
当与基础设施层的适当访问控制相结合时,对象锁定可针对 S3 层威胁提供强大保护并满足法规要求(SEC 17a-4 等)。RADOS 绕过场景需要特权集群访问,应通过单独的机制严格控制和审计。
RGW 内部机制:对象逻辑头 (OLH)
现在我们了解了 API 语义,接下来我们将探讨 RGW 如何在底层实现版本控制。这就是对象逻辑头 (OLH) 变得至关重要的地方。
问题:解决歧义
考虑一个简单的 GET 请求:GET /bucket/photo.jpg。在未版本化的桶中,这是明确的:只有一个具有该键的对象。但是,如果启用了版本控制,“photo.jpg”可能具有数十个版本。RGW 应该返回哪一个?
幼稚的解决方案是扫描所有版本并选择时间戳最新的版本。但这会对性能产生深远影响:
- 每个 GET 都需要对桶索引进行范围扫描
- 成本将随着版本数量的增加而线性增长
- 并发写入可能会产生竞态条件
RGW 通过一层间接解决了这个问题:对象逻辑头。
什么是 OLH?
OLH 是一种机制,用于跟踪哪个版本实例是对象的“当前”版本。当您在没有版本 ID 的情况下访问 hoto.jpg 时,RGW 会使用 OLH 来确定要返回哪个版本实例。
Ceph 源代码在桶索引中定义了不同的条目类型 (cls_rgw_types.h):
};当启用版本控制时:
每个对象版本都作为具有唯一版本 ID 的 Instance 条目存储
OLH 条目跟踪哪个实例是当前版本
非版本化对象使用 Plain 条目
OLH Epochs:版本排序
RGW 使用 olh_epoch 计数器来建立版本排序。正如 Ceph GitHub 存储库中所述:
注意:“现有算法使用 OLH Epochs,每个名称的新版本都会递增,用于将版本从最新到最旧进行排序。”
— ceph/ceph PR (https://github.com/ceph/ceph/pull/31325)
当写入新版本时:
1. olh_epoch 递增
2. 在桶索引中创建新的 Instance 条目
3. 更新 OLH 以反映新的当前版本
这种基于 Epochs 的方法即使在并发写入场景中也能确保一致的排序,并且对于版本可能无序到达的多站点复制至关重要。
OLH 日志
OLH 机制包含一个 `olh_log`,用于记录版本历史的修改。更改不会直接更新 OLH 指针,而是先记录下来,然后应用。这种基于日志的方法:
允许安全的并发修改
支持多站点同步(每个区域维护自己的 olh_log)
允许从部分故障中恢复
olh_log 由 RGW 代码库中的 apply_olh_log() 等函数处理,这些函数评估待处理的更改并相应地更新当前版本指针。
删除标记和 OLH
在版本化桶中删除对象时,RGW 使用专用操作 (CLS_RGW_OP_LINK_OLH_DM) 创建删除标记。此操作:
创建一个标记为删除标记的特殊零字节 Instance 条目
更新 OLH 以指向此删除标记作为当前版本
随后的 GET 请求(不带版本 ID)将解析为删除标记并返回 404,而直接的版本访问仍然适用于所有以前的版本。
检查桶索引
您可以使用 radosgw-admin 检查桶索引条目:
$ radosgw-admin bi list --bucket my-bucketOLH 条目 跟踪当前版本:
}OLH 告诉我们:
report.pdf 的当前版本是实例 sTsGobhZm2cGravZvOmc9IbpXgIEM8R。当前纪元是 6,它不是删除标记。
每个对象版本都存在实例类型条目:
}请注意 versioned_epoch 如何建立排序。我们的三个版本的纪元分别为 2、3 和 6;OLH 指向纪元 6,证实它是当前版本。
当我们删除 `eport.pdf 而不指定版本 ID 时,会创建一个删除标记:
}现在 OLH 已经改变:
}OLH 现在指向一个新实例,其中 "delete_marker": true 且纪元为 7。删除标记的实例条目确认它是一个零字节标记:
}radosgw-admin object stat 命令可以提供更高级别的视图,一直到特定的对象版本:
$ radosgw-admin object stat --bucket my-bucket --object report.pdf --object-version sTsGobhZm2cGravZvOmc9IbpXgIEM8R这显示了从 RGW 视角看,对象的元数据、清单和版本信息。
关键要点
OLH 机制提供了几个基本属性:
高效查找:不带版本 ID 的 GET 请求可以快速解析到当前版本,而无需扫描所有版本
一致排序:基于纪元的系统确保确定性的版本排序
多站点兼容性:`lh_log`设计支持版本可能在不同区域并发创建的复制场景
安全并发访问:日志和应用模型处理并发写入者之间的竞态条件
带有版本控制的生命周期管理
正如我们在 第二部分 中讨论的,生命周期管理通过基于策略的规则自动化数据治理。启用版本控制后,生命周期策略获得了管理版本历史的额外功能。
版本化桶的过期操作
操作 效果Expiration(天/日期) 向当前版本添加删除标记(不删除数据)NoncurrentVersionExpiration在指定天数后永久删除非当前版本ExpiredObjectDeleteMarker当删除标记是唯一剩余版本时将其移除NewerNoncurrentVersions限制要保留的非当前版本数量
示例:版本保留策略
此策略无限期保留当前版本,保留最近三个非当前版本,并在 90 天后永久删除更旧的非当前版本:
}使用 AWS CLI 应用策略:
$ aws --endpoint=http://rgw:80 s3api put-bucket-lifecycle-configuration --bucket versioned-bucket --lifecycle-configuration file://lifecycle-policy.json理解 NoncurrentVersionExpiration 参数
NoncurrentVersionExpiration 规则有两个参数,它们共同控制版本保留:
}工作原理:只有当两个条件都为 true 时,版本才会被删除:
版本必须至少是 NoncurrentDays(90 天)的非当前版本,并且
必须有超过 NewerNoncurrentVersions(3 个)的较新非当前版本
假设您有一个对象 report.pdf,其版本历史如下:
└─ v1 - 2025-06-15 (179 天非当前) ✅ 删除生命周期和对象锁定交互
当生命周期策略和对象锁定都处于活动状态时,对象锁定优先。如果生命周期规则尝试删除锁定的对象版本,则删除将被阻止:
这确保了合规性要求始终优先于自动化清理策略。
云迁移和对象锁定
RGW 基于策略的云迁移功能允许您使用生命周期策略将数据分层到外部 S3 兼容端点(公共云、磁带网关等)。当对象锁定处于活动状态时,锁定的对象会在云迁移期间自动跳过,以保留 WORM 契约。
这种行为是有意的:从 Ceph 的角度来看,云迁移是一种 *破坏性* 操作:迁移后,本地副本通常会被移除并替换为存根。允许对锁定的对象执行此操作将违反不可变性保证。
来自 RGW 生命周期代码 (rgw_ lc.cc):
}这确保了合规性数据保留在您的 Ceph 集群上,直到保留期到期,无论可能适用的任何云分层策略。
操作注意事项
存储容量规划
启用版本控制后,存储消耗会迅速增长:
每次修改都会创建一个新的完整对象版本
删除操作不会释放空间(它们会添加删除标记)
只有永久删除版本时才会回收空间
监控建议:跟踪逻辑(S3)和物理(RADOS)使用情况:
$ ceph df detail您可能会发现将此或其他的 rgw-exporter
(https://github.com/pcuzner/rgw-exporter) 添加到您的 Prometheus 中很有用。
索引分片大小用于版本化桶
每个对象版本都会在桶索引中创建额外的条目。一个桶如果有一百万个对象,平均每个对象有十个版本,则有 1000 万个索引条目。请相应地规划分片数量:
$ radosgw-admin bucket reshard --bucket versioned-bucket --num-shards XXX请注意,截至 2025 年 12 月,正在进行一项工作,旨在增强动态重分片以考虑版本化对象。运行早期版本的集群应将版本控制纳入其手动分片计数或动态重分片阈值。
MFA 删除以增加安全性
RGW 支持 MFA 删除,这需要多因素身份验证才能永久删除对象版本或更改桶的版本控制状态。
--mfa "my-mfa-device 293651"启用后,任何在未提供有效 MFA 代码的情况下尝试永久删除版本的操作都将失败,并显示 ccessDenied。
有关完整的 MFA 设置说明,包括使用 radosgw-admin mfa create 创建 TOTP 令牌,请参见 Ceph 对象网关多因素身份验证文档(https://docs.ceph.com/en/latest/radosgw/mfa)。
结论:完整的数据保护堆栈
通过本次深度解析的第三部分,我们探讨了 Ceph RGW 如何实现企业数据保护的两个基石功能。版本控制 提供了每个对象的完整历史记录,从而能够从意外修改和删除中恢复。对象锁定 增加了 WORM 语义,以实现法规遵从性和勒索软件保护。
这些功能的核心是 对象逻辑头 (OLH),这是一种优雅的架构解决方案,通过一层间接高效地维护版本历史。
结合第二部分中的生命周期管理功能,您现在对 RGW 的数据治理堆栈有了完整的了解:
版本控制 + OLH:保留历史记录并实现时间点恢复
对象锁定:强制实现合规性不可变性
生命周期管理:在策略约束内自动清理版本
垃圾回收:回收永久删除版本的空间
如有相关问题,请在文章后面给小编留言,小编安排作者第一时间和您联系,为您答疑解惑。
热门跟贴