Ceph读写流程

发布时间 2023-04-25 12:58:56作者: XU-NING

Ceph 读写流程

概述

Ceph的读写流程是由OSD和PG共同完成的,对于OSD而言,OSD的主要任务是进行消息的接收分发,最终将消息存到队列op_wq中。接下来交由ShardedThreadPool线程池中的线程来处理读写,线程会将请求从op_wq中取出,做如下操作。

在ReplicatedPG类中进行一系列的合法性检查。

对于读请求,在ReplicatedPG类中完成读请求流程,向client发送ACK消息完成读操作。

对于写请求,需要调用ReplicatedPGBackend类,向从副本发送写指令,在从收到所有从副本完成写操作之后,主才会向client发送ACK消息完成写操作。

写操作相对于读操作复杂很多,这是由于Ceph采用副本的高可用机制。一份完整的数据需要存放在多个OSD上面,只有当所有从都确认数据存储到本地,这时候主才可以向client发送写操作成功消息。在 [RADOS: A Scalable, Reliable Storage Service for Petabyte-scale Storage Clusters]中对于写消息提出了primary-copy, chain, splay三个副本策略。 Ceph目前(v10.2.10)采用primary-copy策略。如下图所示

osd1是主osd,在第一个RTT收到client写请求时,向从发送写请求,主在RTT3收到osd2和osd3的ack

的时候向client发送ack。

具体读写流程:

  1. OSD接收消息到消息进入op_wq

如下图所示

ms_fast_dispatch函数是OSD中线程处理client请求的入口函数,接下来进行一系列的调用,进入到op_wq中等待其它线程调用。

  1. ####op_wq出队列线程调用

ShardedThreadPool线程池会选取线程调用shardedthreadpool_worker函数对入队列的 operations进行处理。最终调用ReplicatedPG::do_reequest对于客户端的请求进行分类处理。

  1. 调用ReplicatedPG::execute_ctx(OpContext *ctx)处理读写
    1. 对于读请求来说,在execute_ctx()函数中会调用ReplicatedPGBackend类中的函数

objects_read_sync读入数据,然后在后续的流程中调用complete_read_ctx()向client回复。

    1. 对于写请求来说

如果log过多,需要整理 log 调用calc_trim_to()

调用ReplicatedPGBackend类中issue_op() 向所有从osd发送写请求 主处理从的写完成消息,如果所有的从都完成了写请求,调用回调函数 ReplicatedPG::eval_repop()向client发送消息完成写操作

下图是写操作的示意图:

图中第二步,主向从发写消息的消息类型是MSG_OSD_REPOP, 第三步从回复的消息类型是 MSG_OSD_REPOPREPLY,所带的CEPH_OSD_FLAG_ONDISK标识位为1,表示数据已经写到disk上。