3.2.3 I/O路径
RGW是 RADOSGateway, 顾名思义是 RADOS对象存储系统上层的一个网关服务,根据网关的功能定义,网关负责完成不同协议的转换和对接。在Ceph场景中,RGW即完成类似的功能:接收用户 S3/Swift接口规则的数据存取请求,然后将其转化为后端RADOS能够处理的操作。
RGW 的请求处理经历了3 个阶段:
(1) Web框架主要负责接收用户请求,RGW中常用的 Web框架包括 CivetWeb、Apache、Beast等;
(2) 根据用户请求类型,分别选择不同的RESTMgr(针对不同的Resource)、 Handler、RGWOp来处理用户的具体业务,梳理出用户的请求数据;
(3) 将用户的业务请求转换为对 RADOS层数据读写请求的封装, 具体操作由RGWRados完成。
RGW的业务架构示意如图 3-29所示。请求到达 RGW网关后,在 RGWFrontend层做相应转发,请求到达RGWRESTMgr层,RGWRESTMgr依照请求资源类型,对请求做相应的 RGWHandler层的资源实例化工作。
在 RGWHandler层中实例化后的请求,首先进行前置处理,完成基本信息的校验等工作,在校验完成后,调用相关的业务接口RGWOp完成 Bucket和 Object的请求处理, 并在 RGWOp中,调用终极接口 RGWRados,完成 RGW数据的最终落盘(RGWRados是 RGW网关模块和后端的 RADOS底层存储系统交互的窗口)。RGW请求处理流程见图 3-30。
图3-29 RGw 业务架构示意
图3-30 RGw 请求处理流程
对应上述业务处理过程,RGW中会有 3个重要的数据结构:RGWFrontend、RGWRESTMgr及 RGWHandler。
◆ RGWFrontend:RGWFrontend是 RGW的 WEB前端类的封装,用于处理 HTTP(s)相关的请求,完成RGW业务逻辑中的 WEB 框架接收用户请求的功能。目前最新的 WEB框架是 Beast。
◆ RGWRESTMgr:RGWRESTMgr负责RGW 处理的资源类型区分,RGWRESTMgr包含了多种不同类型的路径和资源,并可根据请求资源类型的不同,将请求“路由”到不同的业务逻辑来进行处理(请求的实例化工作)。
◆ RGWHandler:RGWHandler负责具体的用户请求处理,如客户使用 S3规范进行业务请求,该层中会调用S3相关的 RGWHandler,后续操作如下。
(1) RGWHandler_REST_Service_S3
负责处理S3 用户类型请求,包括获取用户的统计信息、用户的桶列表、S3账户访问权限设置等。
(2) RGWHandler_REST_Bucket_S3
负责处理S3桶类型请求,包括桶的ACL权限列表、生命周期规则以及具体的创建/删除桶等操作。
(3) RGWHandler_REST_Obj_S3
负责处理 S3Object类型请求, 包括 Object的 ACL权限列表、Tagging及具体的Object数据操作(简单上传、分块上传、删除)等。
3.2.4 元数据/数据布局
前面提到过,CephRGW将数据组织分为 3种类型:Metadata、bucketindex及data。Metadata是对象的元数据, 包含 user、bucket、bucket.instance、OTP等信息;bucketindex 是对象的索引,严格意义上,也可以将其归类到元数据范畴内;data是对象的数据,每个 RGW对象(rgw-object)都会保存在一个或多个 RADOS对象(system-object)里。
CephRADOS层中的对象(system-object),通常以下列3种形式进行组织。
◆ RADOS对象 Data;
◆ RADOS对象扩展属性 xattr;
◆ RADOS 对象 OMAP。
1. RGW Metadata
CephRGW 的元数据包含以下信息。
◆ user:用来保存用户信息。
◆ bucket:用来维护 bucketname和bucketinstanceID的映射。
◆ bucket.instance:用来保存 bucketinstance信息。
◆ OPT(One-timePassword mechanism):Ceph N 版新增特性,可以根据虚拟或硬件MFA(Multi-factorAuthentication)设备,基于 OTP算法生成一个密码。
可以使用如下命令查看当前 RGW元数据的类别。
# ./bin/radosgw-admin metadata list[
"bucket""bucket.instance"
"otp”
"user"
]
(1) User元数据
通过以下命令查看某个用户的元数据。
#./bin/radosgw-adminmetadata getuser:john
{
"key": "user:john""ver": {
"tag": "_l1Bbi640q1-AJVYHHiY_mJk""ver": 1
}
"mtime":"2020-08-30T08:14:09.884832Z"
"data": {
"user_id": "john""display_name”:“john”
"email":""
"suspended":0
"max_buckets":1000
"subusers":[]
"keys": [
{
"user": "john""access_key": "john""secret_key":"john"
}
]
"swift_keys":[]
"caps":[]
"op_mask": "read write delete""default_placement": """default_storage_class": """placement_tags": []"bucket_quota":{
"enabled": false"check_on_raw": false"max_size":-1
"max_size_kb":0
"max_objects":-1
}
"user_quota": {"enabled": false"check_on_raw": false"max_size":-1
"max_size_kb":0
"max_objects":-1
}
"temp_url_keys": []"type": "rgw”
"mfa_ids":[]
"attrs":[]
}
}
这些 user信息存储在存储池 {zone}.rgw.meta的 users:{field}命名空间里,field字段当前有 keys、swift、email、uid,分别对应用户的 S3密钥对、Swift密钥对、邮箱、用户 ID等信息。
例如,users.uid命名空间里,包含了用户john对应的两个 RADOS对象 {uid} 和 {uid}.bucket(如john和john.bucket),john对象里存储着用户基本信息数据,john.buckets则以 OMAP形式保存着用户的存储桶信息。通过 RADOS命令可以查看。
#./bin/rados ls-p default.rgw.meta --namespace=users.uid| grep john
john.bucketsjohn
{user_id}.buckets以 OMAP形式保存。OMAPKey为用户拥有的存储桶名,当用户需要列出自己的桶列表时,就对OMAPKey遍历来获取。OMAPValue为桶的基本信息,如桶名、桶 ID、桶内对象大小、对象数量、桶创建时间等。
可以通过以下命令查看。
####使⽤ RADOS命令查看⽤户john拥有的存储桶
#./bin/radoslistomapkeys-pdefault.rgw.meta--namespace=users.uidjohn.buckets
john-bkt1
#### 获得 OMAPValue,然后解析出内容
#./bin/radosgetomapval-pdefault.rgw.meta--namespace=users.uid john.
buckets john-bkt1 john-bkt1.txtWritingto john-bkt1.txt
# ./bin/ceph-dencoder import john-bkt1.txt type cls_user_bucket_entry decodedump_json
{
"bucket": {
"name":"john-bkt1"
"marker":"54dba15f-9c2e-40ea-8b87-fc5f2eb01236.154118.1"
"bucket_id":"54dba15f-9c2e-40ea-8b87-fc5f2eb01236.154118.1"
}
"size":6775
"size_rounded":8192
"creation_time":"2020-08-30T08:21:57.057841Z"
"count": 1
"user_stats_sync":"true"
}
(2) Bucket/BucketInstance元数据
使用以下命令获得 bucket的元数据信息。
#./bin/radosgw-adminmetadatagetbucket:john-bkt1
{
"key": "bucket:john-bkt1""ver": {
"tag": "_d4u-u5S_CzORuXmXK-O280O""ver": 1
}
"mtime":"2020-08-30T08:21:56.996327Z"
"data": {
"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":""
}
}
"owner":"john"
"creation_time":"2020-08-30T08:21:56.873461Z"
"linked":"true"
"has_bucket_info":"false"
}
}
使用以下命令获得 bucketinstance元数据信息。
# ./bin/radosgw-admin metadata get bucket.instance:john-bkt1:54dba15f-9c2e-40ea-8b87-fc5f2eb01236.154118.1
{
"key":"bucket.instance:john-bkt1:54dba15f-9c2e-40ea-8b87-fc5f2eb01236.154118.1""ver": {
"tag": "_xo05nh_v_OZBNq8zkM20Yuz""ver": 1
}
"mtime":"2020-08-30T08:21:56.981329Z"
"data": {
"bucket_info":{
"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":""
}
}
"creation_time":"2020-08-30T08:21:56.873461Z"
"owner":"john"
"flags": 0
"zonegroup":"fddc0981-34db-49f1-b6c7-aea8d36dda1c"
"placement_rule": "default-placement""has_instance_obj":"false"
"quota": {
"enabled": false"check_on_raw": false"max_size":-1
"max_size_kb":0
"max_objects":-1
}
"num_shards":11
"bi_shard_hash_type": 0"requester_pays": "false""has_website": "false""swift_versioning": "false""swift_ver_location": """index_type": 0"mdsearch_config": []"reshard_status": 0"new_bucket_instance_id":""
}
"attrs": [
{
"key":"user.rgw.acl"
"val": "AgJ7AAAAAwIQAAAABAAAAGpvaG4EAAAAam9obgQDXwAAAAEBAAAABAAAAGpvaG4PAAAAAQAAAAQAAABqb2huBQM0AAAAAgIEAAAAAAAAAAQAAABqb2huAAAAAAAAAAACAgQAAAAPAAAABAAAAGpvaG4AAAAAAAAAAAAAAAAAAAAA"
}
]
}
}
bucket/bucketinstance元数据信息都存储在存储池 {zone}.rgw.meta的 root命名空间里。
#./bin/rados ls -pdefault.rgw.meta --namespace=root | grepjohn
john-bkt1
.bucket.meta.john-bkt1:54dba15f-9c2e-40ea-8b87-fc5f2eb01236.154118.1
其中,{bucket}对象作为数据存储,记录了bucketinstance和它的 owner的信息。
.bucket.meta.{tenant}.{bucket}:{marker}对象存储了存储桶元数据信息,其 xattr里记录了访问该桶的授权信息。
#### 解析 bucketmeta信息
# ./bin/rados get -p default.rgw.meta --namespace=root .bucket.meta.john-bkt1:54dba15f-9c2e-40ea-8b87-fc5f2eb01236.154118.1john-bkt1.instance.txt#./bin/ceph-dencoderimportjohn-bkt1.instance.txttypeRGWBucketInfodecodedump_json
{
"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":""
}
}
"creation_time":"2020-08-30T08:21:56.873461Z"
"owner":"john"
"flags": 0
"zonegroup": "fddc0981-34db-49f1-b6c7-aea8d36dda1c""placement_rule": "default-placement""has_instance_obj":"false"
"quota": {
"enabled": false"check_on_raw": false"max_size":-1
"max_size_kb":0
"max_objects":-1
}
"num_shards":11
"bi_shard_hash_type": 0"requester_pays": "false""has_website": "false""swift_versioning": "false""swift_ver_location": """index_type": 0"mdsearch_config": []"reshard_status": 0"new_bucket_instance_id":""
}
#### 解析 bucketACL信息
#./bin/radoslistxattr-pdefault.rgw.meta--namespace=root.bucket.meta.
john-bkt1:54dba15f-9c2e-40ea-8b87-fc5f2eb01236.154118.1
ceph.objclass.version
user.rgw.acl
# ./bin/rados getxattr -p default.rgw.meta --namespace=root .bucket.meta.john-bkt1:54dba15f-9c2e-40ea-8b87-fc5f2eb01236.154118.1 user.rgw.acl > john-bkt1.acl.txt
#./bin/ceph-dencoderimportjohn-bkt1.acl.txttypeRGWAccessControlPolicydecodedump_json
{
"acl": {
"acl_user_map": [ # ⽤户 ACL信息
{
"user": "john""acl":15
}
]
"acl_group_map": [] # 预定义组的授权信息
"grant_map": [ # 授权⽤户ACL信息
{
"id":"john"
"grant": {
"type": {
"type": 0
}
"id":"john"
"email":""
"permission": {"flags":15
}
"name": "john""group": 0"url_spec":""
}
}
]
}
"owner": {
"id":"john"
"display_name":"john"
}
}
(3) BucketIndex元数据
使用以下命令获得 bucket对应的 bucketindex信息。
# ./bin/radosgw-admin bi list --bucket john-bkt1[
{
"type":"plain"
"idx":"ceph.conf”
"entry": {
"name":"ceph.conf"
"instance":""
"ver": {
"pool": 7
"epoch":481480
}
"locator":""
"exists":"true"
"meta": {
"category":1
"size":6775
"mtime":"2020-08-30T08:22:04.626979Z"
"etag":"155e629efda9bd340ebf8494fed41ba4"
"storage_class": "STANDARD""owner": "john""owner_display_name": "john""content_type": "text/plain""accounted_size": 6775"user_data":"""appendable":"false"
}
"tag":"54dba15f-9c2e-40ea-8b87-fc5f2eb01236.154109.3286743"
"flags": 0"pending_map": []"versioned_epoch":0
}
}
]
bucketindex信息存储在存储池 {zone}.rgw.buckets.index里, 命名格式为:.dir.
{bucket_id}.{shard_id}。
通过如下命令查看存储桶索引。
#./bin/rados-pdefault.rgw.buckets.index ls|grep 54dba15f-9c2e-40ea-8b87-
fc5f2eb01236.154118.1
.dir.54dba15f-9c2e-40ea-8b87-fc5f2eb01236.154118.1.6
.dir.54dba15f-9c2e-40ea-8b87-fc5f2eb01236.154118.1.1
.dir.54dba15f-9c2e-40ea-8b87-fc5f2eb01236.154118.1.4
.dir.54dba15f-9c2e-40ea-8b87-fc5f2eb01236.154118.1.2
.dir.54dba15f-9c2e-40ea-8b87-fc5f2eb01236.154118.1.5
.dir.54dba15f-9c2e-40ea-8b87-fc5f2eb01236.154118.1.7
.dir.54dba15f-9c2e-40ea-8b87-fc5f2eb01236.154118.1.10
.dir.54dba15f-9c2e-40ea-8b87-fc5f2eb01236.154118.1.0
.dir.54dba15f-9c2e-40ea-8b87-fc5f2eb01236.154118.1.8
.dir.54dba15f-9c2e-40ea-8b87-fc5f2eb01236.154118.1.9
.dir.54dba15f-9c2e-40ea-8b87-fc5f2eb01236.154118.1.3
Bucketindex维护着 bucket和 bucket里对象的映射信息, 这个映射信息存储在RADOS对象的 OMAP 里。如果存储桶开启了分片功能,这些映射关系会被切分,保存在多个 RADOS对象的 OMAP里。
OMAPKey为 RGW 对象名,当列出桶内对象时,实际上就是遍历这些存储桶索引的OMAP的所有 Key。
#./bin/radoslistomapkeys-pdefault.rgw.buckets.index.dir.54dba15f-9c2e-
40ea-8b87-fc5f2eb01236.154118.1.7
ceph.conf
OMAPValue 为对象的一些基本元数据信息。
# ./bin/rados getomapval -p default.rgw.buckets.index .dir.54dba15f-9c2e-40ea-8b87-fc5f2eb01236.154118.1.7ceph.conf ceph.conf.txt
Writingtoceph.conf.txt
# ./bin/ceph-dencoder import ceph.conf.txt type rgw_bucket_dir_entry decodedump_json
{
"name":"ceph.conf"
"instance":""
"ver": {
"pool": 7
"epoch":481480
}
"locator":""
"exists":"true"
"meta": {
"category":1
"size":6775
"mtime":"2020-08-30T08:22:04.626979Z"
"etag":"155e629efda9bd340ebf8494fed41ba4"
"storage_class": "STANDARD""owner": "john""owner_display_name": "john""content_type": "text/plain""accounted_size": 6775"user_data":"""appendable":"false"
}
"tag":"54dba15f-9c2e-40ea-8b87-fc5f2eb01236.154109.3286743"
"flags": 0"pending_map": []"versioned_epoch":0
}
每个 OMAP都有 header 信息,里面包含了存储桶统计、对象数量、总大小等信息。获得某个 bucketindex对象对应的header信息, 里面包含了这个 index对象的
OMAPheader 对应的统计信息和分片信息。
#./bin/radosgetomapheader-pdefault.rgw.buckets.index.dir.54dba15f-9c2e-
40ea-8b87-fc5f2eb01236.154118.1.7 index-header.txtWritingto index-header.txt
#./bin/ceph-dencoderimportindex-header.txttypergw_bucket_dir_headerdecodedump_json
{
"ver": 2
"master_ver": 0
"stats": [
1
{
"total_size":6775
"total_size_rounded":8192
"num_entries":1
"actual_size":6775
}
]
"new_instance":{
"reshard_status": "not-resharding""new_bucket_instance_id": """num_shards":-1
}
}
(4) OTP元数据
CephM版本支持MFA。MFA(Multi-FactorAuthentication)即多重要素认证,是 AWSS3 提供的一个提高数据安全性的功能。它能够在用户名称和密码之外再额外增加一层保护,当用户启用 MFA功能后,在进行操作时,除了要提供用户名和密码外,还需要提供来自MFA设备的身份验证代码。
当前在 AWSS3中,MFA 主要应用于对启用版本控制功能的存储桶的数据删除场景。当前Ceph支持基于时间的一次性密码算法(TOTP)。
为用户配置了 MFA后,OTP 元数据通过以下命令查看。
#./bin/radosgw-admin metadatalist otp
[
"user:john"
]
相关元数据会存储在 {zone}.rgw.otp池里。
#./bin/rados ls -pdefault.rgw.otp
user:john
#./bin/radoslistomapkeys -pdefault.rgw.otpuser:john
header
OMAPKey的 header对应用户的 MFAID,otp/{totp-serial}对应用户相应的 MFA的配置。