前言

我们知道,FileStore是目前Ceph版本的默认存储方式(后续社区准备采用BlueStore)。

RDB是我们虚拟机使用Ceph的常用方式,Ceph是一个基于对象存储的分布式文件系统,在Ceph中,所有的文件都是对象,本文探讨在Ceph中的RDB在Ceph的实现原理和映射方式。

了解RBD的映射原理以后,对我们运维管理,数据恢复会有很大的帮助。

操作过程

1.创建pool

1. [root@centos7 ceph]# ceph osd pool create test 64 64
2. pool 'test' created
3. [root@centos7 ceph]# rados ls -p test
4. none

创建好test pool后,通过rados查看pool中的对象,因为没有存储任何东西,所以没发现对象。

2.创建image

1. [root@centos7 ceph]# rbd create test/test --size 1024
2. [root@centos7 ceph]# rados ls -p test
3. rbd_directory
4. test.rbd

在test pool中,创建了rbd的test image,此时通过rados查看,发现了两个对象:rbd_directory和test.rbd。

3.Object2PG

在Ceph中,每一个对象(Object)都会首先映射到一个pg上,然后pg再映射到一组osd上。

1. [root@centos7 ceph]# ceph osd map test rbd_directory
2. osdmap e163 pool 'test' (5) object 'rbd_directory' -> pg 5.30a98c1c (5.
1c) -> up [2,3] acting [2,3]

通过ceph osd map [pool] [object_name] 直接可以查看到object到pg的映射关系,本例中rbd_directory 映射到了pg=5.1c.前面的5是pool_id,30a98c1c这串数值其实就是通过Ceph的Hash函数将rbd_directory映射的结果,我们把他成为object_id,因为本例的pool中pg_num=64,映射过来的pg_id=0x30a98c1c%64=0x1c, 从上面可以看出,Ceph的object_id到pg的映射就是简单的取模处理。一旦Ceph的pg数据发生变化,pg的映射也会发生变化,从原理上来看,当一个Ceph的生产集群,最好不要调整pg数。

4.PG2OSD

每个pg都会通过Crush算法,映射到一组osd上,Crush算法是Ceph数据高可用性的保障。

Crush算法其实一个能够根据服务器部署情况而产生不同映射结果的一致性哈希算法。

1. [root@centos7 ceph]# ceph osd tree
2. # id weight type name up/down reweight
3. -1 4 root default
4. -3 4 rack rack01
5. -2 4 host node01
6. 0 1 osd.0 up 1
7. 1 1 osd.1 up 1
8. 2 1 osd.2 up 1
9. 3 1 osd.3 up 1
10.
11. [root@centos7 ceph]# ceph pg map 5.1c
12. osdmap e163 pg 5.1c (5.1c) -> up [2,3] acting [2,3]

本例中有4个osd, 通过ceph pg map 可以找到对应的object映射到了那个osd,本例中映射到了2和3,2是主osd(本例配置的副本数为2)。

5.文件落地

1. [root@centos7 ceph]# cd osd/ceph-2/current/
2. [root@centos7 ceph]# cd 5.1c_head/
3. [root@centos7 5.1c_head]# ls
4. rbd\udirectory__head_30A98C1C__5
5. [root@centos7 5.1c_head]# hexdump -C rbd\\udirectory__head_30A98C1C__5
6. 00000000 00 00 00 00 01 00 00 00 04 00 00 00 74 65 73 74 |............test|
7. 00000010 00 00 00 00 |....|
8. 00000014

从上面寻找的过程中,通过osd的目录,进入到pg所在的目录,因为一个osd会承载多个pg,同时一个pg会映射到至少一个以上的osd上。本例中顺藤摸瓜,进入osd/ceph-2/current,由于pg是5.1c,进入5.1c的目录,找到了文件rbd\udirectory__head_30A98C1C__5,命名规则也很简单{object_name}head{object_id}_{pool_Id},通过hexdump发现,里面存储了test,猜想他应该是保存了image的名字。再查看另外一个文件test.rbd,如下,通过hexdump查看,发现里面存储了一些RBD的描述信息。

1. [root@centos7 osd]# ceph osd map test test.rbd
2. osdmap e163 pool 'test' (5) object 'test.rbd' -> pg 5.a2fa4514 (5.14) -
> up [3,1] acting [3,1]
3. [root@centos7 osd]# cd ceph-3/current/5.14_head/
4. [root@centos7 5.14_head]# ls
5. test.rbd__head_A2FA4514__5
6. [root@centos7 5.14_head]# hexdump -C test.rbd__head_A2FA4514__5
7. 00000000 3c 3c 3c 20 52 61 64 6f 73 20 42 6c 6f 63 6b 20 |<<< Rados
Block |
8. 00000010 44 65 76 69 63 65 20 49 6d 61 67 65 20 3e 3e 3e |Device Ima
ge >>>|
9. 00000020 0a 00 00 00 00 00 00 00 72 62 2e 30 2e 31 36 64 |........rb
.0.16d|
10. 00000030 30 2e 36 62 38 62 34 35 36 37 00 00 00 00 00 00 |0.6b8b4567......|
11. 00000040 52 42 44 00 30 30 31 2e 30 30 35 00 16 00 00 00 |RBD.001.00
5.....|
12. 00000050 00 00 00 40 00 00 00 00 00 00 00 00 00 00 00 00 |...@......

......|
13. 00000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |..........
......|
14. 00000070|

通过rbd info 查看rbd的信息,发现果然有几分似曾相识,比如rb.0.16d0.6b8b4567,从这里我们可以发现,rbd info 其实就是读取了test.rbd中的数据,也就是说rbd的描述信息存放在test.rbd中。

1. [root@centos7 5.14_head]# rbd info test/test
2. rbd image'test':
3. size 1024 MB in 256 objects4. order 22 (4096 kB objects)
5. block_name_prefix: rb.0.16d0.6b8b4567
6. format: 1

6.RBD文件组织

6.1map到dev

1. [root@centos7 osd]# rbd map test/test
2. [root@centos7 osd]# rbd showmapped
3. id pool image snap device
4. 0 test test - /dev/rbd0

6.2格式化文件系统

1. [root@centos7 osd]# mkfs.ext4 /dev/rbd0
2. mke2fs 1.42.9 (28-Dec-2013)
3. Discardingdevice blocks: done
4. Filesystemlabel=
5. OS type: Linux
6. Block size=4096 (log=2)
7. Fragmentsize=4096 (log=2)
8. Stride=1024 blocks, Stripe width=1024 blocks
9. 65536 inodes, 262144 blocks
10. 13107 blocks (5.00%) reserved for the super user
11. First data block=0
12. Maximum filesystem blocks=268435456
13. 8 block groups
14. 32768 blocks per group, 32768 fragments per group
15. 8192 inodes per group
16. Superblockbackups stored on blocks:
17. 32768, 98304, 163840, 229376
18.
19. Allocatinggroup tables: done
20. Writinginode tables: done
21. Creatingjournal (8192 blocks): done
22. Writing superblocks and filesystem accounting information: done

6.3挂载文件系统

1. [root@centos7 osd]# mount /dev/rbd0 /mnt

6.4创建文件(128M)

1. [root@centos7 osd]# cd /mnt/
2. [root@centos7 mnt]# dd if=/dev/zero of=./data bs=1M count=128
3. 128+0 records in
4. 128+0 records out
5. 134217728 bytes (134 MB) copied, 0.130102 s, 1.0 GB/s

6.5查看文件

1. [root@centos7 ~]# rados ls -p test
2. rb.0.16d0.6b8b4567.000000000000
3. rb.0.16d0.6b8b4567.000000000004
4. rb.0.16d0.6b8b4567.000000000020
5. rb.0.16d0.6b8b4567.000000000021
6. rb.0.16d0.6b8b4567.000000000022
7. rb.0.16d0.6b8b4567.000000000023
8. ...
9. rb.0.16d0.6b8b4567.00000000003e
10. rb.0.16d0.6b8b4567.00000000003f
11. rb.0.16d0.6b8b4567.000000000040
12. rb.0.16d0.6b8b4567.000000000041
13. rb.0.16d0.6b8b4567.000000000060
14. rb.0.16d0.6b8b4567.000000000080
15. rb.0.16d0.6b8b4567.000000000081
16. rb.0.16d0.6b8b4567.000000000082
17. rb.0.16d0.6b8b4567.000000000083
18. rb.0.16d0.6b8b4567.000000000084
19. rb.0.16d0.6b8b4567.000000000085
20. rb.0.16d0.6b8b4567.000000000086
21. rb.0.16d0.6b8b4567.000000000087
22. rb.0.16d0.6b8b4567.0000000000a0
23. rb.0.16d0.6b8b4567.0000000000e0
24. rb.0.16d0.6b8b4567.000000000032
25. rb.0.16d0.6b8b4567.0000000000ff
26. rbd_directory
27. test.rbd
28. rb.0.16d0.6b8b4567.000000000025

在格式化了文件系统,同时创建了128M的文件以后,通过rados查看,出现了很多以

rb.0.16d0.6b8b4567的文件,同时出现了连续的文件命令,从rb.0.16d0.6b8b4567.000000000020到rb.0.16d0.6b8b4567.000000000041,共32个,加上ceph的对象大小为4M,共128M,和测试文件大小吻合。其他的一些文件这是ext4文件系统的一些描述信息。

因此,我们可以推测,rbd文件组织是一个{image_name}.rdb 和 若干rbd_prefix.{num},每个块大小为4M,整个rbd的文件数=size/4M+1。

总结

Ceph是一个非常优秀的分布式文件系统,对象首先通过object_name计算出object_id,然后取模,映射到pg上,然后pg通过crush算法映射到一组osd上,其中一个为主osd。

rbd则是ceph的一种访问方式,在rados的基础上的另外一层封装,实现简单,仅添加了一个描述文件,其他的文件通过顺序方式组织起来,通过librbd提供给其他应用访问。

文章来源于腾讯云开发者社区,点击查看原文