美文网首页
rbd对象探究

rbd对象探究

作者: DaemonXiao | 来源:发表于2021-06-16 10:34 被阅读0次

    rbd对象探究

    1. rbd镜像的创建与使用

    为了更直观的感受rbd对象,本文从创建rbd池开始,构建了一个模拟的rbd使用环境,并以此探究rbd的对象。

    首先是rbd池的创建与使用:

    服务端:

    1.创建rbd池

    [root@node-1 ~]# ceph osd pool create rbd-pool 64 64 && rbd pool init rbd-pool

    2.创建块设备镜像

    [root@node-1 ~]# rbd create --size 1024 rbd-pool/rbd-pool-image-1

    3.拷贝密钥文件,或者创建新用户,这里直接拷贝admin密钥及配置

    [root@node-1 ~]# scp –r /etc/ceph 192.168.159.132:/etc/

    客户端:

    1.注意更新ceph yum源

    2.安装ceph-common

    [root@192.168.159.132 ~]# yum install ceph-common –y

    3.挂载块设备镜像

    [root@192.168.159.132 ~]# rbd map rbd-pool/rbd-pool-image-1

    4.格式化,仅第一次挂载需要,块设备名称注意更改

    [root@192.168.159.132 ~]# mkfs.xfs /rbd /dev/rbd0

    5.挂载到目录

    [root@192.168.159.132 ~]# mkdir /mnt/rbd0 && mount /dev/rbd0 /mnt/rbd0

    6.卸载

    [root@192.168.159.132 ~]# umount /mnt/rbd0 && rbd unmap rbd-pool/rbd-pool-image-1

    注意:在rbd map时可能会报错,因为内核特性不支持。

    rbd: sysfs write failed

    RBD image feature set mismatch. You can disable features unsupported by the kernel with "rbd feature disable rbd-pool/rbd-pool-image-1 object-map fast-diff deep-flatten".

    In some cases useful info is found in syslog - try "dmesg | tail".

    rbd: map failed: (6) No such device or address

    这里根据提示关闭某些特性即可。

    2. 当我们创建镜像时,创建了什么?

    [root@node-1 ~]# rados -p rbd-pool ls

    rbd_object_map.20cc292949764 # rbd特性信息

    rbd_header.20cc292949764 #image元数据

    rbd_directory # 记录该rbd池中含有的image_nameid

    rbd_info # rbd信息

    rbd_id.rbd-pool-image-1 #此镜像的id

    通过以上命令及其结果可以看出,相关含义在《Ceph设计原理与实现》一书中有详细介绍,当我们创建完镜像后,rbd-pool中多了几个对象。其含义可在src/include/rbd_types.h文档中查看。

    /* New-style rbd image 'foo' consists of objects

    • rbd_id.foo - id of image

    • rbd_header.<id> - image metadata

    • rbd_object_map.<id> - optional image object map

    • rbd_data.<id>.00000000

    • rbd_data.<id>.00000001

    • ... - data

    */

    目前rbd镜像中还没有文件,因此大部分对象是空的。通过“rados -p rbd-pool get <obj_name> <output_file_name>”命令可以导出对象。

    经过查看,发现rbd_id.rbd-pool-image-1保存了镜像的id:20cc292949764。

    rbd_info中保存了:overwrite validated。

    rbd_object_map.20cc292949764中保存了:

    {

    "size": 256,

    "bit_table": [

    "0x00",

    "0x00",

    }//用于支持 object-map特性,具体作用在实践中遇到再来补充。

    这里给出查看rbd_object_map命令: ceph-dencoder import ./rbd_object_map.20cc292949764 type BitVector<2> decode dump_json。

    3. 向rbd写入一个文件后,实际写入的是什么?

    在mkfs块设备后,我们查看下rbd-pool中的对象。

    [root@node-1 data]# rados -p rbd-pool ls

    rbd_data.20e5ff0224ec0.00000000000000e0 #image对象信息

    rbd_directory #rbd管理image对象信息

    rbd_header.20e5ff0224ec0 #image元数据

    rbd_data.20e5ff0224ec0.0000000000000060 #

    rbd_info #rbd信息

    rbd_data.20e5ff0224ec0.0000000000000001

    rbd_data.20e5ff0224ec0.00000000000000ff

    rbd_data.20e5ff0224ec0.0000000000000080

    rbd_id.rbd-pool-image-1 #记录image_nameimage_id的映射关系

    rbd_data.20e5ff0224ec0.00000000000000c0

    rbd_data.20e5ff0224ec0.0000000000000082

    rbd_data.20e5ff0224ec0.0000000000000020

    rbd_data.20e5ff0224ec0.0000000000000040

    rbd_data.20e5ff0224ec0.0000000000000081

    rbd_data.20e5ff0224ec0.0000000000000000

    rbd_data.20e5ff0224ec0.00000000000000a0

    发现增加了12个rbd_data对象。rbd被xfs格式化以后会产生一些对象,这些对象是以16进制名称的方式存储在后台的,也就是rbd大小一定的情况下对象数目是一定的,也就是名称也是一定的。在后续的向文件中写入操作的过程中,还会发现,对象依然是从rbd_data.*****00的对象开始写入。这个实际和客户端格式化的文件系统有关。在《从ceph对象中提取rbd中的指定文件》一文中可以得知:rbd存储对象和文件系统的sectors是一一对应的。

    客户端查看分区设备信息:

    [root@localhost ~]# parted -s /dev/rbd0 unit s print

    Model: 未知 (unknown)

    Disk /dev/rbd0: 2097152s

    Sector size (logical/physical): 512B/512B

    Partition Table: loop

    Disk Flags:

    Number Start End Size File system 标志

    • 1 0s 2097151s 2097152s xfs*

    上面结果中“Start”对应的“0s”表示该分区设备从第0块sector开始写入,每块sector大小512B,共有2097152s 块。

    服务端查看镜像信息:

    [root@node-1 ~]# rbd info rbd-pool/rbd-pool-image-1

    rbd image 'rbd-pool-image-1':

    size 1 GiB in 256 objects #大小1GB,平均分配给256个对象

    order 22 (4 MiB objects) # 每个对象大小4MB

    snapshot_count: 0

    id: 20e5ff0224ec0

    block_name_prefix: rbd_data.20e5ff0224ec0

    format: 2 # image 1 基本上不用

    features: layering, exclusive-lock

    op_features: # image支持的特性

    flags:

    create_timestamp: Wed May 26 16:42:36 2021

    access_timestamp: Wed May 26 16:42:36 2021

    modify_timestamp: Wed May 26 16:42:36 2021

    上述结果可知镜像对应的块设备大小1GB,平均分配到256个对象,每个4MB。

    简单计算可以得出:sector数量 * 单个sector大小 = 镜像大小

    2097152 * 512 / 1024 / 1024 = 1024 MB = 1GB。

    因此2097152个sector和image中的256个对象存在对应关系。已知sector从0块开始写入,那么obj应该也从0开始增长,写满4MB后,换到新的obj。

    我在这里使用dd命令在客户端写入一个4MB对象,然后再去查看pool中对象信息。

    这里我们在客户端上挂载镜像后,向该目录中写入一个无意义对象。

    [root@localhost mnt]# dd if=/dev/zero of=/mnt/rbd0/file1 count=1 bs=4MB

    然后,观察rbd-pool对象情况。

    [root@node-1 ~]# rados -p rbd-pool ls

    rbd_data.20e5ff0224ec0.00000000000000e0

    rbd_directory

    rbd_header.20e5ff0224ec0

    rbd_data.20e5ff0224ec0.0000000000000060

    rbd_info

    rbd_data.20e5ff0224ec0.0000000000000001

    rbd_data.20e5ff0224ec0.00000000000000ff

    rbd_data.20e5ff0224ec0.0000000000000080

    rbd_id.rbd-pool-image-1

    rbd_data.20e5ff0224ec0.00000000000000c0

    rbd_data.20e5ff0224ec0.0000000000000082

    rbd_data.20e5ff0224ec0.0000000000000020

    rbd_data.20e5ff0224ec0.0000000000000040

    rbd_data.20e5ff0224ec0.0000000000000081

    rbd_data.20e5ff0224ec0.0000000000000000

    rbd_data.20e5ff0224ec0.00000000000000a0

    似乎没有变化,但其实rbd_data.******00对象的大小增加了,先按下不表,我们看下此时rbd_data.******00对象的大小。

    [root@node-1 ~]# rados -p rbd-pool stat rbd_data.20e5ff0224ec0.0000000000000000

    rbd-pool/rbd_data.20e5ff0224ec0.0000000000000000 mtime 2021-05-26 18:22:26.000000, size 4034560

    经查询,rbd_data.******00对象大小为4034560B。

    我们再向客户端挂载的文件目录中写入一个有意义的小对象。

    [root@localhost rbd0]# vi hellorbd

    hello rbd

    然后,查看hellorbd文件在块设备中的位置,顺便也可以看下file1的位置。

    [root@localhost rbd0]# xfs_bmap -lvp /mnt/rbd0/hellorbd

    /mnt/rbd0/hellorbd:

    • EXT: FILE-OFFSET BLOCK-RANGE AG AG-OFFSET TOTAL FLAGS*

    0: [0..7]: 7880..7887 0 (7880..7887) 8 01111

    [root@localhost rbd0]# xfs_bmap -lvp /mnt/rbd0/file1

    /mnt/rbd0/file1:

    • EXT: FILE-OFFSET BLOCK-RANGE AG AG-OFFSET TOTAL FLAGS*

    0: [0..7815]: 64..7879 0 (64..7879) 7816 01111

    可以看出hellorbd在sector中分布在[7880~7887],file1为[64~7879]。hellorbd紧跟着file1,并且file1并非从0开始,而是从64开始,说明前面的sector已经被使用,这段64个sector(即 64 * 512 B)长度空间在格式化文件系统的时候已经被占用了。还有一点值得吐槽的是:dd命令中的4MB,实际写入大小只有4000000B。

    根据hellorbd的位置信息,可以计算出它存储在在rbd-pool/rbd-pool-image-1中的对象的具体位置。

    计算方法:

    1.计算出hellorbd到rbd-pool对象的映射

    sectors数量 / 对象数量 = 单个对象的sectors范围

    2097152/256 = 8192

    根据 hellorbd:[7880~7887],可以得出hellorbd在第0个对象中:rbd_data.******00。

    2.计算出hellorbd在rbd_data对象中偏移量

    (7880 - (0 * 8192))* 512B = 4030560

    4034560!还记得我们上文中在写入file1之后,查看过rbd_data.******00对象的大小吗?就是4034560。

    接下来使用rados命令和dd命令在服务端还原出rbdhello。

    [root@node-1 ~]# rados -p rbd-pool get rbd_data.20e5ff0224ec0.0000000000000000 ./rbd_data.20e5ff0224ec0.0000000000000000

    [root@node-1 ~]# dd if=rbd_data.20e5ff0224ec0.0000000000000000 of=hellorbd bs=512 count=8 skip=7880

    • [root@node-1 ~]# cat hellorbd*

    hello rbd

    或者,

    [root@node-1 ~]# dd if=rbd_data.20e5ff0224ec0.0000000000000000 of=hellorbd-1 bs=1 count=4096 skip=4034560

    [root@node-1 ~]# cat hellorbd-1

    hello rbd

    可以得出,块设备在rbd中被切割成一个个对象,保存在rbd_data对象中,这样使得rbd管理起块设备的数据极为方便,而且也达到到了瘦分配的特性。rbd_data中还保存着客户端中这个设备的信息(文件系统,大小等),这个客户端在挂载时,可以直接把image映射为一个块设备,其所有读写操作的本质都是rbd_data。

    相关文章

      网友评论

          本文标题:rbd对象探究

          本文链接:https://www.haomeiwen.com/subject/fvexyltx.html