Ceph RBD:克隆 + 克隆卷元数据/数据IO详解

文章目录

  • 引言
    • 克隆概述
    • 本文结论
  • 克隆的元数据结构
    • 创建卷vol_0
    • 创建快照vol_0_snap_0
    • 创建克隆卷vol_0_snap_0_clone_0
    • 克隆卷元数据
      • 克隆卷的元数据有哪些?
      • 如何找到clone卷对应的原卷?
      • 如何找到clone卷对应的快照?
      • 如何通过原卷找到clone卷?
      • 主要元数据总结
  • 创建clone卷流程
  • 克隆卷数据
    • 创建卷vol_1,写入8M数据
    • 创建快照vol_1_snap_0
    • 创建克隆卷vol_1_snap_0_clone_0
      • 读克隆卷0-1M位置
      • 写克隆卷4M-5M位置
      • 读写数据总结
  • 扁平化
    • 创建卷vol_2,写入8M数据
    • 创建快照vol_2_snap_0
    • 创建克隆卷vol_2_snap_0_clone_0
    • 执行扁平化
      • 扁平化后数据
      • 扁平化后原数据
      • 扁平化总结

引言

阅读本文前建议先阅读如下文章,了解卷和快照的概念,及其元数据和数据的存储方式。

  • Ceph RBD:创建image + image元数据详解
  • Ceph RBD:快照 + Bluestore/Filestore快照区别

克隆概述

快照是保存某个时间点的原卷的数据,但快照是只读的,如果想在此快照的基础上继续存储数据,就需要创建克隆卷。克隆的主要操作有两个:

  • 克隆(rbd clone):在快照的基础上,创建克隆卷,此过程只创建卷,不进行数据操作。
  • 扁平化(rbd flatten):将clone卷未写过的位置,从快照卷中拷贝到clone卷,拷贝完成后解除与快照卷和原卷的关系,扁平化后的clone卷,可以独立使用。

本文结论

下面先列出克隆相关的关键点,后文会通过实践一步一步讲解。

  • 元数据
    • header:克隆卷header中记录parent,通过parent可以解析出克隆卷对应的原卷和快照。
    • rbd_children:记录了原卷和克隆卷的对应关系,通过此可以通过原卷对应的所有克隆卷。
  • 数据
    • 读:读克隆卷时不会将快照数据拷贝到克隆卷中。
    • 写:写克隆卷时数据会写入克隆卷。
    • 读写克隆卷对原卷和快照卷的数据没有任何影响。
  • 扁平化
    • 元数据:扁平化后,header中的parent和rbd-children中相关信息被清除。
    • 数据:扁平化过程中,会将快照卷的数据拷贝到克隆卷中。

克隆的元数据结构

创建卷vol_0

观察元数据为:

[root@VM-16-10-centos ~]# rados -p blockpool ls
rbd_directory
rbd_header.b5f02487a541c
rbd_info
rbd_object_map.b5f02487a541c
rbd_id.vol_0
[root@VM-16-10-centos ~]# rados -p blockpool listomapvals rbd_header.b5f02487a541c
access_timestamp
value (8 bytes) :
00000000  7d 01 60 62 16 0e 21 09                           |}.`b..!.|
00000008

create_timestamp
value (8 bytes) :
00000000  7d 01 60 62 16 0e 21 09                           |}.`b..!.|
00000008

features
value (8 bytes) :
00000000  3d 00 00 00 00 00 00 00                           |=.......|
00000008

modify_timestamp
value (8 bytes) :
00000000  7d 01 60 62 16 0e 21 09                           |}.`b..!.|
00000008

object_prefix
value (26 bytes) :
00000000  16 00 00 00 72 62 64 5f  64 61 74 61 2e 62 35 66  |....rbd_data.b5f|
00000010  30 32 34 38 37 61 35 34  31 63                    |02487a541c|
0000001a

order
value (1 bytes) :
00000000  16                                                |.|
00000001

size
value (8 bytes) :
00000000  00 00 40 06 00 00 00 00                           |..@.....|
00000008

snap_seq
value (8 bytes) :
00000000  00 00 00 00 00 00 00 00                           |........|
00000008

创建快照vol_0_snap_0

观察元数据,可以看到产生了快照卷,snap_seq也变化了。

[root@VM-16-10-centos ~]# rados -p blockpool ls
rbd_directory
rbd_object_map.b5f02487a541c.000000000000000a
rbd_header.b5f02487a541c
rbd_info
rbd_object_map.b5f02487a541c
rbd_id.vol_0
[root@VM-16-10-centos ~]# rados -p blockpool listomapvals rbd_header.b5f02487a541c
access_timestamp
value (8 bytes) :
00000000  7d 01 60 62 16 0e 21 09                           |}.`b..!.|
00000008

create_timestamp
value (8 bytes) :
00000000  7d 01 60 62 16 0e 21 09                           |}.`b..!.|
00000008

features
value (8 bytes) :
00000000  3d 00 00 00 00 00 00 00                           |=.......|
00000008

modify_timestamp
value (8 bytes) :
00000000  7d 01 60 62 16 0e 21 09                           |}.`b..!.|
00000008

object_prefix
value (26 bytes) :
00000000  16 00 00 00 72 62 64 5f  64 61 74 61 2e 62 35 66  |....rbd_data.b5f|
00000010  30 32 34 38 37 61 35 34  31 63                    |02487a541c|
0000001a

order
value (1 bytes) :
00000000  16                                                |.|
00000001

size
value (8 bytes) :
00000000  00 00 40 06 00 00 00 00                           |..@.....|
00000008

snap_seq
value (8 bytes) :
00000000  0a 00 00 00 00 00 00 00                           |........|
00000008

snapshot_000000000000000a
value (70 bytes) :
00000000  08 08 40 00 00 00 0a 00  00 00 00 00 00 00 0c 00  |..@.............|
00000010  00 00 76 6f 6c 5f 30 5f  73 6e 61 70 5f 30 00 00  |..vol_0_snap_0..|
00000020  40 06 00 00 00 00 00 00  00 00 00 00 00 00 00 01  |@...............|
00000030  01 04 00 00 00 00 00 00  00 90 02 60 62 d9 54 5e  |...........`b.T^|
00000040  00 00 00 00 00 00                                 |......|
00000046

创建克隆卷vol_0_snap_0_clone_0

查看rados对象信息,发现多了克隆卷的rados对象和一个叫rbd_children的对象。

[root@VM-16-10-centos ~]# rados -p blockpool ls
rbd_object_map.b613fe7f7d1c5
rbd_directory
rbd_children
rbd_object_map.b5f02487a541c.000000000000000a
rbd_header.b5f02487a541c
rbd_info
rbd_id.vol_0_snap_0_clone_0
rbd_header.b613fe7f7d1c5
rbd_object_map.b5f02487a541c
rbd_id.vol_0

克隆卷元数据

克隆卷的元数据有哪些?

1、与普通卷相同,通过rbd_directory找到克隆卷id。

[root@VM-16-10-centos ~]# rados -p blockpool listomapvals rbd_directory
id_b5f02487a541c
value (9 bytes) :
00000000  05 00 00 00 76 6f 6c 5f  30                       |....vol_0|
00000009

id_b613fe7f7d1c5
value (24 bytes) :
00000000  14 00 00 00 76 6f 6c 5f  30 5f 73 6e 61 70 5f 30  |....vol_0_snap_0|
00000010  5f 63 6c 6f 6e 65 5f 30                           |_clone_0|
00000018

name_vol_0
value (17 bytes) :
00000000  0d 00 00 00 62 35 66 30  32 34 38 37 61 35 34 31  |....b5f02487a541|
00000010  63                                                |c|
00000011

name_vol_0_snap_0_clone_0
value (17 bytes) :
00000000  0d 00 00 00 62 36 31 33  66 65 37 66 37 64 31 63  |....b613fe7f7d1c|
00000010  35                                                |5|
00000011

2、进而可以读取克隆卷的header,与普通卷相比,克隆卷有一个parent原数据。

[root@VM-16-10-centos ~]# rados -p blockpool listomapvals rbd_header.b613fe7f7d1c5
access_timestamp
value (8 bytes) :
00000000  54 03 60 62 14 ff 62 29                           |T.`b..b)|
00000008

create_timestamp
value (8 bytes) :
00000000  54 03 60 62 14 ff 62 29                           |T.`b..b)|
00000008

features
value (8 bytes) :
00000000  3d 00 00 00 00 00 00 00                           |=.......|
00000008

modify_timestamp
value (8 bytes) :
00000000  54 03 60 62 14 ff 62 29                           |T.`b..b)|
00000008

object_prefix
value (26 bytes) :
00000000  16 00 00 00 72 62 64 5f  64 61 74 61 2e 62 36 31  |....rbd_data.b61|
00000010  33 66 65 37 66 37 64 31  63 35                    |3fe7f7d1c5|
0000001a

order
value (1 bytes) :
00000000  16                                                |.|
00000001

parent
value (52 bytes) :
00000000  02 02 2e 00 00 00 01 00  00 00 00 00 00 00 00 00  |................|
00000010  00 00 0d 00 00 00 62 35  66 30 32 34 38 37 61 35  |......b5f02487a5|
00000020  34 31 63 0a 00 00 00 00  00 00 00 01 00 00 40 06  |41c...........@.|
00000030  00 00 00 00                                       |....|
00000034

size
value (8 bytes) :
00000000  00 00 40 06 00 00 00 00                           |..@.....|
00000008

snap_seq
value (8 bytes) :
00000000  00 00 00 00 00 00 00 00                           |........|
00000008

如何找到clone卷对应的原卷?

在克隆卷的header中有parent,为其原卷的id。

如何找到clone卷对应的快照?

1、可以导出header信息中的parent。

[root@VM-16-10-centos ~]# rados -p blockpool getomapval rbd_header.b613fe7f7d1c5 parent file_parent
Writing to file_parent

2、解码parent信息,得到快照卷,如下表示愿卷的id为b5f02487a541c,即vol_0。对应的快照为snap_id = 10,根据原卷的header又可以知道snap_id=10为快照vol_0_snap_0。

[root@VM-16-10-centos ~]# ceph-dencoder type cls_rbd_parent import file_parent decode dump_json
{
    "pool_id": 1,
    "pool_namespace": "",
    "image_id": "b5f02487a541c",
    "snap_id": 10,
    "head_overlap": 104857600
}

如何通过原卷找到clone卷?

通过查看rbd_children中的信息,就可以找到clone卷。

[root@VM-16-10-centos ~]# rados -p blockpool listomapvals rbd_children
key (33 bytes):
00000000  01 00 00 00 00 00 00 00  0d 00 00 00 62 35 66 30  |............b5f0|
00000010  32 34 38 37 61 35 34 31  63 0a 00 00 00 00 00 00  |2487a541c.......|
00000020  00                                                |.|
00000021

value (21 bytes) :
00000000  01 00 00 00 0d 00 00 00  62 36 31 33 66 65 37 66  |........b613fe7f|
00000010  37 64 31 63 35                                    |7d1c5|
00000015

主要元数据总结

  • rbd_children:用于从原卷找到克隆卷。
  • 克隆卷中header中parent:保存克隆卷到原卷和快照卷的关系。

创建clone卷流程

根据前面介绍的元数据可以直接参考代码中的注释了。

  /**
   * @verbatim
   *
   * <start>
   *    |
   *    v
   * OPEN PARENT
   *    |
   *    v
   * VALIDATE CHILD                    <finish>
   *    |                                 ^
   *    v                                 |
   * CREATE CHILD * * * * * * * * * > CLOSE PARENT
   *    |                                 ^
   *    v                                 |
   * OPEN CHILD * * * * * * * * * * > REMOVE CHILD
   *    |                                 ^
   *    v                                 |
   * ATTACH PARENT  * * * * * * * * > CLOSE CHILD
   *    |                               ^
   *    v                               *
   * ATTACH CHILD * * * * * * * * * * * *
   *    |                               *
   *    v                               *
   * GET PARENT META  * * * * * * * * * ^
   *    |                               *
   *    v (skip if not needed)          *
   * SET CHILD META * * * * * * * * * * ^
   *    |                               *
   *    v (skip if not needed)          *
   * GET MIRROR MODE  * * * * * * * * * ^
   *    |                               *
   *    v (skip if not needed)          *
   * SET MIRROR ENABLED * * * * * * * * *
   *    |
   *    v
   * CLOSE CHILD
   *    |
   *    v
   * CLOSE PARENT
   *    |
   *    v
   * <finish>
   *
   * @endverbatim
   */

克隆卷数据

创建卷vol_1,写入8M数据

查看rados对象。

[root@VM-16-10-centos ~]# rados -p blockpool ls
rbd_directory
rbd_id.vol_1
rbd_info
rbd_data.b6916687f5078.0000000000000001
rbd_header.b6916687f5078
rbd_data.b6916687f5078.0000000000000000
rbd_object_map.b6916687f5078

创建快照vol_1_snap_0

查看rados对象。由于snap未写入数据,因此查看数据对象无snap数据。

[root@VM-16-10-centos ~]# rados -p blockpool ls
rbd_directory
rbd_id.vol_1
rbd_info
rbd_data.b6916687f5078.0000000000000001
rbd_header.b6916687f5078
rbd_data.b6916687f5078.0000000000000000
rbd_object_map.b6916687f5078
rbd_object_map.b6916687f5078.000000000000000c
[root@VM-16-10-centos ~]# rados -p blockpool listsnaps rbd_data.b6916687f5078.0000000000000000
rbd_data.b6916687f5078.0000000000000000:
cloneid snaps   size    overlap
head    -       4194304
[root@VM-16-10-centos ~]# rados -p blockpool listsnaps rbd_data.b6916687f5078.0000000000000001
rbd_data.b6916687f5078.0000000000000001:
cloneid snaps   size    overlap
head    -       4194304

创建克隆卷vol_1_snap_0_clone_0

查看rados对象,发现除了新增卷,未产生任何数据。

[root@VM-16-10-centos ~]# rados -p blockpool ls
rbd_directory
rbd_id.vol_1
rbd_children
rbd_info
rbd_header.b6c7f3d38e16f
rbd_data.b6916687f5078.0000000000000001
rbd_header.b6916687f5078
rbd_id.vol_1_snap_0_clone_0
rbd_data.b6916687f5078.0000000000000000
rbd_object_map.b6916687f5078
rbd_object_map.b6916687f5078.000000000000000c
rbd_object_map.b6c7f3d38e16f
[root@VM-16-10-centos ~]# rados -p blockpool listsnaps rbd_data.b6916687f5078.0000000000000000
rbd_data.b6916687f5078.0000000000000000:
cloneid snaps   size    overlap
head    -       4194304
[root@VM-16-10-centos ~]# rados -p blockpool listsnaps rbd_data.b6916687f5078.0000000000000001
rbd_data.b6916687f5078.0000000000000001:
cloneid snaps   size    overlap
head    -       4194304

读克隆卷0-1M位置

1、查看rados对象。快照数据没有改变。

[root@VM-16-10-centos ~]# rados -p blockpool ls
rbd_directory
rbd_id.vol_1
rbd_children
rbd_info
rbd_header.b6c7f3d38e16f
rbd_data.b6916687f5078.0000000000000001
rbd_header.b6916687f5078
rbd_id.vol_1_snap_0_clone_0
rbd_data.b6916687f5078.0000000000000000
rbd_object_map.b6916687f5078
rbd_object_map.b6916687f5078.000000000000000c
rbd_data.b6c7f3d38e16f.0000000000000000
rbd_object_map.b6c7f3d38e16f

2、查看快照数据,无快照数据产生。

[root@VM-16-10-centos ~]# rados -p blockpool listsnaps rbd_data.b6c7f3d38e16f.0000000000000000
rbd_data.b6c7f3d38e16f.0000000000000000:
cloneid snaps   size    overlap
head    -       4194304
[root@VM-16-10-centos ~]# rados -p blockpool listsnaps rbd_data.b6916687f5078.0000000000000000
rbd_data.b6916687f5078.0000000000000000:
cloneid snaps   size    overlap
head    -       4194304

写克隆卷4M-5M位置

1、查看rados对象,可以发现又多了一个对象,说明写会在克隆卷产生数据,同时观察原卷的数据,没有影响。

[root@VM-16-10-centos ~]# rados -p blockpool ls
rbd_directory
rbd_id.vol_1
rbd_children
rbd_info
rbd_header.b6c7f3d38e16f
rbd_data.b6916687f5078.0000000000000001
rbd_header.b6916687f5078
rbd_id.vol_1_snap_0_clone_0
rbd_data.b6916687f5078.0000000000000000
rbd_object_map.b6916687f5078
rbd_data.b6c7f3d38e16f.0000000000000001
rbd_object_map.b6916687f5078.000000000000000c
rbd_data.b6c7f3d38e16f.0000000000000000
rbd_object_map.b6c7f3d38e16f

2、查看原卷数据,无快照数据产生。

[root@VM-16-10-centos ~]# rados -p blockpool listsnaps rbd_data.b6916687f5078.0000000000000001
rbd_data.b6916687f5078.0000000000000001:
cloneid snaps   size    overlap
head    -       4194304
[root@VM-16-10-centos ~]# rados -p blockpool listsnaps rbd_data.b6c7f3d38e16f.0000000000000001
rbd_data.b6c7f3d38e16f.0000000000000001:
cloneid snaps   size    overlap
head    -       4194304

读写数据总结

  • 读克隆卷时会将快照数据拷贝到克隆卷中。
  • 写克隆卷时数据会写入克隆卷。
  • 读写克隆卷对原卷和快照卷的数据没有任何影响。

扁平化

创建卷vol_2,写入8M数据

[root@VM-16-10-centos ~]# rados -p blockpool ls
rbd_directory
rbd_id.vol_2
rbd_data.b7114d8a69a3d.0000000000000000
rbd_info
rbd_header.b7114d8a69a3d
rbd_data.b7114d8a69a3d.0000000000000001
rbd_object_map.b7114d8a69a3d

创建快照vol_2_snap_0

[root@VM-16-10-centos ~]# rados -p blockpool ls
rbd_object_map.b7114d8a69a3d.0000000000000010
rbd_directory
rbd_id.vol_2
rbd_data.b7114d8a69a3d.0000000000000000
rbd_info
rbd_header.b7114d8a69a3d
rbd_data.b7114d8a69a3d.0000000000000001
rbd_object_map.b7114d8a69a3d

创建克隆卷vol_2_snap_0_clone_0

1、增加了原数据卷vol_2_snap_0_clone_0相关rados对象。

[root@VM-16-10-centos ~]# rados -p blockpool ls
rbd_object_map.b7114d8a69a3d.0000000000000010
rbd_directory
rbd_object_map.b7285744baa89
rbd_header.b7285744baa89
rbd_id.vol_2
rbd_data.b7114d8a69a3d.0000000000000000
rbd_children
rbd_info
rbd_header.b7114d8a69a3d
rbd_id.vol_2_snap_0_clone_0
rbd_data.b7114d8a69a3d.0000000000000001
rbd_object_map.b7114d8a69a3d

2、查看克隆卷header,发现有parent。

[root@VM-16-10-centos ~]# rados -p blockpool listomapvals rbd_header.b7285744baa89
access_timestamp
value (8 bytes) :
00000000  75 12 60 62 2e 63 33 24                           |u.`b.c3$|
00000008

create_timestamp
value (8 bytes) :
00000000  75 12 60 62 2e 63 33 24                           |u.`b.c3$|
00000008

features
value (8 bytes) :
00000000  3d 00 00 00 00 00 00 00                           |=.......|
00000008

modify_timestamp
value (8 bytes) :
00000000  75 12 60 62 2e 63 33 24                           |u.`b.c3$|
00000008

object_prefix
value (26 bytes) :
00000000  16 00 00 00 72 62 64 5f  64 61 74 61 2e 62 37 32  |....rbd_data.b72|
00000010  38 35 37 34 34 62 61 61  38 39                    |85744baa89|
0000001a

order
value (1 bytes) :
00000000  16                                                |.|
00000001

parent
value (52 bytes) :
00000000  02 02 2e 00 00 00 01 00  00 00 00 00 00 00 00 00  |................|
00000010  00 00 0d 00 00 00 62 37  31 31 34 64 38 61 36 39  |......b7114d8a69|
00000020  61 33 64 10 00 00 00 00  00 00 00 01 00 00 40 06  |a3d...........@.|
00000030  00 00 00 00                                       |....|
00000034

size
value (8 bytes) :
00000000  00 00 40 06 00 00 00 00                           |..@.....|
00000008

snap_seq
value (8 bytes) :
00000000  00 00 00 00 00 00 00 00                           |........|
00000008

3、查看rbd_child,可以看到原卷和克隆卷的父子关系。

[root@VM-16-10-centos ~]# rados -p blockpool listomapvals rbd_children
key (33 bytes):
00000000  01 00 00 00 00 00 00 00  0d 00 00 00 62 37 31 31  |............b711|
00000010  34 64 38 61 36 39 61 33  64 10 00 00 00 00 00 00  |4d8a69a3d.......|
00000020  00                                                |.|
00000021

value (21 bytes) :
00000000  01 00 00 00 0d 00 00 00  62 37 32 38 35 37 34 34  |........b7285744|
00000010  62 61 61 38 39                                    |baa89|
00000015

执行扁平化

扁平化后数据

1、执行扁平化后,发现克隆卷中有8M的数据。说明扁平化过程,会将快照数据拷贝到克隆卷中。

[root@VM-16-10-centos ~]# rados -p blockpool ls
rbd_data.b7285744baa89.0000000000000001
rbd_object_map.b7114d8a69a3d.0000000000000010
rbd_data.b7285744baa89.0000000000000000
rbd_directory
rbd_object_map.b7285744baa89
rbd_header.b7285744baa89
rbd_id.vol_2
rbd_data.b7114d8a69a3d.0000000000000000
rbd_children
rbd_info
rbd_header.b7114d8a69a3d
rbd_id.vol_2_snap_0_clone_0
rbd_data.b7114d8a69a3d.0000000000000001
rbd_object_map.b7114d8a69a3d

扁平化后原数据

1、查看克隆卷的header,发现已经没有了parent。

[root@VM-16-10-centos ~]# rados -p blockpool listomapvals rbd_header.b7285744baa89
access_timestamp
value (8 bytes) :
00000000  75 12 60 62 2e 63 33 24                           |u.`b.c3$|
00000008

create_timestamp
value (8 bytes) :
00000000  75 12 60 62 2e 63 33 24                           |u.`b.c3$|
00000008

features
value (8 bytes) :
00000000  3d 00 00 00 00 00 00 00                           |=.......|
00000008

modify_timestamp
value (8 bytes) :
00000000  75 12 60 62 2e 63 33 24                           |u.`b.c3$|
00000008

object_prefix
value (26 bytes) :
00000000  16 00 00 00 72 62 64 5f  64 61 74 61 2e 62 37 32  |....rbd_data.b72|
00000010  38 35 37 34 34 62 61 61  38 39                    |85744baa89|
0000001a

order
value (1 bytes) :
00000000  16                                                |.|
00000001

size
value (8 bytes) :
00000000  00 00 40 06 00 00 00 00                           |..@.....|
00000008

snap_seq
value (8 bytes) :
00000000  00 00 00 00 00 00 00 00                           |........|
00000008

2、查看rbd_children,发现已经没有了原卷和克隆卷的父子关系。

[root@VM-16-10-centos ~]# rados -p blockpool listomapvals rbd_children

扁平化总结

  • 元数据:扁平化后,header中的parent和rbd-children中相关信息被清除。
  • 数据:扁平化过程中,会将快照卷的数据拷贝到克隆卷中。

你可能感兴趣的:(Ceph,RBD,分布式,云计算,linux)