RGW Bucket信息是如何保存在RADOS中的
在RGW User信息是如何保存在RADOS中的中,我们知道RGW是如何将User信息保存在RADOS中的。
这一节主要探寻如何通过uid获取与之关联的桶信息。
和User相似,Bucket信息也记录在meta池:
liuzheng@liuzheng-MS-7B23:~/ceph/build$ s3cmd mb s3://bucket_test Bucket 's3://bucket_test/' created liuzheng@liuzheng-MS-7B23:~/ceph/build$ ./bin/rados ls -p default.rgw.meta --all users.uid liuzheng users.uid liuzheng.buckets root bucket_test users.uid test root .bucket.meta.bucket_test:7134480e-d818-43de-895d-1c2ddcc9b43c.4181.1
可以看到,在创建一个名为bucket_test的bucket后,meta池中多了三个item:
- users.uid:liuzheng.buckets: 记录用户下所有的桶名称,保存在omap中~
- root:bucket_test: ???
- root:.bucket.meta.XXX:XXX: ???
同User,我们将通过librados来读取这些数据来。
code
// // Created by liuzheng on 22-7-28. // #include <iostream> #include <gtest/gtest.h> #include "include/rados/librados.hpp" #include "rgw/rgw_common.h" TEST(RGW_RADOS_BUCKET, GET_BUCKET_INFO) { librados::Rados rados; EXPECT_EQ(0, rados.init2("client.admin", "ceph", 0)); EXPECT_EQ(0, rados.conf_read_file(CEPH_CONF)); EXPECT_EQ(0, rados.connect()); librados::IoCtx ioctx; EXPECT_EQ(0, rados.ioctx_create("default.rgw.meta", ioctx)); ioctx.set_namespace("users.uid"); librados::ObjectReadOperation rop1; uint64_t size = 0; struct timespec mtime{}; bufferlist outbl; rop1.stat2(&size, &mtime, nullptr); ioctx.operate(OID_BUCKETS, &rop1, &outbl); //liuzheng.buckets对象的内容为空 EXPECT_EQ(0, size); librados::ObjectReadOperation rop2; std::map<std::string, bufferlist> attrs; rop2.getxattrs(&attrs, nullptr); ioctx.operate(OID_BUCKETS, &rop2, &outbl); //liuzheng.buckets对象的xattrs为空 EXPECT_EQ(0, attrs.size()); librados::ObjectReadOperation rop3; bufferlist header; std::set<std::string> keys; rop3.omap_get_header(&header, nullptr); rop3.omap_get_keys2("", -1, &keys, nullptr, nullptr); ioctx.operate(OID_BUCKETS, &rop3, &outbl); //我们只创建了一个名为 bucket_test 的bucket。 #define BUCKET_NAME "bucket_test" EXPECT_EQ(1, keys.size()); EXPECT_EQ(BUCKET_NAME, *keys.begin()); std::map<std::string, bufferlist> vals; ioctx.omap_get_vals_by_keys(OID_BUCKETS, keys, &vals); EXPECT_EQ(*keys.begin(), vals.begin()->first); //可见,{uid}.buckets 的omap中: // key 表示bucket name // val 表示的是cls_user_bucket_entry cls_user_bucket_entry bucket; auto iter = vals.begin()->second.cbegin(); bucket.decode(iter); EXPECT_EQ(BUCKET_NAME, bucket.bucket.name); // 回到 root 命名空间,存在两个对象,一个对象名和桶名一致,一个很长~ ioctx.set_namespace("root"); size = 0; EXPECT_EQ(0, ioctx.stat2(BUCKET_NAME, &size, nullptr)); EXPECT_LE(0, size); bufferlist bl; EXPECT_EQ(size, ioctx.read(BUCKET_NAME, bl, size, 0)); RGWBucketEntryPoint point; iter = bl.cbegin(); point.decode(iter); EXPECT_EQ(BUCKET_NAME, point.bucket.name); EXPECT_EQ(OID_USERNAME, point.owner.id); //我们通过point构造第2个对象 #define OID_BUCKET_INFO ".bucket.meta.bucket_test:c1672b05-e73f-4302-a988-ae513ac05659.4163.1" //RGW_BUCKET_INSTANCE_MD_PREFIX 定义在 rgw_rados.h std::string oid_ = ".bucket.meta." + point.bucket.get_key(':'); EXPECT_EQ(OID_BUCKET_INFO, oid_); std::cout << point.bucket.bucket_id << std::endl; size = 0; bl.clear(); EXPECT_EQ(0, ioctx.stat2(oid_, &size, nullptr)); EXPECT_LE(0, size); EXPECT_EQ(size, ioctx.read(oid_, bl, size, 0)); RGWBucketInfo bucket_info; iter = bl.cbegin(); bucket_info.decode(iter); rados.shutdown(); }
总结
通过对 default.rgw.meta池的分析,其bucket相关的信息如下:
namespace | oid | value | xattr | omap |
---|---|---|---|---|
users.uid | {username}.buckets | NULL | NULL | key为桶名,val为 cls_user_bucket_entry |
root | 对象内容为RGWBucketEntryPoint |
VERSION | NULL | |
root | .bucket.meta.{bucket_name}: | RGWBucketInfo |
VERSION && acl相关 | NULL |
接下来需要进一步学习rgw对 bucket的 基本操作 的 流程~。
本文作者:liutimo
本文链接:https://www.cnblogs.com/liutimo/p/16552745.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步