Ceph读写流程概述
回顾:
上一篇分析了osd定时器部分,接下会再大概了解一下ceph的读写流程好为以后深入理解其他逻辑做准备
读写流程分析:
一、模块
1.1 消息封装:在OSD上发送和接收信息。
cluster_messenger -与其它OSDs和monitors沟通
client_messenger -与客户端沟通
1.2 消息调度:
Dispatcher类,主要负责消息分类
1.3 工作队列:
1.3.1 OpWQ: 处理ops(从客户端)和sub ops(从其他的OSD)。运行在op_tp线程池。
1.3.2 PeeringWQ: 处理peering任务,运行在op_tp线程池。
1.3.3 CommandWQ:处理cmd命令,运行在command_tp。
1.3.4 RecoveryWQ: 数据修复,运行在recovery_tp。
1.3.5 SnapTrimWQ: 快照相关,运行在disk_tp。
1.3.6 ScrubWQ: scrub,运行在disk_tp。
1.3.7 ScrubFinalizeWQ: scrub,运行在disk_tp。
1.3.8 RepScrubWQ: scrub,运行在disk_tp。
1.3.9 RemoveWQ: 删除旧的pg目录。运行在disk_tp。
1.4 线程池:
有4种OSD线程池:
1.4.1 op_tp: 处理ops和sub ops
1.4.2 recovery_tp:处理修复任务
1.4.3 disk_tp: 处理磁盘密集型任务
1.4.4 command_tp: 处理命令
二、客户端写入数据大致流程及保存形式
2.1 读写框架
{width="439" height="379"}
\
{width="328" height="382"}
\
\
2.2 客户端写入流程
在客户端使用 rbd 时一般有两种方法:
● 第一种 是 Kernel rbd。就是创建了rbd设备后,把rbd设备map到内核中,形成一个虚拟的块设备,这时这个块设备同其他通用块设备一样,一般的设备文件为/dev/rbd0,后续直接使用这个块设备文件就可以了,可以把 /dev/rbd0 格式化后 mount 到某个目录,也可以直接作为裸设备使用。这时对rbd设备的操作都通过kernel rbd操作方法进行的。
● 第二种是 librbd 方式。就是创建了rbd设备后,这时可以使用librbd、librados库进行访问管理块设备。这种方式不会map到内核,直接调用librbd提供的接口,可以实现对rbd设备的访问和管理,但是不会在客户端产生块设备文件。
应用写入rbd块设备的过程:
1. 应用调用 librbd 接口或者对linux 内核虚拟块设备写入二进制块。下面以 librbd 为例。
2. librbd 对二进制块进行分块,默认块大小为 4M,每一块都有名字,成为一个对象
3. librbd 调用 librados 将对象写入 Ceph 集群
4. librados 向主 OSD 写入分好块的二进制数据块 (先建立TCP/IP连接,然后发送消息给 OSD,OSD 接收后写入其磁盘)
5. 主 OSD 负责同时向一个或者多个次 OSD 写入副本。注意这里是写到日志(Journal)就返回,因此,使用SSD作为Journal的话,可以提高响应速度,做到服务器端对客户端的快速同步返回写结果(ack)。
6. 当主次OSD都写入完成后,主 OSD 向客户端返回写入成功。
7. 当一段时间(也许得几秒钟)后Journal 中的数据向磁盘写入成功后,Ceph通过事件通知客户端数据写入磁盘成功(commit),此时,客户端可以将写缓存中的数据彻底清除掉了。
8. 默认地,Ceph 客户端会缓存写入的数据直到收到集群的commit通知。如果此阶段内(在写方法返回到收到commit通知之间)OSD 出故障导致数据写入文件系统失败,Ceph 将会允许客户端重做尚未提交的操作(replay)。因此,PG 有个状态叫 replay:“The placement group is waiting for clients to replay operations after an OSD crashed.”。
\
也就是,文件系统负责文件处理,librbd 负责块处理,librados 负责对象处理,OSD 负责将数据写入在Journal和磁盘中。
\
该过程具有强一致性的特点:
● Ceph 的读写操作采用 Primary-Replica 模型,Client 只向 Object 所对应 OSD set 的 Primary 发起读写请求,这保证了数据的强一致性。
● 由于每个 Object 都只有一个 Primary OSD,因此对 Object 的更新都是顺序的,不存在同步问题。
● 当 Primary 收到 Object 的写请求时,它负责把数据发送给其他Replicas,只要这个数据被保存在所有的OSD上时,Primary 才应答Object的写请求,这保证了副本的一致性。这也带来一些副作用。相比那些只实现了最终一致性的存储系统比如 Swift,Ceph 只有三份拷贝都写入完成后才算写入完成,这在出现磁盘损坏时会出现写延迟增加。
● 在 OSD 上,在收到数据存放指令后,它会产生2~3个磁盘seek操作:
○ 把写操作记录到 OSD 的 Journal 文件上(Journal是为了保证写操作的原子性)。
○ 把写操作更新到 Object 对应的文件上。
○ 把写操作记录到 PG Log 文件上。
\
下期预告:
Osd存储系统——FileStore