osd 代码流分析:Ceph 数据IO全栈流程-源码分析【附源码】_Darren_Wen_51CTO博客
作为分布式存储系统,Msg(src/msg)模块可谓是Ceph的基石之一。Ceph发展到Luminous ,已经支持的3大通信机制:simple,async和xio,其中simple历史最为悠久,是Ceph最早的通信模块,原理简单但性能较差(多线程模型,对于较大的集群,会产生很多线程,对主机的要求也比较高。)。async作为后起之秀,优良的性能使其自Luminous开始已经作为了缺省msg方案。xio拥有众多实验特性,目前距离生产环境还有很大距离。
在使用OOP设计一个通信模块时,往往少不了以下几个抽象:
- Messenger 用于在最高层次管理所有通信,通常包括通信策略,工作线程等等
- Connection表示对一个连接的抽象,经常会设计一个状态机来供上层管理该Connection
- Message是对消息的封装,通常包含’Header + Data + Checking’ 几部分,Message和报文流的常常需要转换方法,Message->buf:encode(),Message<-buf:decode()
- Stack 负责实现真实的通信,比如TCP/IP协议栈、RDMA协议栈
以此为基础,Ceph Msg框架就显得十分清晰,下面就是Async机制核心的封装:AsyncMessenger,Processor,AsyncConnection,NetworkStack,Worker,EventCenter,Message,本文将逐个讨论这些角色。
上图是Ceph Msg模块框图,可以看出,msg模块可以分为3个层次:
层次 | 内容 |
1 | async/simple/xio |
2 | Generic NetworkStack(通用) |
3 | Specific NetworkStack(特定) |
上层将”通信机制”抽象出来,下层聚焦于协议栈,包括硬件无关的部分以及硬件相关的部分,比如RDMAStack针对配置了IB卡的存储节点,DPDKStack用于使用X86 DPDK技术的存储节点,而PosixStack则是Linux原生的Socket通信接口。
AsyncMessenger
AsynMessenger类继承自Messenger:
class AsyncMessenger:public SimplePolicyMessenger
class SimplePolicyMessenger:public Messenger
SimplePolicyMessenger是和”连接策略”相关的类。AsyncMessenger作为整个通信模块的核心和中转,不论是作为底层通信的NetworkStack,还是作为连接的抽象的Connection,抑或处理对端链接请求的Processor,都要围着它转。以OSD进程的main函数为例(src/ceph_osd.cc),整个OSD进程也不过7个Messenger实例:
ms_public, ms_cluster, ms_hb_back_client, ms_hb_front_client, ms_hb_back_server, ms_hb_front_server, ms_objecter, |
这7个Messenger分别用来处理不同类型的消息。
//src/msg/async/AsyncMessenger.h
75 class AsyncMessenger : public SimplePolicyMessenger {
139 int send_message(Message *m, const entity_inst_t& dest) override {}
176 void ready() override; //启动Processor和dispatch_queue线程
197 AsyncConnectionRef create_connect(const entity_addr_t& addr, int type);
221 NetworkStack *stack;
222 std::vector<Processor*> processors;
223 friend class Processor;
224 DispatchQueue dispatch_queue;
273 ceph::unordered_map<entity_addr_t, AsyncConnectionRef> conns;
280 set<AsyncConnectionRef> accepting_conns;
343 AsyncConnectionRef lookup_conn(const entity_addr_t& k) {
346 }
348 int accept_conn(AsyncConnectionRef conn)