共计 2529 个字符,预计需要花费 7 分钟才能阅读完成。
由于 Ceph 的历史很久,网络没有采用现在常用的事件驱动(epoll)的模型,而是采用了与 MySQL 类似的多线程模型,每个连接 (socket) 有一个读线程,不断从 socket 读取,一个写线程,负责将数据写到 socket。多线程实现简单,但并发性能就不敢恭维了。
Messenger 是网络模块的核心数据结构,负责接收 / 发送消息。OSD 主要有两个 Messenger:ms_public 处于与客户端的消息,ms_cluster 处理与其它 OSD 的消息。
数据结构
网络模块的核心是 SimpleMessager:
(1)它包含一个 Accepter 对象,它会创建一个单独的线程,用于接收新的连接(Pipe)。
void *Accepter::entry()
{
...
int sd = ::accept(listen_sd, (sockaddr*)&addr.ss_addr(), &slen);
if (sd >= 0) {
errors = 0;
ldout(msgr->cct,10) << "accepted incoming on sd" << sd << dendl;
msgr->add_accept_pipe(sd);
...
// 创建新的 Pipe
Pipe *SimpleMessenger::add_accept_pipe(int sd)
{lock.Lock();
Pipe *p = new Pipe(this, Pipe::STATE_ACCEPTING, NULL);
p->sd = sd;
p->pipe_lock.Lock();
p->start_reader();
p->pipe_lock.Unlock();
pipes.insert(p);
accepting_pipes.insert(p);
lock.Unlock();
return p;
}
(2)包含所有的连接对象(Pipe),每个连接 Pipe 有一个读线程 / 写线程。读线程负责从 socket 读取数据,然后放消息放到 DispatchQueue 分发队列。写线程负责从发送队列取出 Message,然后写到 socket。
class Pipe : public RefCountedObject {
/**
* The Reader thread handles all reads off the socket -- not just
* Messages, but also acks and other protocol bits (excepting startup,
* when the Writer does a couple of reads).
* All the work is implemented in Pipe itself, of course.
*/
class Reader : public Thread {
Pipe *pipe;
public:
Reader(Pipe *p) : pipe(p) {}
void *entry() { pipe->reader(); return 0; }
} reader_thread; /// 读线程
friend class Reader;
/**
* The Writer thread handles all writes to the socket (after startup).
* All the work is implemented in Pipe itself, of course.
*/
class Writer : public Thread {
Pipe *pipe;
public:
Writer(Pipe *p) : pipe(p) {}
void *entry() { pipe->writer(); return 0; }
} writer_thread; /// 写线程
friend class Writer;
...
/// 发送队列
map<int, list<Message*> > out_q; // priority queue for outbound msgs
DispatchQueue *in_q; /// 接收队列
(3)包含一个分发队列 DispatchQueue,分发队列有一个专门的分发线程(DispatchThread),将消息分发给 Dispatcher(OSD)完成具体逻辑处理。
消息的接收
接收流程如下:Pipe 的读线程从 socket 读取 Message,然后放入接收队列,再由分发线程取出 Message 交给 Dispatcher 处理。
消息的发送
发送流程如下:
其它资料
这篇文章解析 Ceph: 网络层的处理简单介绍了一下 Ceph 的网络,但对 Pipe 与 Connection 的关系描述似乎不太准确,Pipe 是对 socket 的封装,Connection 更加上层、抽象。
在 CentOS 7.1 上安装分布式存储系统 Ceph http://www.linuxidc.com/Linux/2015-08/120990.htm
Ceph 环境配置文档 PDF http://www.linuxidc.com/Linux/2013-05/85212.htm
CentOS 6.3 上部署 Ceph http://www.linuxidc.com/Linux/2013-05/85213.htm
Ceph 的安装过程 http://www.linuxidc.com/Linux/2013-05/85210.htm
HOWTO Install Ceph On FC12, FC 上安装 Ceph 分布式文件系统 http://www.linuxidc.com/Linux/2013-05/85209.htm
Ceph 文件系统安装 http://www.linuxidc.com/Linux/2013-05/85208.htm
CentOS 6.2 64 位上安装 Ceph 0.47.2 http://www.linuxidc.com/Linux/2013-05/85206.htm
Ubuntu 12.04 Ceph 分布式文件系统 http://www.linuxidc.com/Linux/2013-04/82588.htm
Fedora 14 上安装 Ceph 0.24 http://www.linuxidc.com/Linux/2011-01/31580.htm
Ceph 的详细介绍:请点这里
Ceph 的下载地址:请点这里
本文永久更新链接地址:http://www.linuxidc.com/Linux/2015-10/124549.htm