metadata

ceph rgw的元数据分成四类:

[root@muhongtao-ceph-3 rgw]# radosgw-admin metadata list
[
    "bucket",
    "bucket.instance",
    "otp",				//暂忽略不分析
    "user"
]

这里只分析三类:

  • bucket
  • bucket.instance
  • user

这三类元数据都是存放在 meta pool 中的, 可以通过命令:

[root@mceph-3 ~]# rados -p meta.pool ls --all   //查看meta.pool中存储的元数据有哪些
root    bucket1
root    .bucket.meta.bucket1:8fb2def7-7ccd-4803-a76a-566554e21b9e.95969.3
users.keys      3F998GKDQHGGOI7060CN
root    bucket2
users.uid       1009-user-01
root    sensebucket
root    .bucket.meta.sensebucket:8fb2def7-7ccd-4803-a76a-566554e21b9e.95969.1
root    .bucket.meta.bucket2:8fb2def7-7ccd-4803-a76a-566554e21b9e.95969.2
users.uid       1009-user-01.buckets
[root@mceph-3 ~]#

#ns=root [1]
[root@ceph-3 ~]# rados -p class_hdd_pool_1.meta ls --namespace=root
bucket1
.bucket.meta.bucket1:8fb2def7-7ccd-4803-a76a-566554e21b9e.95969.3
bucket2
.bucket.meta.bucket2:8fb2def7-7ccd-4803-a76a-566554e21b9e.95969.2
sensebucket
.bucket.meta.sensebucket:8fb2def7-7ccd-4803-a76a-566554e21b9e.95969.1
[root@ceph-3 ~]#

#ns=users.uid  [2]
[root@ceph-3 ~]# rados -p class_hdd_pool_1.meta ls --namespace=users.uid
1009-user-01
1009-user-01.buckets
[root@ceph-3 ~]#

#ns=users.keys  [3]
[root@ceph-3 ~]# rados -p class_hdd_pool_1.meta ls --namespace=users.keys
3F998GKDQHGGOI7060CN

针对元数据信息查询,都可以使用这一范式:

  • radosgw-admin metadata get bucket:bucket_name
  • radosgw-admin metadata get bucket.instance:bucket_name.instance
  • radosgw-admin metadata get bucket:bucket_name
  • [1] namespace=root: 上述在 namespace=root 下存储6哥 rados对象,分为三组,每组包含一个 rados bucket对象 和 一个 rados bucket.instance 对象。
[root@ceph-3 ~]# rados -p class_hdd_pool_1.meta ls --namespace=root
bucket1
.bucket.meta.bucket1:8fb2def7-7ccd-4803-a76a-566554e21b9e.95969.3
bucket2
.bucket.meta.bucket2:8fb2def7-7ccd-4803-a76a-566554e21b9e.95969.2
sensebucket
.bucket.meta.sensebucket:8fb2def7-7ccd-4803-a76a-566554e21b9e.95969.1

我们以bucket1组为例,来分别看一下这两个 rados对象中都包含了什么信息:

<1>. 查看这两个rados对象的xattr属性

[root@ceph-3 ~]# rados -p class_hdd_pool_1.meta listxattr --namespace=root bucket1
ceph.objclass.version
[root@ceph-3 ~]# rados -p class_hdd_pool_1.meta listxattr --namespace=root .bucket.meta.bucket1:8fb2def7-7ccd-4803-a76a-566554e21b9e.95969.3
ceph.objclass.version
user.rgw.acl
user.rgw.lc

针对rados对象:bucket1来讲, ceph.objclass.version是其存储在meta pool中的数据信息,该rados对象:bucket1仅仅包括一个扩展属性:xattr, 通过 getxattr获取该属性的值,显示为乱码:

[root@muhongtao-ceph-3 ~]# rados -p class_hdd_pool_1.meta getxattr --namespace=root bucket1 ceph.objclass.version
$_sFEdSejSKb39KBN0PS-IReM

//TODO: 怎么将该属性解码并输出看一下呢?

针对rados对象:.bucket.meta.bucket1:8fb2def7-7ccd-4803-a76a-566554e21b9e.95969.3来讲, ceph.objclass.version、user.rgw.acl、user.rgw.lc 是其存储在meta pool中的数据信息,该rados对象仅仅包括一个扩展属性:xattr, 通过getxattr将该属性的值保存下来并解码(解码需要知道对应的类型, 上边的ceph.objclass.version不知道对应类型):

#lc
[root@ceph-3 ~]# rados -p class_hdd_pool_1.meta getxattr --namespace=root .bucket.meta.bucket1:8fb2def7-7ccd-4803-a76a-566554e21b9e.95969.3 user.rgw.lc > lc.txt
[root@ceph-3 ~]# ceph-dencoder import lc.txt type RGWLifecycleConfiguration decode dump_json
{
    "prefix_map": {
        "transclod-": {
            "status": true,
            "dm_expiration": false,
            "expiration": 0,
            "noncur_expiration": 0,
            "mp_expiration": 0
        }
    },
    "rule_map": [
        {
            "id": "transbucket_id_0987654321_1019",         //这个是之前随意定的一个 id
            "rule": {
                "id": "transbucket_id_0987654321_1019",
                "prefix": "transclod-",                     //lc前缀
                "status": "Enabled",
                "expiration": {
                    "days": "",
                    "date": ""
                },
                "noncur_expiration": {
                    "days": "",
                    "date": ""
                },
                "mp_expiration": {
                    "days": "",
                    "date": ""
                },
                "filter": {
                    "prefix": "",
                    "obj_tags": {}
                },
                "dm_expiration": false
            }
        }
    ]
}

#acl
[root@ceph-3 ~]# rados -p class_hdd_pool_1.meta getxattr --namespace=root .bucket.meta.bucket1:8fb2def7-7ccd-4803-a76a-566554e21b9e.95969.3 user.rgw.acl > acl.txt
[root@ceph-3 ~]#
[root@ceph-3 ~]# ceph-dencoder import acl.txt type RGWAccessControlPolicy decode dump_json
{
    "acl": {
        "acl_user_map": [
            {
                "user": "1009-user-01",
                "acl": 15
            }
        ],
        "acl_group_map": [],
        "grant_map": [
            {
                "id": "1009-user-01",
                "grant": {
                    "type": {
                        "type": 0
                    },
                    "id": "1009-user-01",
                    "email": "",
                    "permission": {
                        "flags": 15
                    },
                    "name": "1009-user-01",
                    "group": 0,
                    "url_spec": ""
                }
            }
        ]
    },
    "owner": {
        "id": "1009-user-01",
        "display_name": "1009-user-01"
    }
}
  • [2] namespace=users.uid: 上述在 namespace=users.uid 下存储着两个 rados 对象: 1009-user-01 和 1009-user-01.buckets 那么这两个rados对象在 class_hdd_pool_1.meta 中都存储了什么东西呢?
[root@eph-3 rgw]# rados -p class_hdd_pool_1.meta --namespace=users.uid listxattr 1009-user-01
ceph.objclass.version
[root@ceph-3 rgw]# rados -p class_hdd_pool_1.meta --namespace=users.uid listxattr 1009-user-01.buckets
[root@ceph-3 rgw]# //空

rados对象:1009-user-01, 该对象只有一个 xattr属性, 没有omap属性。该对象本身包括了用户的基本信息, 都在该属性 xattr中。可以通过 getxattr获取该属性的值,但是显示为乱码:

[root@ceph-3 rgw]# rados -p class_hdd_pool_1.meta --namespace=users.uid getxattr 1009-user-01 ceph.objclass.version
$_yQablR9CUuAbj6nUUMdtI7t
[root@ceph-3 rgw]#

//TODO 怎么将该属性解码输出看一下呢?

rados对象:1009-user-01.buckets, 该对象本身不包含信息, 只是个占位符, 该对象真正包含的信息存放在 omap属性中, 该对象没有 xattr扩展属性。 用户在对bucket拉列表(list bucket)时候会用到这个rados对象的信息。 rados对象1009-user-01.buckets的omap中存储的都是一个个的<key, value>, 首先列举一下该对象含有的key有哪些:

[root@ceph-3 rgw]# rados -p class_hdd_pool_1.meta --namespace=users.uid listomapkeys 1009-user-01.buckets
bucket1
bucket2
sensebucket

在列举一下该rados对象含有的values:

[root@ceph-3 rgw]# rados -p class_hdd_pool_1.meta --namespace=users.uid listomapvals 1009-user-01.buckets
bucket1
value (172 bytes) :
00000000  09 05 a6 00 00 00 00 00  00 00 d1 04 00 00 00 00  |................|
00000010  00 00 7f 53 8d 5f 01 00  00 00 00 00 00 00 07 03  |...S._..........|
00000020  77 00 00 00 07 00 00 00  62 75 63 6b 65 74 31 00  |w.......bucket1.|
00000030  00 00 00 2c 00 00 00 38  66 62 32 64 65 66 37 2d  |...,...8fb2def7-|
00000040  37 63 63 64 2d 34 38 30  33 2d 61 37 36 61 2d 35  |7ccd-4803-a76a-5|
00000050  36 36 35 35 34 65 32 31  62 39 65 2e 39 35 39 36  |66554e21b9e.9596|
00000060  39 2e 33 2c 00 00 00 38  66 62 32 64 65 66 37 2d  |9.3,...8fb2def7-|
00000070  37 63 63 64 2d 34 38 30  33 2d 61 37 36 61 2d 35  |7ccd-4803-a76a-5|
00000080  36 36 35 35 34 65 32 31  62 39 65 2e 39 35 39 36  |66554e21b9e.9596|
00000090  39 2e 33 00 00 00 00 00  00 00 00 00 10 00 00 00  |9.3.............|
000000a0  00 00 00 01 7f 53 8d 5f  95 34 f1 18              |.....S._.4..|
000000ac

bucket2
value (172 bytes) :
00000000  09 05 a6 00 00 00 00 00  00 00 36 07 00 00 00 00  |..........6.....|
00000010  00 00 e6 b8 87 5f 01 00  00 00 00 00 00 00 07 03  |....._..........|
00000020  77 00 00 00 07 00 00 00  62 75 63 6b 65 74 32 00  |w.......bucket2.|
00000030  00 00 00 2c 00 00 00 38  66 62 32 64 65 66 37 2d  |...,...8fb2def7-|
00000040  37 63 63 64 2d 34 38 30  33 2d 61 37 36 61 2d 35  |7ccd-4803-a76a-5|
00000050  36 36 35 35 34 65 32 31  62 39 65 2e 39 35 39 36  |66554e21b9e.9596|
00000060  39 2e 32 2c 00 00 00 38  66 62 32 64 65 66 37 2d  |9.2,...8fb2def7-|
00000070  37 63 63 64 2d 34 38 30  33 2d 61 37 36 61 2d 35  |7ccd-4803-a76a-5|
00000080  36 36 35 35 34 65 32 31  62 39 65 2e 39 35 39 36  |66554e21b9e.9596|
00000090  39 2e 32 00 00 00 00 00  00 00 00 00 10 00 00 00  |9.2.............|
000000a0  00 00 00 01 e6 b8 87 5f  d4 42 01 21              |......._.B.!|
000000ac

sensebucket
value (176 bytes) :
00000000  09 05 aa 00 00 00 00 00  00 00 d7 04 a0 00 00 00  |................|
00000010  00 00 da 30 80 5f 04 00  00 00 00 00 00 00 07 03  |...0._..........|
00000020  7b 00 00 00 0b 00 00 00  73 65 6e 73 65 62 75 63  |{.......sensebuc|
00000030  6b 65 74 00 00 00 00 2c  00 00 00 38 66 62 32 64  |ket....,...8fb2d|
00000040  65 66 37 2d 37 63 63 64  2d 34 38 30 33 2d 61 37  |ef7-7ccd-4803-a7|
00000050  36 61 2d 35 36 36 35 35  34 65 32 31 62 39 65 2e  |6a-566554e21b9e.|
00000060  39 35 39 36 39 2e 31 2c  00 00 00 38 66 62 32 64  |95969.1,...8fb2d|
00000070  65 66 37 2d 37 63 63 64  2d 34 38 30 33 2d 61 37  |ef7-7ccd-4803-a7|
00000080  36 61 2d 35 36 36 35 35  34 65 32 31 62 39 65 2e  |6a-566554e21b9e.|
00000090  39 35 39 36 39 2e 31 00  00 00 00 00 00 00 00 00  |95969.1.........|
000000a0  20 a0 00 00 00 00 00 01  da 30 80 5f ef 00 bd 23  | ........0._...#|
000000b0

[root@ceph-3 rgw]#

我们来列举一个bucket的metadata, 注意上边listomapvals出的bucket1的size=172 bytes.

[root@ceph-3 ~]# rados -p class_hdd_pool_1.meta --namespace=users.uid getomapval 1009-user-01.buckets bucket1 bucket1.meta
Writing to bucket1.meta
[root@ceph-3 ~]# ls -la
total 8
drwxr-xr-x 2 root root  44 Oct 21 04:56 .
drwxr-xr-x 6 root root  95 Oct 21 02:44 ..
-rw-r--r-- 1 root root 172 Oct 21 04:56 bucket1.meta
[root@ceph-3 ~]#

可以看到 buceket1.meta 大小172 bytes. 来解析一下该文件:

[root@ceph-3 ceph_index]# ceph-dencoder import bucket1.meta type cls_user_bucket_entry decode dump_json
{
    "bucket": {
        "name": "bucket1",
        "marker": "8fb2def7-7ccd-4803-a76a-566554e21b9e.95969.3",
        "bucket_id": "8fb2def7-7ccd-4803-a76a-566554e21b9e.95969.3"
    },
    "size": 1233,			//包含的文件的总大小
    "size_rounded": 4096,	// ???
    "creation_time": "2020-10-19 08:51:11.418460Z", //bucket的创建时间
    "count": 1,			//文件个数
    "user_stats_sync": "true"
}

该rados对象1009-user-01.buckets中的数据存储在 omap中, 格式为<key, value>, key为bucket_name, value为”类型为cls_user_bucket_entry的序列化过的数据”

[3]:

[root@ceph-3 ~]# rados -p class_hdd_pool_1.meta ls --namespace=users.keys
3F998GKDQHGGOI7060CN    //这是该用户的access key

包含了key到uid的映射信息, 可以通过 access key找到uid

[root@ceph-3 ~]# rados -p class_hdd_pool_1.meta --namespace=users.keys get 3F998GKDQHGGOI7060CN key.txt
[root@ceph-3 ~]# cat key.txt
1009-user-01

index 索引数据

bucket index是一类特殊的 metadata, 通过bucket index, 可以列出该bucket下所有的 rgw对象。 bucket index保存在 index pool。我这里是: class_hdd_pool_1.index

bucket index信息本身保存在 index pool中:

[root@ceph-3 ~]# rados -p class_hdd_pool_1.index ls
.dir.8fb2def7-7ccd-4803-a76a-566554e21b9e.95969.1       // .dir. + bucket_id
.dir.8fb2def7-7ccd-4803-a76a-566554e21b9e.95969.3
.dir.8fb2def7-7ccd-4803-a76a-566554e21b9e.95969.2

index pool 中存放三个 rados对象( .dir. + bucket_id ), 分别是三个bucket的索引数据。 这三个rados对象是存放在 index pool 中的, 并且这三个rados对象的自身数据信息都存放在 omap中: <key, val>, key是bucket中的对象名(文件名), val是bucket中文件名对应的文件内容:即该文件的索引信息。

使用 listomapkeys即可将该bucket下所有的对象名列出来:

[root@muhongtao-ceph-3 ~]# rados -p class_hdd_pool_1.index listomapkeys .dir.8fb2def7-7ccd-4803-a76a-566554e21b9e.95969.1
test.5M.gz.clod.1009
transclod-5mb.1009
transclod-test.1009
transclod-user.md.json.1009
[root@muhongtao-ceph-3 ~]#
[root@muhongtao-ceph-3 ~]# rados -p class_hdd_pool_1.index listomapkeys .dir.8fb2def7-7ccd-4803-a76a-566554e21b9e.95969.2
uptransfer-zone1.bak.1015
[root@muhongtao-ceph-3 ~]# rados -p class_hdd_pool_1.index listomapkeys .dir.8fb2def7-7ccd-4803-a76a-566554e21b9e.95969.3
transclod-usermd.json.1019

同理使用 listomapvals 即可将该bucket下所有文件对象的索引列出来: (该bucket只含有一个对象)

[root@ceph-3 ~]# rados -p class_hdd_pool_1.index listomapvals .dir.8fb2def7-7ccd-4803-a76a-566554e21b9e.95969.3
transclod-usermd.json.1019
value (239 bytes) :
00000000  08 03 e9 00 00 00 1a 00  00 00 74 72 61 6e 73 63  |..........transc|
00000010  6c 6f 64 2d 75 73 65 72  6d 64 2e 6a 73 6f 6e 2e  |lod-usermd.json.|
00000020  31 30 31 39 02 00 00 00  00 00 00 00 01 07 03 78  |1019...........x|
00000030  00 00 00 01 d1 04 00 00  00 00 00 00 a8 53 8d 5f  |.............S._|
00000040  17 61 15 1a 20 00 00 00  64 32 39 64 31 63 65 32  |.a.. ...d29d1ce2|
00000050  32 36 35 31 38 38 36 37  34 35 64 35 33 35 36 30  |2651886745d53560|
00000060  66 66 61 30 39 37 63 62  0c 00 00 00 31 30 30 39  |ffa097cb....1009|
00000070  2d 75 73 65 72 2d 30 31  0c 00 00 00 31 30 30 39  |-user-01....1009|
00000080  2d 75 73 65 72 2d 30 31  0a 00 00 00 74 65 78 74  |-user-01....text|
00000090  2f 70 6c 61 69 6e d1 04  00 00 00 00 00 00 00 00  |/plain..........|
000000a0  00 00 04 00 00 00 43 4c  4f 44 00 00 00 00 00 00  |......CLOD......|
000000b0  00 00 00 01 01 03 00 00  00 81 89 02 02 20 00 00  |............. ..|
000000c0  00 5f 53 61 33 77 6a 56  56 33 69 58 61 34 59 76  |._Sa3wjVV3iXa4Yv|
000000d0  76 69 67 42 5a 64 52 37  36 6f 41 44 73 61 30 5f  |vigBZdR76oADsa0_|
000000e0  63 00 00 00 00 00 00 00  00 00 00 00 00 00 00     |c..............|

我们也使用 getomapval 将其列出: (getomapval是操作单个对象的命令: getomapval index_rados_obj original_obj_name)

[root@muhongtao-ceph-3 ~]# rados -p class_hdd_pool_1.index getomapval .dir.8fb2def7-7ccd-4803-a76a-566554e21b9e.95969.3 transclod-usermd.json.1019
value (239 bytes) :
00000000  08 03 e9 00 00 00 1a 00  00 00 74 72 61 6e 73 63  |..........transc|
00000010  6c 6f 64 2d 75 73 65 72  6d 64 2e 6a 73 6f 6e 2e  |lod-usermd.json.|
00000020  31 30 31 39 02 00 00 00  00 00 00 00 01 07 03 78  |1019...........x|
00000030  00 00 00 01 d1 04 00 00  00 00 00 00 a8 53 8d 5f  |.............S._|
00000040  17 61 15 1a 20 00 00 00  64 32 39 64 31 63 65 32  |.a.. ...d29d1ce2|
00000050  32 36 35 31 38 38 36 37  34 35 64 35 33 35 36 30  |2651886745d53560|
00000060  66 66 61 30 39 37 63 62  0c 00 00 00 31 30 30 39  |ffa097cb....1009|
00000070  2d 75 73 65 72 2d 30 31  0c 00 00 00 31 30 30 39  |-user-01....1009|
00000080  2d 75 73 65 72 2d 30 31  0a 00 00 00 74 65 78 74  |-user-01....text|
00000090  2f 70 6c 61 69 6e d1 04  00 00 00 00 00 00 00 00  |/plain..........|
000000a0  00 00 04 00 00 00 43 4c  4f 44 00 00 00 00 00 00  |......CLOD......|
000000b0  00 00 00 01 01 03 00 00  00 81 89 02 02 20 00 00  |............. ..|
000000c0  00 5f 53 61 33 77 6a 56  56 33 69 58 61 34 59 76  |._Sa3wjVV3iXa4Yv|
000000d0  76 69 67 42 5a 64 52 37  36 6f 41 44 73 61 30 5f  |vigBZdR76oADsa0_|
000000e0  63 00 00 00 00 00 00 00  00 00 00 00 00 00 00     |c..............|
000000ef

我们将该索引信息进行解码:

[root@ceph-3 ~]# rados -p class_hdd_pool_1.index getomapval .dir.8fb2def7-7ccd-4803-a76a-566554e21b9e.95969.3 transclod-usermd.json.1019 transclod-usermd.json.1019
Writing to transclod-usermd.json.1019
[root@ceph-3 ~]# ls
transclod-usermd.json.1019

#文件的索引内容
[root@ceph-3 ~]# ceph-dencoder import transclod-usermd.json.1019 type rgw_bucket_dir_entry decode dump_json
{
    "name": "transclod-usermd.json.1019",
    "instance": "",
    "ver": {
        "pool": 137,
        "epoch": 2
    },
    "locator": "",
    "exists": "true",
    "meta": {           //文件的元数据
        "category": 1,
        "size": 1233,
        "mtime": "2020-10-19 08:51:52.437608Z",
        "etag": "d29d1ce22651886745d53560ffa097cb",
        "storage_class": "CLOD",
        "owner": "1009-user-01",
        "owner_display_name": "1009-user-01",
        "content_type": "text/plain",
        "accounted_size": 1233,
        "user_data": "",
        "appendable": "false"
    },
    "tag": "_Sa3wjVV3iXa4YvvigBZdR76oADsa0_c",
    "flags": 0,
    "pending_map": [],
    "versioned_epoch": 0
}

总结一下:

  • bucket index信息存储在 index pool中。
  • bucket index中记录的bucket相关信息(含有哪些key, 以及key对应的vals)存储在 omap中:
    • omap<key, val>, key是bucket下存储的对象名, val是这些文件名对应的索引信息, val的结构是: rgw_bucket_dir_entry
    • 每个bucket还有一个bucket header存放在omap 中,记录该bucekt的对象个数,总大小等

查看一下 omap header信息:

[root@ceph-3 ~]# rados getomapheader -p class_hdd_pool_1.index .dir.8fb2def7-7ccd-4803-a76a-566554e21b9e.95969.3 header.txt
Writing to header.txt
[root@ceph-3 ~]# ceph-dencoder type rgw_bucket_dir_header import header.txt decode dump_json
{
    "ver": 3,
    "master_ver": 0,
    "stats": [
        1,
        {
            "total_size": 1233,         //该bucket目前的存储量大小
            "total_size_rounded": 4096,
            "num_entries": 1,           //对象个数
            "actual_size": 1233         //真实大小???
        }
    ],
    "new_instance": {
        "reshard_status": "not-resharding",
        "new_bucket_instance_id": "",
        "num_shards": -1
    }
}

object info

关于对象信息请看另一篇文章:object数据格式分析