rgw里面用户、bucket、用户数据之间关系

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了rgw里面用户、bucket、用户数据之间关系相关的知识,希望对你有一定的参考价值。

参考技术A 本篇文章介绍了ceph rgw组件里面,用户、bucket和用户数据对象之间的关系,以及它们和底层rados对象之间的关系,我们希望达到以下目的:

理解了上面这些关系之后,然后做一个小实验:通过s3cmd把上传文件到radosgw,然后直接通过拼接底层的rados对象来得到用户数据。

首先要准备一个radosgw环境,这里为了演示方便,使用了最简的配置。

查看rados里面的存储池

可以看到启动radosgw服务时,radosgw服务自动会创建相关的存储池

下面为了达到我们列出的目标,我们需要创建一个rgw用户,然后使用该用户创建一个bucket。

再次查看rados里面的存储池

可以看到创建用户之后,自动创建了default.rgw.users.uid这个池。

使用s3cmd客户端创建一个bucket

再次查看rados里面的存储池

可以看到创建用户之后,自动创建了default.rgw.buckets.index这个池

我们上面创建了一个radosgw用户rgwuser01,这个用户相关数据保存在哪里呢?

通过上面命令可以看到,在default.rgw.users.uid池里面有两个rados对象,rgwuser01对象和我们用户的id名称一致,这个对象就是用来保存用户信息的rados对象。每个radosgw用户在这个池里面都对应一个rados对象,对象名就是用户id名称。

可以看到,bk01这个bucket在 default.rgw.data.root 池里面有个rados对象 .bucket.meta.bk01:475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1 与之对应,这个rados对象就是对应bk01 bucket的,这个rados对象里面存放了一些关于bk01 bucket元数据信息:

通过查询bk01这个bucket的元数据信息,可以知道bk01这个bucket的id为 475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1 。

另外,bucket的acl信息保存在元数据对象的xattr里面:

我们都知道一个用户可以有属于自己的多个bucket,那用户和bucket的对应关系是怎么建立的呢?

在上面通过 rados -p default.rgw.users.uid ls 命令查询的结果里面除了用户对象以外,还有一个rgwuser01.buckets对象,这个对应的命令格式就是uid.buckets,用户和bucket的对应关系就保存在这个对象的omap里面,key值就是bucket的名称,让我们来验证下:

查看rgwuser01.buckets这个对象有哪些key

可以看到有bk01这个key,bk01就是我们创建的bucket名称,这点没问题了。再来获取下bk01这个key对应的value值

可以看到bk01这个key所对应的value值就是bk01这个bucket的信息。这样我们知道了uid,然后通过uid.buckets这个rados对象就可以查询到该用户下有哪些bucket了。

使用s3cmd客户端上传一个对象

查看rados里面的存储池信息

可以看到上传对象之后,自动创建了default.rgw.buckets.data这个池,看下这个池里面的对象

那么bucket是如何知道自己包含了哪些对象呢?其实是每个bucket在default.rgw.buckets.index这个池里面有一个rados对象,我们叫这个rados对象为索引对象

可以看到一个 .dir.475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1 对象,这个对象的名称和我们上面看到的bucket id相比,在前面多了.dir.这个字符,这个对象就是每个bucket在rados里面的索引对象,命名格式就是.dir.bucket-id。这个对象的omap里面就保存了这个bucket下所包含的所有对象信息,我们验证下

可以看到输出里面和我们上传的对象名一致,我们再上传一个对象看看是不是这样

然后再次查看,发现确实是这样的

这样我们就知道了bucket是怎么知道自己包含了哪些用户数据对象的。要说明一点的是,bucket的索引对象个数可以去更改,默认只有一个。

这个实验大概过程就是,用户通过radosgw的客户端(s3cmd),上传一个文件,然后我们在rados层面获取该文件对应的rados对象,然后通过这些rados对象直接拼接成用户上传的文件。

首先准备一个文件,这里特意准备了一个稍大的文件是为了让s3cmd分段上传(默认15M一段),小文件虽然不用分段,但是原理也一样

计算该文件的md5值,用于验证后面我们拼接出来的文件的正确性

然后使用s3cmd上传到radosgw中(radosgw最终会将数据存到rados中)

可以看到s3cmd将文件分成了6段来上传,每段的大小是15M,最后一段是8M,因为文件最后只剩8M了嘛。
根据前面我们的讲述,我们知道radosgw将用户数据保存在了default.rgw.buckets.data池中,我们来看下刚才上传的文件在rados中的分布情况

radosgw默认将用户数据按照4M大小(有参数可以控制切分大小)来切好,然后放到rados里面的,所以我们上传的文件最终就是切分成了上面的这些对象。

接下来我们就是要把这些对象get出来,然后拼接成我们的用户数据(就是我们使用s3cmd put上去的文件)。

首先我们把上面的对象整理成下面的顺序,然后放入一个文本文件中:

为啥要整理成这种顺序,仔细观察下就会发现,所有和用户数据对象messages相关的rados对象,都有规律的。

这里简单粗暴说下:首先所有对象都是以bk01这个bucket的id开头,然后我们知道分成了6段,看下包含__multipart_messages字符的对象有6个,然后每个结尾都有数字标识,从1-6。
再看每段里面又包含__shadow_messages字符的对象,也是每个结尾都有数字标识,从1-3。最后是一个475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1_messages-20180722这样的对象,这个对象里面就是保存了整个用户数据对象的元数据和分段的信息。

然后从rados中获取这些对象,并拼接

最后我们看下我们拼接文件的md5值,看是否和开始我们使用s3cmd上传的文件的md5一样

可以看到,md5值是一样的。这样我们就完成了,直接通过底层的rados对象来重组出用户的数据,实际上我们正常情况下不需要这么去做,这里只是为了更好的理解用户数据在底层rados上是怎么组织和存放的。

好了,到这里就弄清楚了开始在目标里面列出的几个问题,动手试试吧。

Ceph RGW:数据的存储及寻址

参考技术A

RGW是一个对象处理网关。数据实际存储在ceph集群中。利用librados的接口,与ceph集群通信。RGW主要存储三类数据:元数据(metadata)、索引数据(bucket index)、数据(data)。这三类数据一般存储在不同的pool中,元数据也分多种元数据,存在不同的ceph pool中。

1、 Metadata
元数据信息包括:user,bucket,以及bucket.instance。其中:
user: 主要是对象存储的用户信息
bucket:主要维护bucket name与bucket instance id之间的映射信息
bucket.instance:维护了bucket instance信息

查看user的元数据如下:
radosgw-admin metadata list user:

radosgw-admin metadata get user:testid:

radosgw-admin metadata list bucket:

radosgw-admin metadata get bucket:first:

radosgw-admin metadata list bucket.instance:

radosgw-admin metadata get bucket.instance:first:bucket_id

2、Bucket Index
bucket index主要维护的是一个bucket中object的索引信息。一个bucket对应一个或多个rados object(开启bucket shards下)。维护的是一个key-val的map结构,map存放在object的omap(rocksdb)中,key对应的rgw object,val是关于rgw object的一些元数据信息,检索bucket的存放的object时,需要这些信息。omap也包含一个Header,其存放的是bucket account info,如此bucket中Object的个数,总的size等。
3、Data
rgw object内容,存放在一个或多个rados object中。rados object分为header和tail部分,header最多可以容纳512KB的数据,如果一个rgw object的大小小于512KB,那么只有header。否则剩余的数据会按照集群rados object的大小条带化分割成多个rados object。

在Pool: zone.rgw.meta利用namespace隔离多个存储空间:

对于Pool: zone.rgw.log也包含多个namespace:

当检索对象存储中的一个object时,会包含三个要素:user,bucket,object。user主要是RGW用于获取user id验证ACL;bucket及obejct用于确定object在pool中的位置。

User

user数据存储在 zone.rgw.meta:users.uid 中,如下:

包含两部分: ups3: user本身信息; ups3.buckets: 用户所属的bucket。

ups3: 用户的基本信息,及ACL/Bucekt Quota/User Quota等;对应struct RGWUserInfo, 定义于rgw_common.h。
ups3.buckets:用户所属的Buckets,key-value结构,存放于omap结构中;对应struct cls_user_bucket_entry,定义于rgw_common.h,数据操作如下:

通过uid.buckets查到用户具有哪些buckets,并且这些bucket以下基本数据。

Bucket

Bucket信息存在在 zone.rgw.meta:root 中,如下:

first: 记录了bucket与bucket_instance_id的对应关系,其对应于数据结构:struct RGWBucketEntryPoint
.bucket.meta.first:1c60b268-0a5d-4718-ad02-e4b5bce824bf.44166.4: bucket instance;寻址方式:.bucket.meta.tenant:bucket.name:bucket_id;对应结构体:struct RGWBucketInfo。
其中Bucket ACL及IAM Policy存放在bucket instance object的attr中。如下:

获取Bucket ACL及IAM Policy数据如下:

Object

Bucket Index: Bucket中包含的Object信息,都存放在一个或多个Object的 omap 中。此omap为一个key-value结构,key为object的名称,value对应 struct rgw_bucket_dir_entry : cls_rgw_types.h 。
Bucket Index Object:

如下:

在此bucket下,有一个object: ntp.conf:

检索value:

omap header记录了以下统计信息:

对象存储object的数据存放在pool: zone.rgw.buckets.data 中。object的构成及寻址分为以下两类:

一个RGW Object可以由一个或多个rados object构成。其中第一个 object 是此RGW 的 head 对象,主要包含一些元数据信息,如 manifest, ACLs, content type, ETag, and user-defined metadata 。这些metadata存放在此head 对象的xattr中。其中 manifest 描述了此rgw object在分布情况。同时,此head对象,最多可额外容纳 4MB 数据,如果RGW Object大小下于 4MB ,那么此 RGW Object就不会分片,只有此 head 对象。
如下检索:

目前bucket下有一个 ntp.conf , <4MB 。检索其 manifest :

如上:
max_head_size: 表示head对象最大size;
head_size: 表示当前head 对象size;
prefix: 用于在rados中分片object的寻址。

RGW OBject ACL:

上传一个 >4MB 的 RGW Object,检索其 manifest 信息:

Manifest信息:

根据 manifest 检索对象:

对于一个大的RGW Object,会被切割成多个独立的RGW Object上传,称为multipart。multipar的优势是断点续传。s3接口默认切割大小为15MB。

在此,上传一个60MB大小的Object。

分成了四个部分上传,查看rados对象:

包含了三类对象, head,multipart,shadow 。

multipart 下的 manifest :

所有的object的检索是根据上述manifest信息构建object index:

在上以上的信息中,此RGW Object大小为48128000字节,分为4段,三段15MB,最后一段为920KB。同时每段存储在rados集群中的条带化大小为4MB。因此15MB大小的分段,也分为4个rados object,一个multipart首部,及3个shadow分片。920KB大小的分段只有一个multipart首部。

.rgw.root :

包含的都是zone,zonegroup,realm等信息

以上是关于rgw里面用户、bucket、用户数据之间关系的主要内容,如果未能解决你的问题,请参考以下文章

Ceph rgw multi-tenancy多租户实测

CEPH RGW 设置 user default_placement为ssd-placement,优化100KB-200KB小文件性能,使用户创建的bucket对象放置到 SSD设备上。

关于ceph rgw storage_class 的使用研究(amazon S3 智能分层 )

Ceph配置桶存储分片

如何使用ansible部署ceph-rgw

010 Ceph RGW对象存储