ceph_io_3
步骤:
1. client连接monitor获取集群map信息。
2. 同时新主osd1由于没有pg数据会主动上报monitor告知让osd2临时接替为主。
3. 临时主osd2会把数据全量同步给新主osd1。
4. client IO读写直接连接临时主osd2进行读写。
5. osd2收到读写io,同时写入另外两副本节点。
6. 等待osd2以及另外两副本写入成功。
7. osd2三份数据都写入成功返回给client, 此时client io读写完毕。
8. 如果osd1数据同步完毕,临时主osd2会交出主角色。
9. osd1成为主节点,osd2变成副本。
2.3 Ceph IO算法流程
ceph_io_4
1. File用户需要读写的文件。File->Object映射:
a. ino (File的元数据,File的唯一id)。
b. ono(File切分产生的某个object的序号,默认以4M切分一个块大小)。
c. oid(object id: ino ono)。
2. Object是RADOS需要的对象。Ceph指定一个静态hash函数计算oid的值,将oid映射成一个近似均匀分布的伪随机值,然后和mask按位相与,得到pgid。Object->PG映射:
a. hash(oid) & mask-> pgid 。
b. mask = PG总数m(m为2的整数幂)-1 。
3. PG(Placement Group),用途是对object的存储进行组织和位置映射, (类似于redis cluster里面的slot的概念) 一个PG里面会有很多object。采用CRUSH算法,将pgid代入其中,然后得到一组OSD。PG->OSD映射:
a. CRUSH(pgid)->(osd1,osd2,osd3) 。
2.4 Ceph IO伪代码流程
locator = object_name obj_hash = hash(locator) pg = obj_hash % num_pg osds_for_pg = crush(pg) # returns a list of osdsprimary = osds_for_pg[0] replicas = osds_for_pg[1:]
2.5 Ceph RBD IO流程
ceph_rbd_io
步骤:
1. 客户端创建一个pool,需要为这个pool指定pg的数量。
2. 创建pool/image rbd设备进行挂载。
3. 用户写入的数据进行切块,每个块的大小默认为4M,并且每个块都有一个名字,名字就是object 序号。
4. 将每个object通过pg进行副本位置的分配。
5. pg根据cursh算法会寻找3个osd,把这个object分别保存在这三个osd上。
6. osd上实际是把底层的disk进行了格式化操作,一般部署工具会将它格式化为xfs文件系统。
7. object的存储就变成了存储一个文rbd0.object1.file。
2.6 Ceph RBD IO框架图
ceph_rbd_io1
客户端写数据osd过程:
1. 采用的是librbd的形式,使用librbd创建一个块设备,向这个块设备中写入数据。
2. 在客户端本地同过调用librados接口,然后经过pool,rbd,object、pg进行层层映射,在PG这一层中,可以知道数据保存在哪3个OSD上,这3个OSD分为主从的关系。
3. 客户端与primay OSD建立SOCKET 通信,将要写入的数据传给primary OSD,由primary OSD再将数据发送给其他replica OSD数据节点。
2.7 Ceph Pool和PG分布情况