在介绍ceph的读写流程时,我们流程的开始于OSD::_ms_dispatcher,这个函数的意义表示,osd拿到了消息,并要根据不同的表示对消息进行dispatcher,那么消息究竟是如何来的,这个之前没有进行任何介绍,本章主要就是对此进行梳理。本文引用参考了《解析ceph:网络层的处理》这篇文章。
现在大多的网络编程中,都会使用基于事件通知的异步网络IO方式来实现,比如Epoll和Kqueue。Ceph项目开始的比较早,使用的是poll。在终端采用了两个读写线程pipe:: reader_thread和pipe::writer_thread来处理读写事件。读线程在得到请求后会解析网络流并重构消息,然后派发给后端的dispatcher队列,后端的dispatcher线程负责将队列中的消息进行分发。写线程等到有模块调用send_message时会被wakeup然后处理。
Ceph在目前的网络层面上有三个重要概念,分别是 Messenger,Pipe,Connection。Messenger实际上可以理解为一个监听地址和多个连接的集合。比如每个OSD 中会有cluster_messenger 和public_messenger,顾名思义cluster_messenger 负责给OSD 与其他OSD 和Monitor 的通信并提供了一个监听地址,public_messenger负责与客户端的通信并提供了一个面向客户端的监听地址。因此cluster_messenger 中负责的连接会全部是面向其他OSD 或者Monitor 的连接。Pipe实际上是一个 Session 的载体,为了解决网络连接不稳定或者临时闪断连接的问题,Pipe会一直维护面向一个终端地址的会话状态,如类似 TCP 包序号的消息序号和发送队列。Connection 就是一个 socket 的