Ceph RGW Rados Bucket Index 深度解析:索引模型、版本化、事务一致性与分片重分片
存储分布式文件系统对象存储后端高可用【免费下载链接】cephCeph is a distributed object, block, and file storage platform项目地址https://gitcode.com/gh_mirrors/ce/ceph点击查看免费下载导读本文基于 Ceph 开源仓库中的 doc/dev/radosgw/bucket_index.rst系统解析 RGWRADOS Gateway的 Rados Bucket Index 机制。Bucket Index 是每个存储桶Bucket内对象列表及其元数据size、etag、mtime 等的索引是支撑 S3ListObjectsV2/ListObjectVersions与 SwiftGET Container等列目录 API 的底层数据结构。读完本文你将掌握 bucket index 的存储模型、S3 版本化下的 olh 间接寻址、读写一致性保证、索引事务协议、分片与动态重分片机制以及基于radosgw-admin的手动运维手段。什么是 Bucket Index在 RGW 中每个存储桶都维护一份bucket index桶索引用于存放该桶内对象列表及每个对象的相关元数据size、etag、mtime 等从而支撑对象列举类 API 请求并承担部分内部记账bookkeeping职责。这些 API 对应 S3 的ListObjectsV2、ListObjectVersions以及 Swift 的GET Container。存储载体RADOS omap索引条目并非存放在独立文件中而是存放在索引对象或按分片拆分的多个索引对象的RADOS omap条目中。omap 是 RADOS 对象上以键值对形式存储的扩展属性集合天然适合存放“对象名 → 元数据”这种字典结构。Indexless 桶存储桶也可以被创建为indexless无索引模式。此类桶没有索引因此无法进行列目录操作。在源码中对应 src/rgw/rgw_bucket_layout.h 的BucketIndexType枚举enum class BucketIndexType : uint8_t { Normal, // normal hash-based sharded index layout Indexless, // no bucket index, so listing is unsupported };可以看到Indexless的注释明确指出 no bucket index, so listing is unsupported。而is_layout_reshardable()等辅助函数rgw_bucket_layout.h也以BucketIndexType::Normal作为可重分片的前提。索引条目的粒度对于非版本化存储桶bucket index 中每个对象对应一个条目。对于 S3版本化存储桶则更为复杂详见下一节每个对象版本和删除标记delete marker都对应一个索引条目。S3 对象版本化与 olh 间接寻址版本化存储桶的 bucket index 中除了按对象名排序的条目外还为同名对象的各个版本维护了一组从新到旧排序的条目供版本化列目录使用。这解释了为何版本化桶在RGWRados::calculate_preferred_shards()src/rgw/driver/rados/rgw_rados.cc中会提前触发重分片——源码注释说明每个版本化桶的第一个对象需要 4 个索引条目之后每新增一个对象需要 2 个条目max_objs_per_shard / 3因此索引增长远快于普通桶。head 对象与版本 oidRGW 在rgw.buckets.data池中为每个对象版本存放一个 head 对象。该 RADOS 对象的 oid 由**对象名 版本 idversion id**组合而成从而保证不同版本对应不同的 RADOS 对象。Object Logical HeadolhS3 的 GET/HEAD 请求按对象名访问时应返回该对象的“当前current”版本。为了支持这一点RGW 额外保存一个object logical headolh对象其 oid 只包含对象名不含版本 id作为指向当前版本 head 对象的间接层indirection。这段间接寻址逻辑实现在RGWRados::follow_olh()src/rgw/driver/rados/rgw_rados.ccint RGWRados::follow_olh(const DoutPrefixProvider *dpp, RGWBucketInfo bucket_info, RGWObjectCtx obj_ctx, RGWObjState *state, const rgw_obj olh_obj, rgw_obj *target, optional_yield y)从实现可见其核心流程收集 olh 对象属性中以RGW_ATTR_OLH_PENDING_PREFIX为前缀的 pending 条目即尚未收敛的版本写入/删除记录→ 检查并移除已过期的 pending 条目check_pending_olh_entries/remove_olh_pending_entries→ 若仍有 pending 条目则调用update_olh()将 olh 推进到最新版本 → 最后从RGW_ATTR_OLH_INFO中解码RGWOLHInfo将olh.target作为当前版本目标返回。若该 olh 标记为removed对象当前为删除标记则设置state-is_dm true并返回-ENOENT。保证 olh 与 bucket index 的一致性为了维持 olh 对象与 bucket index 之间的一致性索引为每个对象名保留一个独立的 olh 条目记录对其所有版本的全部写入/删除日志。当 RGW 需要依据索引判定“当前版本”时RGWRados::apply_olh_log()同样位于 src/rgw/driver/rados/rgw_rados.cc会重放replay这份日志保证 olh 对象收敛到与 bucket index 一致的“当前版本”。一致性保证Consistency GuaranteeRGW 在对象操作上保证读后写一致性read-after-write consistency一旦客户端收到某个写请求的成功响应该写入的效果必须对后续读请求可见。例如S3 客户端先发PutObject覆盖一个已存在对象、紧接着发GetObject读回时RGW不得返回旧对象内容必须返回新对象内容或返回其后某次写入/删除的结果。该保证适用于所有对象写请求PutObject、DeleteObject、PutObjectAcl等与所有对象读请求HeadObject、GetObject、ListObjectsV2等。这一强一致性约束正是后续“三步索引事务”设计见后文的根本动因。Rados 对象模型S3/Swift 对象即 API objects存放在rgw.buckets.data池中每个 API 对象由一个head 对象和零个或多个 tail 对象组成。而bucket index 对象则存放在独立的rgw.buckets.index池中。写入对象时head 对象最后写入作为使其对读请求可见的原子“提交commit”动作。将索引与数据分池、head 后写为下一步通过事务协议保证两者一致提供了物理基础。分片Sharding与重分片Resharding为什么需要分片一个桶的索引通常会被拆分为多个 RADOS 对象称为bucket index shards索引分片。在 RADOS 中对同一对象的多次写入无法并行把索引分散到更多 RADOS 对象上即可提高写入并行度。对于一次对象上传其对应的索引分片通过对象名的哈希选择enum class BucketHashType : uint8_t { Mod, // rjenkins hash of object name, modulo num_shards };见 src/rgw/rgw_bucket_layout.hMod模式即“对象名的 rjenkins 哈希值对分片数取模”。这一设计保证同一对象的所有条目及其在 S3 版本化桶中的所有版本必定落在同一分片上同时一般也能让对象均匀分布到各分片——但当某些对象拥有大量版本时均匀性会被破坏热点分片。分片数量配置新桶的默认分片数为 11可通过以下两个途径覆盖配置位置配置项说明zonegroupbucket_index_max_shards区域组级默认分片数ceph.confrgw_override_bucket_index_max_shards全局覆盖优先级更高源码佐证见 src/rgw/driver/rados/rgw_bucket.cc} else if (cct-_conf-rgw_override_bucket_index_max_shards 0) { ... cct-_conf-rgw_override_bucket_index_max_shards;以及 src/rgw/driver/rados/rgw_rados.cc 中bucket_index_max_shards对rgw_override_bucket_index_max_shards的优先读取逻辑。分片布局结构定义在 src/rgw/rgw_bucket_layout.h 的bucket_index_normal_layoutstruct bucket_index_normal_layout { uint32_t num_shards 1; // 当前分片数 uint32_t min_num_shards 1; // 该桶布局允许的最少分片数 BucketHashType hash_type BucketHashType::Mod; };注意旧桶曾用num_shards 0表示 1rgw::num_shards()辅助函数做了兼容归一化rgw_bucket_layout.h。重分片的必要性与触发条件任何 RADOS 对象的 omap 都有约 100,000 条目的实际上限因此必须保证分片数量足够、使每片条目数不超过该上限。随着桶内对象数增长可能需要reshard重分片以增加分片数。重分片存在两种方式手动重分片通过radosgw-admin管理命令主动触发动态重分片dynamic resharding无需管理员干预自动发生。动态重分片的判定逻辑位于RGWRados::check_bucket_shards()src/rgw/driver/rados/rgw_rados.cc关键流程为首先检查配置开关rgw_dynamic_resharding关闭则直接返回不触发校验布局可重分片is_layout_reshardable调用calculate_preferred_shards()结合rgw_max_dynamic_shards动态分片上限与rgw_max_objs_per_shard每分片目标条目数计算期望分片数版本化桶按 1/3 折算条目上限以提前触发若涉及缩减分片还受rgw_dynamic_resharding_may_reduce开关约束判定需要重分片时通过add_bucket_to_reshard()rgw_rados.cc写入重分片队列reshard log记录old_num_shards、new_num_shards、initiator Dynamic等信息交由后台进程执行。动态缩减分片与延迟等待动态重分片也可以减少分片数量。由于某些桶的对象数会快速增减且不希望频繁重分片去“追逐”这些波动缩减分片操作在“判定需要缩减”与“实际执行”之间引入了延迟到执行时刻会再次检查桶仅当桶仍确实需要缩减分片时才真正执行。该延迟默认 5 天可用 ceph.conf 中的rgw_dynamic_resharding_reduction_wait配置。源码实现见 src/rgw/driver/rados/rgw_reshard.cc读取该配置后换算为等待时间窗口。布局信息的载体桶的索引对象布局信息存放在RGWBucketInfo的struct rgw::BucketLayout中src/rgw/rgw_bucket_layout.h。该结构除记录当前索引布局current_index外还包含reshardingBucketReshardState枚举None/InProgress/InLogrecord标记重分片是否进行中target_index重分片操作的目标布局可选重分片期间存在logs未裁剪的桶日志bilog布局代际历史judge_reshard_lock_time用于判断桶是否正在重分片的锁时间戳。真正的重分片执行逻辑位于 src/rgw/driver/rados/rgw_reshard.cc。手动重分片radosgw-admin 命令radosgw-admin提供了一组完整的重分片运维命令src/rgw/radosgw-admin/radosgw-admin.cc 的命令清单命令用途radosgw-admin bucket reshard --bucketname --num-shardsN手动对指定桶重分片radosgw-admin bucket set-min-shards设置动态重分片会为桶考虑的最少分片数radosgw-admin reshard add将桶加入调度重分片队列radosgw-admin reshard list列出所有正在重分片或已调度的桶radosgw-admin reshard status读取桶的重分片状态radosgw-admin reshard process处理已调度的重分片任务radosgw-admin reshard cancel取消桶的重分片radosgw-admin reshard stale-instances list列出重分片遗留的 stale-instancesradosgw-admin reshard stale-instances delete清理重分片遗留的 stale-instancesradosgw-admin reshardlog list列出桶重分片日志radosgw-admin reshardlog purge裁剪桶重分片日志示例将mybucket强制重分片为 32 个索引分片radosgw-admin bucket reshard --bucketmybucket --num-shards32查看所有待重分片/进行中的桶radosgw-admin reshard list radosgw-admin reshard status --bucketmybucket注上述命令的具体行为与输出格式以当前仓库 radosgw-admin.cc 中的命令注册为准。索引事务Index Transaction问题两个对象无法原子更新所有对象写入或删除都必须同步更新 bucket index 以保持一致性。但 head 对象与 bucket index 存放在不同的 RADOS 对象分属rgw.buckets.data与rgw.buckets.index池中无法用单个 RADOS 操作原子地同时更新两者。为了满足列目录操作的一致性保证RGW 用三步桶索引事务协调这两次对象写入在 bucket index 对象上**预备Prepare**一个事务写入或删除 head 对象在 bucket index 对象上**提交Commit事务若第 2 步失败则取消Cancel**事务。pending 与 completed 状态对象写入与删除可能彼此竞争因此同一对象在某一时刻可能同时存在多个已预备但未提交的事务。RGW 将对象条目区分为两种状态pending挂起存在未完成事务completed完成不存在未完成事务。源码实现位置该事务协议在 src/rgw/driver/rados/rgw_rados.cc 中实现为RGWRados::Object::Write::write_meta()对象写入路径RGWRados::Object::Delete::delete_obj()对象删除路径。而 bucket index 侧的底层操作由 OSD 侧的 class 方法实现位于 src/cls/rgw/cls_rgw.ccrgw_bucket_prepare_op()cls_rgw.cc预备事务将条目标记为 pendingrgw_bucket_complete_op()cls_rgw.cc提交事务或在上游失败时回滚将条目推进到 completed。这些方法通过cls注册接口暴露给 radosgw 调用cls_rgw.cc 中的cls.register_cxx_method(...)注册片段形成 RGW 侧编排 OSD class 侧执行 的完整事务链路。列目录Listing列出条目与盘查 head列目录时RGW 会读取 bucket index 中的全部条目包括 pending 与 completed。对任何 pending 条目必须先检查对应 head 对象是否存在再决定是否将条目纳入最终列表——这保证了即使事务中断列表也不会出现幽灵条目。dir suggest从列目录到索引的反馈如果 RGW 在索引事务中途崩溃索引条目可能卡在 pending 状态。当后续列目录遇到这些 pending 条目时RGW 会把从 head 对象读到的信息回写给 bucket index用于更新条目、解决陈旧事务。这条回写消息称为dir suggest目录建议——因为 bucket index 把它当作一条提示/建议来采纳。源码实现位置列目录功能在 src/rgw/driver/rados/rgw_rados.cc 中实现为RGWRados::Bucket::List::list_objects_ordered()有序列目录RGWRados::Bucket::List::list_objects_unordered()无序列目录RGWRados::check_disk_state()读取 head 对象并编码建议的索引变更即生成 dir suggest 载荷。bucket index 侧的对应操作在 src/cls/rgw/cls_rgw.cc 中实现为rgw_bucket_list()cls_rgw.cc按前缀/游标等条件遍历 omap 条目rgw_dir_suggest_changes()cls_rgw.cc应用列目录回传的建议解决 stale pending 事务。有序列目录的高昂代价由于 RGW 对象依据哈希分布到桶的各索引分片上分片之间不存在词典序lexical ordering只有单个分片内部保持有序。因此有序列目录list_objects_ordered是一种复杂且 I/O 密集的操作从每个分片并行拉取一批条目使用**选择排序selection sort**在批次间归并产出一段有序结果当任一分的批次耗尽时从所有分片再次批量读取如此循环直至完成。这也意味着分片数量越多有序列目录的并行批次管理开销越大运维时需要在写入并行度分片多与有序列目录成本分片少之间权衡并借助动态重分片在桶规模变化时自动保持平衡。小结Rados Bucket Index 是 RGW 对象存储语义的基石它以 RADOS omap 承载对象元数据索引通过 olh 间接层支撑 S3 版本化语义以三步索引事务在数据与索引分池的约束下满足读后写一致性并以分片 动态重分片应对 omap 容量上限与写入并发需求。理解这些机制有助于在部署、排障与容量规划时做出正确的配置决策——例如合理设置rgw_override_bucket_index_max_shards、关注rgw_max_objs_per_shard与rgw_dynamic_resharding系列参数以及熟练使用radosgw-admin的重分片运维命令。赞分享存储分布式文件系统对象存储后端高可用【免费下载链接】cephCeph is a distributed object, block, and file storage platform项目地址https://gitcode.com/gh_mirrors/ce/ceph点击查看免费下载相关推荐Ceph RGW 数据布局深度解析元数据、Bucket 索引与对象寻址机制Ceph RGW 数据布局深度解析元数据、Bucket 索引与对象寻址机制 本指南以 Ceph 官方文档 doc/radosgw/layout.rst htt存储分布式文件系统对象存储后端高可用TiDB 整型分片索引Integer Shard Index设计与实现深度解析TiDB 整型分片索引Integer Shard Index设计与实现深度解析 本篇文章围绕 TiDB 设计文档 Integer shard index h数据库分布式数据库后端OLAPLance 碎片复用索引Fragment Reuse Index深度解析用延迟索引重映射化解 compaction 与索引优化冲突Lance 碎片复用索引Fragment Reuse Index深度解析用延迟索引重映射化解 compaction 与索引优化冲突 Lance 采用碎片数据库向量数据库数据湖全文检索创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

2026最新羽衣甘蓝图片处理实战,3步搞定环境配置

2026最新羽衣甘蓝图片处理实战,3步搞定环境配置

2026最新羽衣甘蓝图片处理实战,3步搞定环境配置 配置环境就卡半天,是不是你最近跑通那个羽衣甘蓝图片批量处理脚本时的真实写照?…

2026/9/24 9:57:30 阅读更多 →
年度技术精华盘点:AI、云计算与系统架构趋势解析

年度技术精华盘点:AI、云计算与系统架构趋势解析

1. 年度技术精华盘点:为什么我们需要系统性回顾?每年底的技术圈总会出现各种"年度盘点",但大多数只是简单罗列文章标题。真正有价值的回顾应该像老友聚会时的深度对话——不仅要告诉你"发生了什么",更要解释&…

2026/9/24 9:56:30 阅读更多 →
《鬼谷子》战略思想在现代商业与组织管理中的应用

《鬼谷子》战略思想在现代商业与组织管理中的应用

1. 典籍背景与核心价值解析《鬼谷子》作为先秦时期重要的战略思想著作,其独特价值在于将军事谋略、政治智慧与心理学原理熔于一炉。这部相传由"鬼谷先生"编撰的典籍,实际上反映了春秋战国时期士人阶层对权力博弈的系统性思考。不同于《孙子兵法…

2026/9/23 2:45:16 阅读更多 →

最新新闻

C盘清理安全指南:识别系统垃圾与误删抢救全攻略

C盘清理安全指南:识别系统垃圾与误删抢救全攻略

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 9:57:00 阅读更多 →
双运放峰值检测电路设计:从原理到PCB调试的工程实践

双运放峰值检测电路设计:从原理到PCB调试的工程实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 9:57:00 阅读更多 →
创维E900S/E910刷机全教程:海思Hi3798MV100短接强刷第三方固件

创维E900S/E910刷机全教程:海思Hi3798MV100短接强刷第三方固件

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 9:57:00 阅读更多 →
全渠道订单路由系统设计:候选筛选、约束评分、履约状态机与异常补偿

全渠道订单路由系统设计:候选筛选、约束评分、履约状态机与异常补偿

订单路由经常被简化为“根据地址选择最近门店”。生产系统中,距离只是一个软目标。库存可用性、商品经营权、服务范围、门店营业、截单时间、任务负载、配送能力与组织边界都可能使最近节点不可用。 一个可追溯的路由流程可以拆成: 订单标准化 → 节点候…

2026/9/24 9:57:00 阅读更多 →
SaaS ERP云原生落地能力验证指南

SaaS ERP云原生落地能力验证指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 9:57:00 阅读更多 →
BLI实验中传感器选择与蛋白固定模式解析

BLI实验中传感器选择与蛋白固定模式解析

一、BLI生物层干涉技术的检测原理生物层干涉技术(Biolayer Interferometry,BLI)是一种基于光学干涉原理的实时、无标记分子相互作用分析技术。实验时,一个分子固定于传感器表面的生物层,作为Ligand;另一个分…

2026/9/24 9:56:00 阅读更多 →

日新闻

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为…

2026/9/24 0:00:19 阅读更多 →
单细胞注释实战:基于Scanpy的标记基因与参考映射流程解析

单细胞注释实战:基于Scanpy的标记基因与参考映射流程解析

简介:一份基于单细胞RNA测序数据的细胞类型注释算法研究Python毕业设计源码,针对计算机相关专业正在做毕设或需要项目实战的学习者,可用于课程设计与期末大作业。项目代码完整、经导师指导评审通过,可直接运行,覆盖数据…

2026/9/24 0:00:19 阅读更多 →
C#源生成器实战:用增量生成器替代反射,告别AOT崩溃

C#源生成器实战:用增量生成器替代反射,告别AOT崩溃

第一次在项目里被反射卡住,是在一个老旧的WinForms模块里:几十个类依赖PropertyChanged通知,运行时反射读属性、发通知,每次启动慢半拍不说,一上.NET Native/AOT裁剪模式几乎全面崩盘。后来我把这段逻辑全部改成C#源生…

2026/9/24 0:00:19 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/23 4:55:02 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/24 9:10:42 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/23 9:53:41 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/23 9:53:40 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/23 9:53:40 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/23 9:53:40 阅读更多 →