《存储漫谈Ceph原理与实践》第三章接入层3.2对象存储RGW(四)

2.  RGWData

 

RGW对象数据存储在 {zone}.rgw.buckets.data池里,一个 RGW对象包含一个或多个 RADOS对象。

当 RGW收到写请求时,会基于 rgw_obj_stripe_size配置的值(默认为4MB)将数据切分为 stripe,并基于 rgw_max_chunk_size配置(默认为 4MB)将这些stripes划分为更小的 chunks,并将这些 chunks写入 RADOS集群。

第一个 chunk写入时会创建 Head对象,随后的 chunks作为tail 追加到对象后面写入。其中 Head对象包含了对象的一些元数据信息,如 ACL、manifest、etag等,作为 xattr保存。Head 对象本身可以包含 4MB 的数据。如果对象大于 4MB,就会生成tail 对象。

Head对象的 manifest 描述了对象的布局信息。查看对象的 xattr和 manifest,可使用如下命令。

 

# ./bin/rados listxattr -p default.rgw.buckets.data 54dba15f-9c2e-40ea-8b87-fc5f2eb01236.154118.1_ceph.conf

user.rgw.acluser.rgw.content_typeuser.rgw.etaguser.rgw.idtaguser.rgw.manifestuser.rgw.pg_veruser.rgw.source_zoneuser.rgw.storage_classuser.rgw.tail_tag

user.rgw.x-amz-content-sha256user.rgw.x-amz-date

user.rgw.x-amz-meta-s3cmd-attrs

 

#./bin/ceph-dencoderimportmanifest.txttypeRGWObjManifestdecodedump_json

{

"objs":[]

"obj_size": 6775"explicit_objs": "false""head_size":6775

"max_head_size":4194304

"prefix":".dhrTwsaLcBPQOYPeIx2bImXjxO_WCKk_"

"rules": [

{

"key": 0

"val": {

"start_part_num":0

"start_ofs":4194304

"part_size":0

"stripe_max_size":4194304

 

 

"override_prefix":""

}

}

]

"tail_instance": """tail_placement":{

"bucket": {

"name":"john-bkt1"

"marker": "54dba15f-9c2e-40ea-8b87-fc5f2eb01236.154118.1""bucket_id": "54dba15f-9c2e-40ea-8b87-fc5f2eb01236.154118.1""tenant":""

"explicit_placement": {"data_pool": """data_extra_pool": """index_pool":""

}

}

"placement_rule":"default-placement"

}

"begin_iter": {"part_ofs":0

"stripe_ofs":0

"ofs": 0

"stripe_size":6775

"cur_part_id":0

"cur_stripe": 0"cur_override_prefix": """location":{

"placement_rule":"default-placement"

"obj": {

"bucket": {

"name":"john-bkt1"

"marker": "54dba15f-9c2e-40ea-8b87-fc5f2eb01236.154118.1""bucket_id": "54dba15f-9c2e-40ea-8b87-fc5f2eb01236.154118.1""tenant":""

"explicit_placement": {"data_pool": """data_extra_pool": """index_pool":""

}

}

"key": {

"name":"ceph.conf"

 

 

 

"instance": ""

"ns": ""

}

}

"raw_obj":{

"pool": ""

"oid: ""

"loc": ""

}

"is_raw":false

}

}

"end_iter": {"part_ofs":4194304

"stripe_ofs":0

"ofs":6775

"stripe_size":6775

"cur_part_id":0

"cur_stripe": 0"cur_override_prefix": """location":{

"placement_rule":"default-placement"

"obj": {

"bucket": {

"name":"john-bkt1"

"marker": "54dba15f-9c2e-40ea-8b87-fc5f2eb01236.154118.1""bucket_id": "54dba15f-9c2e-40ea-8b87-fc5f2eb01236.154118.1""tenant":""

"explicit_placement": {"data_pool": """data_extra_pool": """index_pool":""

}

}

"key": {

"name":"ceph.conf"

"instance":""

"ns":""

}

}

"raw_obj":{

"pool":""

"oid":""

"loc":""

 

 

}

"is_raw":false

}

}

}

 

RGW中的对象对应RADOS对象(一对多关系,对象上传分整体上传和分段上传,不同的上传方式,对应 RADOS对象的方式不同。

首先介绍 3个概念。

◆  rgw_max_chunk_size

RGW下发至 RADOS集群的单个 I/O的大小, 同时也决定了应用对象分成多个RADOS对象时首对象的大小。

◆  rgw_obj_stripe_size

条带大小,也是 RADOS对象最大大小,如果大于rgw_max_chunk_size的对象文件,后续部分会根据这个参数切成多个RADOS对象。

◆  rgwobjectmanifest

管理应用对象和 RADOS 对象的对应关系。

基于以上概念,我们分别介绍普通上传以及分块上传。普通上传的流程如下。

(1)  当对象大小小于等于 rgw_max_chunk_size 时,用户上传的一个对象只对应一个RADOS对象,该RADOS 对象以对象名称命名,对象元数据也保存在该RADOS对象的扩展属性中。

(2)  当对象大小大于 rgw_max_chunk_size 时,对象被划分为一个大小等于分块大小的head以及多个大小等于 rgw_obj_stripe_size 的中间对象,和一个大小小于或等于 rgw_obj_stripe_size的 tail对象。head 以对象名称命名,该对象的数据部分保存了对象前 rgw_max_chunk_size字节的数据,扩展属性部分保存了对象的元数据信息和 manifest信息。中间对象和tail对象保存对象剩余的数据,对象名称为:''shadow_'+ '.' + '32bit随机字符串'

'_' + ' 条带编号',其中条带编号从1开始。分块上传的流程如下。

(1)  RGW根据条带大小 rgw_obj_stripe_size将对象的每一个分块分成多个 RADOS对象,每个分块的第一个 RADOS 对象名称为:'_multipart_'+ ' 用户上传对象名称 ' + ' 分块上传 ID' + ' 分段编号',其余对象的名称为:'_shadow_' + ' 用户上传对象名称' + ' 分块上传 ID'+ ' 分段编号' + '_' + ' 条带编号'。

(2)  当所有的分块上传结束后,RGW会从 data_extra_pool 中的分块上传的临时对象中读取各个分段信息,将各分段的 manifest信息组成一个 manifest;然后生成一个新的RADOS对象,即 head 对象,用来保存分块上传的对象的元数据信息和 manifest信息。

上一篇:带你读《存储漫谈Ceph原理与实践》第三章接入层3.1块存储 RBD(三)


下一篇:真!无钥匙!数字钥匙在智能电动车领域的实践