注意
本文档适用于 Ceph 开发版本。
RADOS桶索引
RGW 中的桶存储其对象列表在一个桶索引中。每个索引条目存储足够的元数据(大小、etag、mtime 等)来响应列出对象的 API 请求。这些 API 在 S3 中,和在 Swift 中。ListObjectsV2和ListObjectVersions在 S3 中,和在 Swift 中。GET Container在 Swift 中。
Note
桶可以被创建为“无索引”。这样的桶没有索引,并且不能被列出。
一致性保证
RGW 对象操作保证写后读一致性。这意味着一旦客户端收到一个写请求的成功响应,那么该写操作的效果必须对后续的读请求可见。
例如:如果一个 S3 客户端发送一个 PutObject 请求来覆盖一个现有的对象,然后发送一个 GetObject 请求来读取它,RGW 必须不能返回前一个对象的内容。它必须要么响应新对象的内容,要么响应一个稍后对象写或删除的结果。
这个一致性保证适用于所有对象写请求(PutObject、DeleteObject、PutObjectAcl 等)和所有对象读请求(HeadObject、GetObject、ListObjectsV2 等)。
Rados 对象模型
S3/Swift 对象,或“API 对象”,存储在 rgw.buckets.data 池中的 rados 对象。每个 API 对象由一个头对象和零个或多个尾对象组成。桶索引对象存储在 rgw.buckets.index 池中。
在写对象时,它的头对象最后被写入。这充当一个原子“提交”,使其对读请求可见。
索引事务
为了保持桶索引的一致性,所有对象写入或删除也必须相应地更新索引。因为头对象存储在不同的 rados 对象中而不是桶索引,我们不能用一个单一的 rados 操作原子地更新两者。为了满足一致性保证对于列出操作,我们必须使用一个三步桶索引事务来协调这两个对象写入:
在它的桶索引对象上准备一个事务。
写入或删除头对象。
提交桶索引对象上的事务(如果步骤 2 失败则取消事务)。
对象写入和删除可能会相互竞争,所以一个给定的对象可能同时有多个准备好的事务。RGW 如果有任何未完成的交易,则认为一个对象条目是“挂起”的,否则认为是“完成”的。
这个事务在src/rgw/driver/rados/rgw_rados.cc
as RGWRados::Object::Write::write_meta()
中实现,用于对象写入,在RGWRados::Object::Delete::delete_obj()
中实现,用于对象删除。桶索引操作在src/cls/rgw/cls_rgw.cc
as rgw_bucket_prepare_op()
和rgw_bucket_complete_op()
.
中实现。
当列出对象时,RGW 会从桶索引中读取所有条目(挂起和完成)。对于任何挂起的条目,它必须在将条目包含在最终列出中之前检查头对象是否存在。
如果 RGW 在一个索引事务中崩溃,一个索引条目可能会卡在这个“挂起”状态。当桶列出遇到这些挂起的条目时,它也会将头对象的信息发送回桶索引,以便它可以更新条目并解决其过时的交易。这个消息被称为“dir suggest”,因为桶索引将其视为一个提示或建议。
桶列出在src/rgw/driver/rados/rgw_rados.cc
as RGWRados::Bucket::List::list_objects_ordered()
和RGWRados::Bucket::List::list_objects_unordered()
. RGWRados::check_disk_state()
中实现,读取头对象并编码建议的更改。相应的桶索引操作在src/cls/rgw/cls_rgw.cc
as rgw_bucket_list()
和rgw_dir_suggest_changes()
.
S3 对象版本控制
对于版本桶,桶索引包含每个对象版本和删除标记的条目。除了按对象名称对索引条目进行排序外,它还必须按名称相同的对象版本从最新到最旧进行排序。
RGW 为每个对象版本在 rgw.buckets.data 池中存储一个头对象。这个 rados 对象的 oid 是对象名称和其版本 id 的组合。
在 S3 中,一个 GET/HEAD 请求对于对象名称会给你该对象的“当前”版本。为了支持这一点,RGW 存储一个额外的“对象逻辑头”(olh)对象,其 oid 仅包括对象名称,它充当指向其当前版本头对象的间接引用。这个间接引用逻辑在src/rgw/driver/rados/rgw_rados.cc
as RGWRados::follow_olh()
.
中实现。src/rgw/driver/rados/rgw_rados.cc
, RGWRados::apply_olh_log()
中重放这个日志,以确保这个 olh 对象收敛到与桶索引相同的“当前”版本。
由 Ceph 基金会带给您
Ceph 文档是一个社区资源,由非盈利的 Ceph 基金会资助和托管Ceph Foundation. 如果您想支持这一点和我们的其他工作,请考虑加入现在加入.