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

概览

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

  • 理解一个用户的信息是如何保存在底层rados中的
  • 理解一个bucket的信息是如何保存在底层rados中的
  • 理解一个用户和该用户所拥有的bucket之间的关系
  • 理解一个bucket和该bucket里面的用户数据之间的关系

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

1、配置一个radosgw服务

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

1.1、准备radosgw配置文件

[root@ceph01 tmp]# cat /etc/ceph/ceph.conf
···
[client.rgw.inst01]
rgw_frontends = civetweb port=9001

1.2、启动radosgw服务

[root@ceph01 tmp]# systemctl start ceph-radosgw@rgw.inst01

查看rados里面的存储池

[root@ceph01 tmp]# ceph osd pool ls
rbd
.rgw.root
default.rgw.control
default.rgw.data.root
default.rgw.gc
default.rgw.log
default.rgw.users.keys

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

2、准备数据

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

2.1、创建一个radosgw用户

[root@ceph01 tmp]# radosgw-admin user create --uid=rgwuser01 --display-name=rgwuser01 --access-key=rgwuser01 --secret=rgwuser01
{
    "user_id": "rgwuser01",
    "display_name": "rgwuser01",
    "email": "",
    "suspended": 0,
    "max_buckets": 1000,
    "auid": 0,
    "subusers": [],
    "keys": [
        {
            "user": "rgwuser01",
            "access_key": "rgwuser01",
            "secret_key": "rgwuser01"
        }
    ],
    "swift_keys": [],
    "caps": [],
    "op_mask": "read, write, delete",
    "default_placement": "",
    "placement_tags": [],
    "bucket_quota": {
        "enabled": false,
        "max_size_kb": -1,
        "max_objects": -1
    },
    "user_quota": {
        "enabled": false,
        "max_size_kb": -1,
        "max_objects": -1
    },
    "temp_url_keys": []
}

再次查看rados里面的存储池

[root@ceph01 tmp]# ceph osd pool ls
rbd
.rgw.root
default.rgw.control
default.rgw.data.root
default.rgw.gc
default.rgw.log
default.rgw.users.keys
default.rgw.users.uid   

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

2.2、创建bucket

使用s3cmd客户端创建一个bucket

[root@ceph07 ~]# s3cmd mb s3://bk01
Bucket 's3://bk01/' created

再次查看rados里面的存储池

[root@ceph01 tmp]# ceph osd pool ls
rbd
.rgw.root
default.rgw.control
default.rgw.data.root
default.rgw.gc
default.rgw.log
default.rgw.users.keys
default.rgw.users.uid
default.rgw.buckets.index

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

3、理解用户、bucket、用户对象之间的关系,以及它们和rados对象的对应关系

3.1、用户和rados对象对应关系

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

[root@ceph01 tmp]# rados -p default.rgw.users.uid ls
rgwuser01.buckets
rgwuser01

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

3.2、bucket和rados对象的对应关系

[root@ceph01 tmp]# rados -p default.rgw.data.root ls
.bucket.meta.bk01:475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1
bk01

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

[root@ceph01 tmp]# rados -p default.rgw.data.root get .bucket.meta.bk01:475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1 bucket.meta.bk01

[root@ceph01 tmp]# ll
total 8
-rw-r--r--. 1 root root 341 Oct 25 17:19 bucket.meta.bk01
···

[root@ceph01 tmp]# ceph-dencoder type RGWBucketInfo import bucket.meta.bk01 decode dump_json
{
    "bucket": {
        "name": "bk01",
        "pool": "default.rgw.buckets.data",
        "data_extra_pool": "default.rgw.buckets.non-ec",
        "index_pool": "default.rgw.buckets.index",
        "marker": "475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1",
        "bucket_id": "475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1",
        "tenant": ""
    },
    "creation_time": "2018-10-25 09:05:06.249973Z",
    "owner": "rgwuser01",
    "flags": 0,
    "zonegroup": "3a55c2fa-805b-4166-961b-907654e76cb6",
    "placement_rule": "default-placement",
    "has_instance_obj": "true",
    "quota": {
        "enabled": false,
        "max_size_kb": -1,
        "max_objects": -1
    },
    "num_shards": 0,
    "bi_shard_hash_type": 0,
    "requester_pays": "false",
    "has_website": "false",
    "swift_versioning": "false",
    "swift_ver_location": "",
    "index_type": 0
}

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

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

[root@ceph01 tmp]# rados -p default.rgw.data.root getxattr .bucket.meta.bk01:475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1 user.rgw.acl > encode.bk01.bucket.acl
[root@ceph01 tmp]# ceph-dencoder type RGWAccessControlPolicy import encode.bk01.bucket.acl decode dump_json
{
    "acl": {
        "acl_user_map": [
            {
                "user": "rgwuser01",
                "acl": 15
            }
        ],
        "acl_group_map": [],
        "grant_map": [
            {
                "id": "rgwuser01",
                "grant": {
                    "type": {
                        "type": 0
                    },
                    "id": "rgwuser01",
                    "email": "",
                    "permission": {
                        "flags": 15
                    },
                    "name": "rgwuser01",
                    "group": 0
                }
            }
        ]
    },
    "owner": {
        "id": "rgwuser01",
        "display_name": "rgwuser01"
    }
}

3.3、用户和bucket的对应关系

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

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

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

[root@ceph01 tmp]# rados -p default.rgw.users.uid listomapkeys rgwuser01.buckets
bk01

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

[root@ceph01 tmp]# rados -p default.rgw.users.uid getomapval rgwuser01.buckets bk01 encode_bk01
Writing to encode_bk01

[root@ceph01 tmp]# ll
total 4
-rw-r--r--. 1 root root 244 Oct 25 17:13 encode_bk01

[root@ceph01 tmp]# ceph-dencoder type RGWBucketEnt import encode_bk01 decode dump_json
{
    "bucket": {
        "name": "bk01",
        "pool": "default.rgw.buckets.data",
        "data_extra_pool": "default.rgw.buckets.non-ec",
        "index_pool": "default.rgw.buckets.index",
        "marker": "475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1",
        "bucket_id": "475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1",
        "tenant": ""
    },
    "size": 0,
    "size_rounded": 0,
    "mtime": "2081-05-24 08:53:24.863590Z",
    "count": 0
}

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

3.4、bucket和bucket里面数据的对应关系

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

[root@ceph07 ~]# s3cmd put anaconda-ks.cfg s3://bk01
upload: 'anaconda-ks.cfg' -> 's3://bk01/anaconda-ks.cfg'  [1 of 1]
 1021 of 1021   100% in    1s   677.26 B/s  done

查看rados里面的存储池信息

[root@ceph01 tmp]# ceph osd pool ls
rbd
.rgw.root
default.rgw.control
default.rgw.data.root
default.rgw.gc
default.rgw.log
default.rgw.users.keys
default.rgw.users.uid
default.rgw.buckets.index
default.rgw.buckets.data

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

[root@ceph01 tmp]# rados -p default.rgw.buckets.data ls
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1_anaconda-ks.cfg

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

[root@ceph01 tmp]# rados -p default.rgw.buckets.index ls
.dir.475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1

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

[root@ceph01 tmp]# rados -p default.rgw.buckets.index listomapkeys .dir.475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1
anaconda-ks.cfg

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

[root@ceph07 ~]# cp anaconda-ks.cfg anaconda-ks.cfg2
[root@ceph07 ~]# s3cmd put anaconda-ks.cfg2 s3://bk01
upload: 'anaconda-ks.cfg2' -> 's3://bk01/anaconda-ks.cfg2'  [1 of 1]
 1021 of 1021   100% in    0s    18.55 kB/s  done

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

[root@ceph01 tmp]# rados -p default.rgw.buckets.index listomapkeys .dir.475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1
anaconda-ks.cfg
anaconda-ks.cfg2

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

4、根据底层的rados对象拼接用户文件

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

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

[root@ceph07 ~]# ll
total 85576
···
-rw-r--r--. 1 root root 87581279 Oct 26 15:24 messages-20180722

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

[root@ceph07 ~]# md5sum messages-20180722 
b4a6227030352dcc3318684789fda6e1  messages-20180722

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

[root@ceph07 ~]# s3cmd put messages-20180722 s3://bk01
upload: 'messages-20180722' -> 's3://bk01/messages-20180722'  [part 1 of 6, 15MB] [1 of 1]
 15728640 of 15728640   100% in    0s    23.46 MB/s  done
upload: 'messages-20180722' -> 's3://bk01/messages-20180722'  [part 2 of 6, 15MB] [1 of 1]
 15728640 of 15728640   100% in    0s    31.34 MB/s  done
upload: 'messages-20180722' -> 's3://bk01/messages-20180722'  [part 3 of 6, 15MB] [1 of 1]
 15728640 of 15728640   100% in    2s     5.05 MB/s  done
upload: 'messages-20180722' -> 's3://bk01/messages-20180722'  [part 4 of 6, 15MB] [1 of 1]
 15728640 of 15728640   100% in    1s     9.08 MB/s  done
upload: 'messages-20180722' -> 's3://bk01/messages-20180722'  [part 5 of 6, 15MB] [1 of 1]
 15728640 of 15728640   100% in    1s    11.20 MB/s  done
upload: 'messages-20180722' -> 's3://bk01/messages-20180722'  [part 6 of 6, 8MB] [1 of 1]
 8938079 of 8938079   100% in    0s    11.76 MB/s  done

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

[root@ceph01 ~]# rados -p default.rgw.buckets.data ls|grep messages-20180722
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__shadow_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.2_2
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__multipart_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.1
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__shadow_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.4_2
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__shadow_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.6_2
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1_messages-20180722
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__shadow_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.3_1
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__shadow_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.1_1
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__shadow_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.5_1
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__shadow_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.5_2
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__shadow_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.3_3
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__multipart_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.5
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__shadow_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.1_2
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__shadow_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.5_3
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__shadow_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.3_2
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__multipart_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.4
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__shadow_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.1_3
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__shadow_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.2_3
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__shadow_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.2_1
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__shadow_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.4_3
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__shadow_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.6_1
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__shadow_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.4_1
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__multipart_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.2
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__multipart_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.6
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__multipart_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.3

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

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

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

[root@ceph01 messagesobj]# cat messages-obj 
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1_messages-20180722
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__multipart_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.1
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__shadow_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.1_1
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__shadow_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.1_2
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__shadow_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.1_3
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__multipart_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.2
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__shadow_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.2_1
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__shadow_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.2_2
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__shadow_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.2_3
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__multipart_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.3
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__shadow_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.3_1
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__shadow_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.3_2
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__shadow_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.3_3
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__multipart_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.4
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__shadow_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.4_1
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__shadow_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.4_2
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__shadow_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.4_3
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__multipart_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.5
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__shadow_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.5_1
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__shadow_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.5_2
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__shadow_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.5_3
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__multipart_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.6
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__shadow_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.6_1
475caa43-5052-4d27-8ffb-897db2b8a2ec.34271.1__shadow_messages-20180722.2~5-WOTuK85AHNkHUOZdTbLBQqCAzYoeW.6_2

为啥要整理成这种顺序,仔细观察下就会发现,所有和用户数据对象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中获取这些对象,并拼接

[root@ceph01 messagesobj]# for i in `cat messages-obj`;do rados -p default.rgw.buckets.data get $i $i; cat $i >> message.txt;done

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

[root@ceph01 messagesobj]# md5sum message.txt 
b4a6227030352dcc3318684789fda6e1  message.txt

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

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,504评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,434评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,089评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,378评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,472评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,506评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,519评论 3 413
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,292评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,738评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,022评论 2 329
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,194评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,873评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,536评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,162评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,413评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,075评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,080评论 2 352

推荐阅读更多精彩内容