【ceph】AsyncMessenger 通信模块基础--编辑中
ceph网络通信三种实现方式
ceph的网络通信的源码在src/msg下,有Ceph Messager的三个实现:simple,async,xio。
simple模式:2021:基本不用了,不建议看了)
simple模式相对比较简单,一个链接的每一端都有两个线程,分别负责读和写,当集群规模很大的时候,会有大量线程,占用大量资源,限制了网络性能。(SimpleMessenger是网络层最早的实现,当时的网络编程模型还是线程当道,因此simple采用的就是这种简单粗暴的线程模型)
async模式:2021:当前主要模式)
async模式基于Epoll + EventCenter,这也是当前的默认消息机制。(async主要是国内ceph大神麦子迈 王豪迈大神的实现的。随着linux提供epoll这样的系统调用,可以提供基于事件的IO多路服用,越来越多的网络开始使用该系统调用来实现高并发通信。比如libevent。async也是如此。)
xio模式(2021:不太了解)
xio模式基于开源网络通信库accelio来实现,目前处于试验阶段。(xio使用了开源网络通信模块accelio,需要依赖第三方的库,目前也在实验阶段。)
从Messenger.cc 这个类中可以看出在create Messager实例的时候根据type选择网络框架是simple/async/xio.其中选择xio的话需要的话需要定义HAVE_XIO 这个宏,并且xio支持tcp/ip。infiniband 这两种协议,而前两种支持tcp/ip 协议。
AsyncMessenger
相关的类
message数据格式
见:https://blog.csdn.net/bandaoyu/article/details/121315682
Messenger实例名称
在main()函数中首先创建Messenger,然后对注册的Messenger进行bind,绑定后start消息模块进行工作,不同的角色会启动相应的守护进程,如果OSD在main()函数中注册了6个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之间的消息
EventCenter
worker 线程 while循环,执行EventCenter::process_events。
这里事件有三类:
time_events:定时事件,比如connection的定时函数AsyncConnection::tick。
external_events:外部事件,放进去里面立马唤醒线程执行,send_message就是外部事件。
file事件:epoll监听的事件,与文件(如socket连接fd)绑定,当fd可读or可写时执行。
例子如下:
time_events:定时事件,比如connection的定时函数AsyncConnection::tick。
register_time_events.insert(center->create_time_event(delay_period*1000000, this));
external_events:外部事件,放进去里面立马唤醒线程执行,send_message就是外部事件。
Messenger::send_message(Message *m, dest)
AsyncMessenger::send_message(Message *m, dest)
--|AsyncMessenger::_send_message(Message *m, dest)
----|conn=_lookup_conn(dest.addr)
----|AsyncMessenger::submit_message(Message *m,conn,dest,...)
------|conn->send_message(m) # AsyncConnection::send_message(Message *m)
--------|out_q[priority].emplace_back(std::move(bl),m) #放入队列//回调操作(write_handler= new C_handle_write(this))放入event中心,wakeup线程执行
--------|EventCenter::dispatch_event_external(write_handler)
----------|external_event.push_back(write_handler) //放入事件中,就可以唤醒线程去执行
----------|wakeup()
|
|
w->center.process_events
|
cb = event->read_cb;
cb->do_request()
|C_handle_write
|
|
--|write_handler = new C_handle_write(this)
file事件:epoll监听的事件,与文件(如socket连接fd)绑定,当fd可读or可写时执行,如
int r = create_file_event(notify_receive_fd, EVENT_READABLE, notify_handler);
notify_receive_fd可读时,process_events将执行回调notify_handler