注意

本文档适用于 Ceph 开发版本。

RADOS桶索引

RGW 中的桶存储其对象列表在一个桶索引中。每个索引条目存储足够的元数据(大小、etag、mtime 等)来响应列出对象的 API 请求。这些 API 在 S3 中,和在 Swift 中。ListObjectsV2ListObjectVersions在 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 中,对同一个对象的多次写入不能并行运行。通过将索引分布到更多的 rados 对象上,我们增加了它的写并行性。对于给定的对象上传,相应的桶索引分片是基于对象名称的哈希来选择的。

新桶的默认分片数是 11,但可以在 zonegroup 的bucket_index_max_shards或 ceph.conf 的rgw_override_bucket_index_max_shards中覆盖。随着桶中对象数量的增加,它的索引分片数也会因为动态重分片而增加。

桶索引对象布局的信息存储在RGWBucketInfo as struct rgw::BucketLayoutfromsrc/rgw/rgw_bucket_layout.h中。重分片逻辑在src/rgw/driver/rados/rgw_reshard.cc.

索引事务

为了保持桶索引的一致性,所有对象写入或删除也必须相应地更新索引。因为头对象存储在不同的 rados 对象中而不是桶索引,我们不能用一个单一的 rados 操作原子地更新两者。为了满足一致性保证对于列出操作,我们必须使用一个三步桶索引事务来协调这两个对象写入:

  1. 在它的桶索引对象上准备一个事务。

  2. 写入或删除头对象。

  3. 提交桶索引对象上的事务(如果步骤 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. 如果您想支持这一点和我们的其他工作,请考虑加入现在加入.