【Ceph RADOS】RGW:索引池与数据池、S3 到 RADOS 的映射边界

💡 原文中文,约9700字,阅读约需23分钟。
📝

内容提要

RGW是Ceph的S3/Swift对象网关,将HTTP请求映射到RADOS操作。核心机制包括:head/tail对象模型(小对象内联,大对象分条)、bucket index的OMAP存储与动态reshard、multipart上传的manifest引用、版本控制的delete marker、GC异步删除、多站点bi-log同步。主要瓶颈是bucket index的LIST性能与GC积压,S3 Select仅做RGW侧过滤,无法下推OSD。

🔎

延伸解读

索引池与数据池的分离设计

RGW 将索引与数据分离到不同池:索引池存储 bucket index 的 OMAP,数据池存储对象数据。这种设计允许独立扩展和优化,但索引池的 OMAP 性能受限于 BlueStore/RocksDB,单 shard 条目过多时 LIST 延迟上升。理解这一分离有助于定位性能瓶颈,避免误判为网络或 RGW 进程问题。

动态 Reshard 的代价

动态 reshard 虽能自动扩展 shard 数,但会短暂阻塞写操作,且无法取消。大桶可能长期停留在单分片热点,队列积压加剧延迟。多站点场景下,Reef 之前不支持动态 reshard,Squid 需按 zone feature 核对。因此,不能将在线 reshard 视为完全无感,需评估业务容忍度。

GC 积压与空间释放

删除对象后,数据不立即释放,而是进入 GC 队列异步删除。若 GC 积压(如停服后重启或大量删除),磁盘空间可能长时间不释放。可通过 radosgw-admin gc process --include-all 手动加速,但会影响正常请求延迟。监控 GC 积压缺乏直接指标,需轮询 gc list,告警存在盲区。

多站点同步的最终一致性

多站点同步基于 bi-log 异步复制,主 zone 写入成功即返回,副 zone 有延迟,可能读到旧版本。网络分区恢复后自动续传,但不触发 fencing,双写冲突需业务层处理。同步积压时,radosgw-admin sync status 显示 behind,需关注带宽与对象大小对延迟的影响。

Q&A

Ceph RGW中,一次S3 PUT操作在RADOS层面大致会触发多少次操作?

对于小于或等于rgw_max_chunk_size(默认4MiB)的小对象,一次PUT大约触发2次RADOS操作:一次head对象写入和一次bucket index的OMAP更新。对于更大的对象,还需要额外的tail写入,次数为ceil((size - inline)/chunk)。

Ceph RGW的bucket index为什么可能成为性能瓶颈?

Bucket index使用OMAP存储在RADOS对象上,底层是BlueStore的RocksDB。当单个shard的条目数达到10^5量级时,LIST操作(OMAP_GET*)和compaction抖动会成为已知痛点。增加shard数量可以分散写并发,但LIST需要在RGW进行K路归并,延迟随shard数上升,因此扩大shard与加速LIST是矛盾的。

Ceph RGW动态resharding的触发条件和影响是什么?

动态resharding默认开启(rgw_dynamic_resharding=true),当bucket的每个shard对象数超过rgw_max_objs_per_shard(默认100000)时触发。动态上限为rgw_max_dynamic_shards(默认1999)。resharding会短暂阻塞对该bucket的写操作(读仍可进行),不是长期双写。可通过radosgw-admin reshard status查看状态,in-progress后不能取消。

Ceph RGW中,multipart upload完成时数据是如何组织的?

Multipart upload完成时,RGW读取所有part的元数据,生成最终对象的manifest,该manifest直接引用各part对象,无需复制数据。然后写入head对象(包含manifest和ETag),更新bucket index,并删除临时multipart元数据对象(推迟到GC)。读取时按manifest依次读取各part的tail对象。

Ceph RGW中,对象版本控制是如何在RADOS层实现的?

开启版本控制的bucket中,每次PUT创建新版本,head对象名包含version_id后缀。最新版本有一个不带版本后缀的current version pointer对象。bucket index中每个key有当前版本条目和历史版本条目。DELETE操作创建delete marker(零字节版本对象),GET返回404,但历史版本仍可通过version_id访问。永久删除需指定versionId,删除head和tail对象并加入GC队列。

Ceph RGW多站点同步的机制和一致性模型是什么?

多站点同步基于bi-log(bucket index log),每次bucket index变更追加一条bi-log条目,远端zone的sync thread拉取并重放GET+PUT操作。同步是异步最终一致,主zone写入成功即返回,副zone有延迟(秒到分钟级)。副zone可能读到旧版本。若同步积压,可用radosgw-admin sync status查看behind状态。

Ceph RGW中,S3 Select是否支持将过滤下推到OSD?

不支持。S3 Select在RGW进程侧实现,OSD层面仍是完整读取对象后在RGW内过滤,因此只节省RGW到客户端的网络带宽,不节省OSD到RGW的内部带宽。与列式存储相比,无法跳过不相关的列块。

Ceph RGW中,存储类(Storage Class)是如何映射到不同RADOS池的?

在zonegroup中配置placement targets,每个target指向不同的data池(如副本池vs EC池,SSD vs HDD)。用户PUT时通过x-amz-storage-class指定存储类,RGW据此选择placement。manifest记录每个stripe的placement标签,读取时按manifest从对应池读取。Lifecycle的Transition操作会重新写入对象到目标池,产生实际I/O。

🏷️

标签

➡️

继续阅读