Ceph网络模块(3)——AsyncMessenger代码流程分析

Ceph网络模块(3)——AsyncMessenger代码流程分析


1、消息模块的生命周期

消息模块的生命周期

如图所示以OSD为例描述了消息模块的生命周期,本文如果没有特殊说明均指的是OSD守护进程。在守护进程的main()函数中首先注册并创建了一个Messenger,然后对注册的Messenger进行绑定,绑定后开启消息模块进行工作,消息模块启动后即启动OSD的初始化,在OSD的初始化中让Messenger处于ready状态,即准备工作状态。当消息模块工作结束后处于wait状态,如果需要的话则删除注册的Messenger。这就是消息模块大致的生命周期,下面详细描述一下每个过程的操作。

OSD注册的Messenger实例列表

编号 Messenger实例名称 作用
1 *ms_public 用来处理OSD和Client之间的消息
2 *ms_cluster 用来处理OSD和集群之间的消息
3 *ms_hbclient 用来处理OSD和其它OSD保持心跳的消息
4 *ms_hb_back_server 用来处理OSD接收心跳消息
5 *ms_hb_front_server 用来处理OSD发送心跳消息
6 *ms_objecter 用来处理OSD和Objecter之间的消息
  1. 系统根据不同的角色会启动相应的守护进程,如果分配的是OSD这个角色,则通过 ceph_osd.cc这个文件来启动守护进程,首先进入的是main()函数;
  2. 在main()函数中会对OSD需要的模块进行注册和初始化,我们主要分析消息模块。在main()函数中注册了6个Messenger的实例,如下表所示。Messenger是一个接口类,根据不同的需求对其进行实现,本文主要从AsyncMessenger来分析。
  3. 初始化消息模块后进行绑定。具体执行绑定的是调用AsyncMessenger的bind函数(),实例调用的参数是配置文件中的g_conf->public_addr和g_conf->cluster_addr等。AsyncMessenger的bind()函数执行的是Processor::bind()。在Processor的bind函数中真正完成了绑定,Processor的bind函数有两个参数,一个是addr,另一个是port。在Processor的bind函数中主要进行的操作有:
    1) 根据bind_addr得出socket的参数family;
    2) 创建socket,family参数根据步骤1)获取;
    3) 将socket设置为非阻塞;
    4) 绑定需要监听的端口;
    5) 获取绑定的socket的name;
    6) 监听端口。
  4. 开启消息模块。在步骤2中create了Messenger,还需要开启它的服务来工作,具体执行是由AsyncMessenger来执行,在create的时候new了一个AsyncMessenger。AsyncMessnger在start函数中调用WorkPool的start来具体执行AsyncMessenger的开启工作。
  5. 启动OSD,在这个之前有一个pre启动(int err = osd->pre_init()),在这个后面还有一个final启动(osd->final_init();)。执行OSD启动的是osd.cc文件中的init函数,调用Messenger的add_dispatcher_head()函数将响应的消息实例加入到dispatchers的链表中。在add_dispatcher_head()函数中如果是链表中的第一个元素,则执行ready函数。ready函数的具体执行是由AsyncMessenger的ready来实现,通过WorkerPool来获取worker,然后启动事件处理中心来处理事件。启动worker线程,并通知事件处理中心可以开始工作了,主要是事件的create和处理。这个时候AsyncMessenger的机制已经基本全部启动完成,可以进行正常的工作。
  6. 注册的Messenger进入wait状态。这个wait和我们平时理解的等待状态不同,wait主要执行的操作是完成清理工作,关闭所有的连接。
  7. 执行完wait操作后,删除之前注册的Messenger。

2、消息模块初始化

Monitor/Client/OSD/MDSDaemon四个模块都有相应main()函数,分别在src文件夹目录下的ceph_mon.cc/ceph_fuse.cc/ceph_osd.cc/ceph_mds.cc源码文件中,在各自的main()函数中,各个模块根据需要注册一个或者多个Messenger(Messenger指针指向AsyncMessenger实例),然后在各自的init()初始化函数中调用add_dispatcher_head ()/add_dispatcher_tail ()函数来启动消息模块。消息模块的初始化流程如下图所示。

消息模块初始化

  • 6
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
Ceph是一个分布式存储系统,包括多个组件,其中包括Librbd块存储库。在Ceph中,Librbd提供了一种将RBD(块设备)映射到客户端的方法,并使客户端能够读写这些设备。在本文中,我们将分析Librbd块存储库的源代码以及RBD的读写过程。 1. Librbd源码分析 Librbd块存储库的源代码位于src/librbd目录下。其中,包括librbd.cc、ImageCtx.cc、ImageWatcher.cc、Journal.cc等多个源代码文件。这些源代码文件组成了Librbd块存储库的核心。 其中,librbd.cc是Librbd块存储库的主要源代码文件。在这个文件中,包括了Librbd的初始化、映射、卸载等方法。ImageCtx.cc则是Image上下文,用于管理Image的状态、锁定、映射等信息。ImageWatcher.cc用于监控Image的状态变化,Journal.cc则是Librbd的Journal日志管理。 2. RBD读写流程源码分析Ceph中,RBD由client和server两个部分组成。client在客户端上运行,提供了将RBD映射到客户端的方法。server在存储集群中运行,提供了RBD的存储和管理。 RBD的读写流程如下: 1)客户端向Ceph Monitor请求RBD映射信息,Monitor返回Image ID和Image特性; 2)客户端向Ceph OSD请求RBD数据块,OSD返回数据块内容; 3)客户端将数据写入或读取到本地块设备; 4)客户端向Ceph OSD写入或读取数据块,OSD返回操作结果; 5)客户端向Ceph Monitor请求解除RBD映射,Monitor返回解除结果。 在上述过程中,涉及到的源代码文件有:librbd.cc、ImageCtx.cc、ImageWatcher.cc、Journal.cc等。 总结 Librbd块存储库和RBD读写流程Ceph存储系统的核心组件之一,通过分析代码可以更加深入地了解Ceph存储系统的实现原理。同时,对于开发者来说,也有助于在Ceph存储系统上构建更加高效、稳定的存储应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值