【ceph 】ceph messenger的Dispatcher模块分析

Dispatcher模块

dispatcher 是消息分发中心,所有收到的消息都经由该模块,并由该模块转发给相应的处理模块(moncliet、mdsclient、osd等)。

如图:

   创建messenger后,把处理消息的dispatcher add 到dispatcher list里面,当messenger接收到消息msg之后,把msg放入msg的队列,由消息处理线程取出来,遍历dispatcher list里面dispatcher,在dispatcher里面的switch比对msg-type,如果刚好有可以处理该msg的分支就处理,dispatcher返回ture,结束。如果该dispatcher里面的switch可以处理该msg的分支,就到default,dispatcher返回false。msg接着会被交给下一个dispatcher去处理。直到被处理,或dispatcher遍历完。

https://www.edrawmax.cn/online/share.html?code=6d487368b32711ecacb543339f8ff90e

        Dispatcher类是一个基类,里面设计封装了应用同Messenger交互的接口(每个具体的Dispatcher派生类自行去实现更具体的消息处理,一般都是再根据消息类型来分开处理消息)。Dispatcher并不是所有的接口封装都是为了转发消息,它更深层次的含义是提供一个应用层和底层的通信接口,而这个接口的桥梁是Messenger消息管理器。


当底层有消息到来时,Messenger会将消息转给dispatcher对于的ms_*系列的接口,最常用的是ms_dispatch接口,因此你可以看到像monitor,osd这些应用的核心消息处理都在ms_dispatch接口里面实现。

bool OSD::ms_dispatch(Message *m)
{
 ……
  _dispatch(m);

……
  return true;
}

void OSD::_dispatch(Message *m)
{
 
  switch (m->get_type()) {
    // -- don't need OSDMap --
    // map and replication
  case CEPH_MSG_OSD_MAP:
    handle_osd_map(static_cast<MOSDMap*>(m));
    break;
  case MSG_MON_GET_PURGED_SNAPS_REPLY:
    handle_get_purged_snaps_reply(static_cast<MMonGetPurgedSnapsReply*>(m));
    break;
    // osd
  case MSG_OSD_SCRUB:
    handle_scrub(static_cast<MOSDScrub*>(m));
    break;
  case MSG_COMMAND:
    handle_command(static_cast<MCommand*>(m));
    return;
    // -- need OSDMap --
  case MSG_OSD_PG_CREATE:
    {
      OpRequestRef op = op_tracker.create_request<OpRequest, Message*>(m);
      if (m->trace)
        op->osd_trace.init("osd op", &trace_endpoint, &m->trace);
      // no map?  starting up?
      if (!get_osdmap()) {
        dout(7) << "no OSDMap, not booted" << dendl;
    logger->inc(l_osd_waiting_for_map);
        waiting_for_osdmap.push_back(op);
    op->mark_delayed("no osdmap");
        break;
      }
      // need OSDMap
      dispatch_op(op);
    }
  }
}

Dispatcher的使用

最简单的方式就是应用本身作为Dispatcher的派生类,如此,Messenger便是直接通过应用关联,比如Monitor、osd、mgr都是应用组件本身作为Dispatcher的派生类。

class Monitor : public Dispatcher

class MDSDaemon : public Dispatcher 

申请一个Dispatcher的派生类实例,做为应用的模块注册给Messenger,比如RadosClient里面会注册各个Client给Messenger,而这些Client都是Dispatcher的派生类。

class MDSDaemon : public Dispatcher

{……}

int MDSDaemon::init()
{

……

  messenger->add_dispatcher_tail(&beacon);
  messenger->add_dispatcher_tail(this); #this 就是MDSDaemon 它自己

……
 }

bool MDSDaemon::ms_dispatch(const ref_t<Message> &m)
{
……
}

例子分析:

Dipatcher类是消息分发的接口,OSD、MON、等类都继承该类,并实现了Dipatcher的消息分发接口

class OSD : public Dispatcher,public md_config_obs_t
{
    /** OSD **/
}

class Monitor : public Dispatcher,public md_config_obs_t
{
public:

    // me
    string name;
}

在OSD::init()函数中把  处理不同消息  的Dipatcher加入到Messenger实例中 

// i'm ready!
client_messenger->add_dispatcher_head(this);
cluster_messenger->add_dispatcher_head(this);
hbclient_messenger->add_dispatcher_head(&heartbeat_dispatcher);
hb_front_server_messenger->add_dispatcher_head(&heartbeat_dispatcher);
hb_back_server_messenger->add_dispatcher_head(&heartbeat_dispatcher);
objecter_messenger->add_dispatcher_head(service.objecter);

Messenger::add_dispatcher_head(Dispatcher *d) 把Dipatcher放入链表Messenger::list<Dispatcher*> dispatchers中,并调用ready(),SimpleMessenger::ready()重写了基类的ready,

void add_dispatcher_head(Dispatcher *d)
{
    bool first = dispatchers.empty();
    dispatchers.push_front(d);
    if (d->ms_can_fast_dispatch_any())
        fast_dispatchers.push_front(d);
    if (first)
        ready();
}

在ready函数中调用DispatchQueue::start, start()函数启动DispatchQueue::DispatchThread和DispatchQueue::LocalDeliveryThread线程类,最终调用DispatchQueue::entry()和DispatchQueue::run_local_delivery。

void DispatchQueue::start()
{
    assert(!stop);
    assert(!dispatch_thread.is_started());
    dispatch_thread.create("ms_dispatch");    //调用Thread::create->Thread::try_create->Thread::_entry_func->Thread::entry_wrapper->DispatchThread::entry
    local_delivery_thread.create("ms_local");
}
class DispatchThread : public Thread
{
    DispatchQueue *dq;
public:
    explicit DispatchThread(DispatchQueue *dq) : dq(dq) {}
    void *entry()
    {
        dq->entry();
        return 0;
    }
} dispatch_thread;

在DispatchQueue::entry()中调用根据不同的命令码qitem.get_code调用不同的Messenger类中的处理函数:

void DispatchQueue::entry()
{
    .
    .

    switch (qitem.get_code())
    {
    case D_BAD_REMOTE_RESET:
        msgr->ms_deliver_handle_remote_reset(qitem.get_connection());
        break;
    case D_CONNECT:
        msgr->ms_deliver_handle_connect(qitem.get_connection());
        break;
    case D_ACCEPT:
        msgr->ms_deliver_handle_accept(qitem.get_connection());
        break;
    case D_BAD_RESET:
        msgr->ms_deliver_handle_reset(qitem.get_connection());
        break;
    default:
        assert(0);
    }
}
else
{
    Message *m = qitem.get_message();
    if (stop)
    {
        ldout(cct, 10) << " stop flag set, discarding " << m << " " << *m << dendl;
        m->put();
    }
    else
    {
        uint64_t msize = pre_dispatch(m);
        msgr->ms_deliver_dispatch(m);
        post_dispatch(m, msize);
    }
}
.
.

}

在Messenger::ms_deliver_dispatch中最终遍历注册到链表的Dipatcher,找到可以处理到来的消息的 Dipatcher调用Dipatcher继承类的ms_dispatch进行处理:

void ms_deliver_dispatch(Message *m)
{
    m->set_dispatch_stamp(ceph_clock_now(cct));
    for (list<Dispatcher *>::iterator p = dispatchers.begin();
            p != dispatchers.end();
            ++p)
    {
        if ((*p)->ms_dispatch(m))     //在Dispatcher继承类中进行处理
            return;
    }
    lsubdout(cct, ms, 0) << "ms_deliver_dispatch: unhandled message " << m << " " << *m << " from "
                         << m->get_source_inst() << dendl;
    assert(!cct->_conf->ms_die_on_unhandled_msg);
    m->put();
}

原文:ceph Dispatcher模块分析_weixin_34320724的博客-CSDN博客

bool MgrClient::ms_dispatch(const ref_t<Message>& m)
{
  std::lock_guard l(lock);

  switch(m->get_type()) {
  case MSG_MGR_MAP:
    return handle_mgr_map(ref_cast<MMgrMap>(m));
  case MSG_MGR_CONFIGURE:
    return handle_mgr_configure(ref_cast<MMgrConfigure>(m));
  case MSG_MGR_CLOSE:
    return handle_mgr_close(ref_cast<MMgrClose>(m));
  case MSG_COMMAND_REPLY:
    if (m->get_source().type() == CEPH_ENTITY_TYPE_MGR) {
      MCommandReply *c = static_cast<MCommandReply*>(m.get());
      handle_command_reply(c->get_tid(), c->get_data(), c->rs, c->r);
      return true;
    } else {
      return false;
    }
  case MSG_MGR_COMMAND_REPLY:
    if (m->get_source().type() == CEPH_ENTITY_TYPE_MGR) {
      MMgrCommandReply *c = static_cast<MMgrCommandReply*>(m.get());
      handle_command_reply(c->get_tid(), c->get_data(), c->rs, c->r);
      return true;
    } else {
      return false;
    }
  default:
    ldout(cct, 30) << "Not handling " << *m << dendl; 
    return false;
  }
}

创建 osd_dispatcher/mon_dispatcher ==>add_dispatcher_

                                                                  ==>ready()

                                                                       ==>start()

                                                                             ==>DispatchThread

                                                                                   ==>entry()

                                                                             ==>LocalDeliveryThread

                                                                                   ==>run_local_delivery()

ms_fast_dispatch和ms_dispatch的区别

fast_preprocess

d) 调用函数read_message()来接收消息,当本函数返回后,就完成了接收消息

2) 调用函数in_q->fast_preprocess(m)预处理消息

3) 调用函数in_q->can_fast_dispatch(m),如果可以进行fast_dispatch,就in_q->fast_dispatch(m)处理。fast_dispatch并不把消息加入到mqueue里,而是直接调用msgr->ms_fast_dispatch()函数,并最终调用注册的fast_dispatcher来进行处理。

4) 如果不能fast_dispatch,就调用函数in_q->enqueue(m, m->get_priority(), conn_id)把接收到的消息加入到DispatchQueue的mqueue队列里,由DispatchQueue的分发线程调用ms_dispatch处理。

ms_fast_dispatch和ms_dispatch两种处理的区别在于:ms_dispatch是由DispatchQueue的线程处理的,它是一个单线程;ms_fast_dispatch函数是由Pipe接收线程直接调用处理的,因此性能比前者好。

ceph网络通信 | Ivanzz

Ceph 数据IO全栈流程-源码分析_Darren_Wen的技术博客_51CTO博客

  bool ms_can_fast_dispatch(const Message *m) const override {
    switch (m->get_type()) {
    case CEPH_MSG_PING:
    case CEPH_MSG_OSD_OP:
    case CEPH_MSG_OSD_BACKOFF:
    case MSG_OSD_SCRUB2:
    case MSG_OSD_FORCE_RECOVERY:
    case MSG_MON_COMMAND:
    case MSG_OSD_PG_CREATE2:
    case MSG_OSD_PG_QUERY:
    case MSG_OSD_PG_QUERY2:
  ……
      return true;
    default:
      return false;
    }
  }


bool DispatchQueue::can_fast_dispatch(const cref_t<Message> &m) const
{
  return msgr->ms_can_fast_dispatch(m);
}

void DispatchQueue::fast_dispatch(const ref_t<Message>& m)
{
  uint64_t msize = pre_dispatch(m);
  msgr->ms_fast_dispatch(m);
  post_dispatch(m, msize);
}
 

void DispatchQueue::run_local_delivery()
{
  std::unique_lock l{local_delivery_lock};
  while (true) {
    if (stop_local_delivery)
      break;
    if (local_messages.empty()) {
      local_delivery_cond.wait(l);
      continue;
    }
    auto p = std::move(local_messages.front());
    local_messages.pop();
    l.unlock();
    const ref_t<Message>& m = p.first;
    int priority = p.second;
    fast_preprocess(m);
    if (can_fast_dispatch(m)) {
      fast_dispatch(m);
    } else {
      enqueue(m, priority, 0);
    }
    l.lock();
  }
}

Dispatcher处理线程

dispatcher 是消息分发中心,所有收到的消息都经由该模块,并由该模块转发给相应的处理模块(moncliet、mdsclient、osd等)。

其实现方式比较简单,就是把所有的模块及其处理消息的方法 handle 注册到分发中心,具体函数为 add_dispatcher_head/tail(),这样就向 dispatcher_queue 中添加了指定模块。后续在分发消息时,对 dispatcher_queue 进行轮询,直到有一个处理模块能够处理该消息,通过 message->get_type() 来指定消息的处理函数。所有的消息分发都在 dispatcher 线程中完成。

在 add_dispatcher_head() 和 add_dispatcher_tail() 函数中,都做了 dispatcher 队列是否为空的判断(通过 dispatchers.empty() == true)。如果判定结果为空,说明需要重新创建 dispatcher 线程并绑定服务端地址,加入事件中心监听端口,具体方法在 ready() 中。

  void add_dispatcher_head(Dispatcher *d) {
    bool first = dispatchers.empty();
    dispatchers.push_front(d);
    if (d->ms_can_fast_dispatch_any())
      fast_dispatchers.push_front(d);
    if (first)
      ready();
  }

 add_dispatche_* 中调用了 AsyncMessenger::ready() 方法。下面给出AsyncMessenger::ready()方法代码:

p->start()(Processor::start())方法中监听 EVENT_READABLE 事件,并把事件提交到 EventCenter 事件中心,由上文介绍的 msgr-worker-x 线程去轮询事件中心的队列,监听端口是否收到消息。收到的消息则由 dispatcher 线程分发给指定的处理程序,其分发消息的接口为 ms_dispatch() 和 ms_fast_dispatch()。

dispatch_queue.start() 中开启了消息分发线程,分别为处理外部消息的 ms_dispatch 线程和处理本地消息的 ms_local 线程。相应的,它们有各自的优先级队列(注意:分发消息的队列时有优先级的,优先级越高,发送时机越早),分别是存储外部消息的 mqueue 和本地消息队列的 local_messages。消息队列的添加方式也有两种:mqueue.enqueue() 和 local_queue.emplace()。

void AsyncMessenger::ready()
{
  ldout(cct,10) << __func__ << " " << get_myaddrs() << dendl;

  stack->ready();
  //绑定端口
  if (pending_bind) {
    int err = bindv(pending_bind_addrs);
    if (err) {
      lderr(cct) << __func__ << " postponed bind failed" << dendl;
      ceph_abort();
    }
  }

  Mutex::Locker l(lock);
  //调用 worker 线程,监听端口
  for (auto &&p : processors)  
    p->start();
  //开启 ms_dispatcher 和 ms_locla 线程
  dispatch_queue.start();
}

void DispatchQueue::start()
{
  ceph_assert(!stop);
  ceph_assert(!dispatch_thread.is_started());
  //开启 ms_dispatch 和 ms_local 线程
  dispatch_thread.create("ms_dispatch");
  local_delivery_thread.create("ms_local");
}


链接:https://www.jianshu.com/p/58956728dadc

Messenger和Dispatcher两大角色

ceph通信模块的角色主要分为Messenger和Dispatcher两大角色

使用ceph通信模块来收发消息
* 发送消息

发消息比较简单,应用只需将消息内容按照需要的消息类型(定义在messaging/*或自定义)进行封装后调用Messenger的send_message即可。

 
接收消息
Messenger是如何将消息转给应用的或者说是如何管理?

Messenger设计了两个分发器管理成员:dispatchers和fast_dispatchers,用来处理不同类型的请求处理。应用层则按需求将不同的分发器注册给Messenger,进而Messenger接收到底层来的消息时,会将消息分发给已经注册的两个dispatchers。


设计fast_dispatchers的目的就是为了让有些消息能够省去底层的一层流程(如放入队列),直接到达应用。

Dispatcher类是一个基类,里面设计封装了应用同Messenger交互的接口(每个具体的Dispatcher派生类自行去实现更具体的消息处理,一般都是再根据消息类型来分开处理消息)。Dispatcher并不是所有的接口封装都是为了转发消息,它更深层次的含义是提供一个应用层和底层的通信接口,而这个接口的桥梁是Messenger消息管理器。


当底层有消息到来时,Messenger会将消息转给dispatcher对于的ms_*系列的接口,最常用的是ms_dispatch接口,因此你可以看到像monitor,osd这些应用的核心消息处理都在ms_dispatch接口里面实现。

Dispatcher的使用

最简单的方式就是应用本身作为Dispatcher的派生类,如此,Messenger便是直接通过应用关联,比如Monitor、osd、mgr都是应用组件本身作为Dispatcher的派生类。

class Monitor : public Dispatcher

申请一个Dispatcher的派生类实例,做为应用的模块注册给Messenger,比如RadosClient里面会注册各个Client给Messenger,而这些Client都是Dispatcher的派生类。

消息类型

ceph的消息基类是:Message,Message里面设计了一个type成员,用来区分不同的消息类型,不同的消息模块可以通过type来构造,而这些type定义在Message.h中

switch(m->get_type()) {

case MSG_MGR_MAP:
    return handle_mgr_map(ref_cast<MMgrMap>(m));
  case MSG_MGR_CONFIGURE:
    return handle_mgr_configure(ref_cast<MMgrConfigure>(m));

……}

 type定义在Message.h中

Message.h

……

// monitor internal
#define MSG_MON_SCRUB              64
#define MSG_MON_ELECTION           65
#define MSG_MON_PAXOS              66
#define MSG_MON_PROBE              67
#define MSG_MON_JOIN               68
#define MSG_MON_SYNC           69
#define MSG_MON_PING               140

……

技巧:比如你想要看某个消息是谁发的,那么你只需要去查看这个消息类型对应的消息模块有哪些,然后再查到谁在使用这个消息模块来封装消息,进而就可以找到发送这个消息的地方。

例子
以ceph-mon为例子,Monitor类继承自Dispatcher

class Monitor : public Dispatcher,
实现它的ms_dispatcher方法,这个方法里面实现了mon的消息处理

注册给Messenger,add_dispatcher_tail方法就是将当前应用添加到dispatcher列表中

messenger->add_dispatcher_tail(this); 
 Messenger收到消息转给dipatcher

void ms_deliver_dispatch(Message *m)
{
    m->set_dispatch_stamp(ceph_clock_now());
    for (list<Dispatcher *>::iterator p = dispatchers.begin();
            p != dispatchers.end();
            ++p)
    {
        if ((*p)->ms_dispatch(m))
            return;

    }
    lsubdout(cct, ms, 0) << "ms_deliver_dispatch: unhandled message " << m << " " << *m << " from "
                                    << m->get_source_inst() << dendl;
    assert(!cct->_conf->ms_die_on_unhandled_msg);
    m->put();

}
ceph monitor处理消息

bool ms_dispatch(Message *m) override
{
    lock.Lock();
    _ms_dispatch(m);
    lock.Unlock();
    return true;

}

bool MgrClient::ms_dispatch2(const ref_t<Message>& m)
{
  std::lock_guard l(lock);

  switch(m->get_type()) {
  case MSG_MGR_MAP:
    return handle_mgr_map(ref_cast<MMgrMap>(m));
  case MSG_MGR_CONFIGURE:
    return handle_mgr_configure(ref_cast<MMgrConfigure>(m));
  case MSG_MGR_CLOSE:
    return handle_mgr_close(ref_cast<MMgrClose>(m));
  case MSG_COMMAND_REPLY:
    if (m->get_source().type() == CEPH_ENTITY_TYPE_MGR) {
      MCommandReply *c = static_cast<MCommandReply*>(m.get());
      handle_command_reply(c->get_tid(), c->get_data(), c->rs, c->r);
      return true;
    } else {
      return false;
    }
  case MSG_MGR_COMMAND_REPLY:
    if (m->get_source().type() == CEPH_ENTITY_TYPE_MGR) {
      MMgrCommandReply *c = static_cast<MMgrCommandReply*>(m.get());
      handle_command_reply(c->get_tid(), c->get_data(), c->rs, c->r);
      return true;
    } else {
      return false;
    }
  default:
    ldout(cct, 30) << "Not handling " << *m << dendl; 
    return false;
  }
}

未整理内容;

Ceph网络模块使用案例:OSD心跳检测机制 - 灰信网(软件开发博客聚合)

ceph的组件主要包括,OSD,monitor,mgr,osdclient,client等,这些模块内部的通信,以及模块间的通信都使用了,后面我们直接把这些组件称为网络模块的使用者。使用者在使用网络模块的时候,主要涉及到2个角色,一个是messenger,一个是dispatcher。messenger相当于一个消息管理器(网络模块的核心,消息的发送和接收都是messenger通过底层的类实现),dispatcher相当于一个消息的处理器。

-messenger

  • ① 将dispatcher移交给它的信息发送给其它节点(节点,这里节点是一个逻辑单元,比如osd.0就算是一个节点,osd.1算一个新的节点)处理
  • ② 从其它节点的messenger获取消息移交给本节点的dispatcher。

-dispatcher

  • ① 对接收到的消息(有messenger移交给它)进行处理
  • ② 把需要发送的消息移交给本节点的messenger

每个ceph组件都会注册多个messenger和多个dispatcher用于处理不同类型的消息。以OSD组件为例,OSD的守护进程启动的时候会注册7个messenger来管理消息,每个messenger的用途不一样。这部分代码在ceph osd守护进程启动中 /src/ceph_osd.cc。 每一个OSD都有一个守护进程(OSD deamon)。这个deamon负责完成OSD的所有逻辑功能,包括与monitor和其他OSD(事实上是其他OSD的deamon)通信以维护更新系 统状态,与其他OSD共同完成数据的存储和维护,与client通信完成各种数据对象操作等等。

例子:一个OSD模块会注册7个messenger和2个dispatcher。

编号

Messenger实例名称

作用

1

*ms_public

用来处理OSD和Client之间的消息

2

*ms_cluster

用来处理OSD和集群之间的消息

3

*ms_hb_front_client

用来向其它OSD发送心跳的消息

4

*ms_hb_back_client

用来向其它OSD发送心跳的消息

5

*ms_hb_back_server

用来接收其他OSD的心跳消息

6

*ms_hb_front_server

用来接收其他OSD的心跳消息

7

*ms_objecter

用来处理OSD和Objecter之间的消息

编号

Dispatcher实例名称

作用

1

*OSD

可以处理部分osd节点的消息

2

*heartbeat_dispatcher

处理心跳连接

1 消息模块的使用框架

1.1 发送消息

本节描述ceph中的应用(osd、mgr、monitor等)是如何使用网络模块发送消息的。在实际的应用中,有两种常见的发送消息的方式,当然这两种方式只是看起来有些不同,的底层实现都是相同,都是调用AsyncConnection::send_message(Message *m)把消息发送出去。

1)方式一:使用AsyncMessenger::send_message(Message *m, const entity_inst_t& dest))

其中Message *m是要发送的消息,dest是目的地址。

send_message会首先去判断自己和目标地址之前是不是已经存在链接Connection,如果没有就创建一个,conn->send_message(m)发送消息

-----------------------------------------------------------

  conn->send_message(m)

  -----------------------------------------------------------

2) 方式二:

① 首先要通过Messenger类,获取对应的Connection:

  ------------------------------------------------------------

  conn = messenger->get_connection(dest_server);

  ------------------------------------------------------------

  get_connection过程是这样的,如果dest.addr是my_inst.addr,就直接返回local_connection。

  如果链接不存在就新建一个。

② 当获得一个Connection之后,就可以调用Connection的发送函数来发送消息。

  -----------------------------------------------------------

  conn->send_message(m)

  -----------------------------------------------------------

具体发送的实现过程依赖于选择的消息模式,simple、async等实现方式都不同。在另一个文章里我会讲到具体实现过程,这里不多做解释。

1.2 消息的接收

消息的接收过程简言之就是通过监听socket判断是否有消息到来,如果有就接收。这个过程是个很复杂的过程,涉及到了连接建立、错误处理等等。具体的实现依赖于选择的消息模式,比如,SimpleMessenger是使用一个read线程来实现;AsyncMessenger是使用基于事件的机制实现。接收的过程对应用层都是透明的,本章不做解释。

1.3 消息的处理

消息接收完成后,就进入消息的处理。首先判断消息m是否可以fast_dispatch,如果可以,调用注册fast_dispatcher函数处理消息。如果不能fast_dispatch,调用函数in_q->enqueue,将接收到的消息加入到DispatchQueue的mqueue队列中,排队等待处理。

2 ceph OSD心跳检测与网络模块 

下面我们具体举一个OSD心跳检测的例子来讲解,通过心跳检测机制来了解网络模块的使用。在ceph中需要通过心跳检测来判断OSD是不是在线,因为这部分的功能比较简单独立。

2.1 Messenger & Dispatcher的注册

在OSD模块注册的7个Messenger和2个Dispatcher中,4个Messenger都和心跳检测相关,一个heartbeat_dispatcher用来处理心跳连接。

编号

Messenger实例名称

作用

1

*ms_public

用来处理OSD和Client之间的消息

2

*ms_cluster

用来处理OSD和集群之间的消息

3

*ms_hb_front_client

用来向其它OSD发送心跳的消息

4

*ms_hb_back_client

用来向其它OSD发送心跳的消息

5

*ms_hb_back_server

用来接收其他OSD的心跳消息

6

*ms_hb_front_server

用来接收其他OSD的心跳消息

7

*ms_objecter

用来处理OSD和Objecter之间的消息

对应代码在ceph_osd.cc中

-------------------------------------------------------------------------------------------------------

-HeartBeatMessenger

在ceph守护进程启动过程中(ceph-osd.cc),创建了4个messenger用于心跳检测。

在ceph守护进程创建osd的时候将这些messenger传给了osd, 注意这些messenger在osd中被重命名了。

重命名为了:

hb_front_client_messenger

hb_back_client_messenger

hb_front_server_messenger

hb_back_server_messenger

---------------------------------------------------------------------------------------------------

编号

Dispatcher实例名称

作用

1

*OSD

可以处理部分osd节点的消息

2

*heartbeat_dispatcher

处理心跳连接

对应代码在osd.cc中

-------------------------------------------------------------------------------------------------------

  hb_front_client_messenger->add_dispatcher_head(&heartbeat_dispatcher);

  hb_back_client_messenger->add_dispatcher_head(&heartbeat_dispatcher);

  hb_front_server_messenger->add_dispatcher_head(&heartbeat_dispatcher);

  hb_back_server_messenger->add_dispatcher_head(&heartbeat_dispatcher);

-------------------------------------------------------------------------------------------------------

posted on 2022-10-04 01:24  bdy  阅读(107)  评论(0编辑  收藏  举报

导航