深入分析Memcached的线程接入模型---上

来源:互联网 发布:软件开发题库 编辑:程序博客网 时间:2024/06/05 02:48

memcached是一个分布式的内存cache系统,目前被大量地运用于各种各样的站点中,以不断提高站点的总体访问性能,而另外一方面,memcached的使用是非常简单的,可以说,使用门槛很低,这也许是造成memcached目前非常流行的原因之一。

 

我们可以看到,网上分析memcached的文章也比较多,本文是笔者结合memcached源代码的基础上对其线程接入模型进行深入的分析,通过学习和借鉴memcached设计和实现上 的一些思想,为我们的系统架构设计增添新的思路。

 

简单的说,memcached的实现并没有使用多进程模型,而是选择了多线程的模型,可以说,这种实现的方案确实是比较轻量级的。而多线程是基于libevent的事件机制以及基于管道pipe的信令周知机制来实现的。

 

主线程main_thread完成了系统的初始化和生成指定数量的worker_thread后,自身转化为一个dispatch_thread,负责系统的监听和转发,main_thread有自身的event_base 实例,该实例负责监听socket是否有连接到来,如果有,则获取一个新的连接socket并且封装成一个CQ_ITEM对象放入其中某个worker_threadCQ队列中,以此同时,往该worker_threadnotify pipe写入一个字节以周知该worker_thread已经有新的CQ_ITME到,可以进行处理了。

 

每个worker_thread都有自己的一个CQ队列,该队列存放已经建立连接的各个连接对象,worker_thread正是不断地从各自的CQ队列里面取得各个连接对象进行处理的。同时,worker_thread也有各自的event_base实例用于出来各自的socket读写等操作以及有一对用于信令周知的读写pipe

 

下面是简单的main_threadworker_thread示意图:

 

 

 

  

下面结合源代码(memcached-1.4.4)进行分析,首页看一下关键的数据结构定义。

 

一,存放到每个worker_thread连接队列和连接item的定义

 

 

CQ_ITEM实例就是main_thread accept一个连接socket后的封装。

 

 

CQ是每个worker_thread存放的已经建立的连接队列,每个worker_thread正是不断的通过读取自己的连接队列的CQ_ITEM进行处理的。

 

二,其实memcached对每个worker_thread也是进行封装成相应的结构体的

为了便于对worker_thread进行处理,memcacheworker_thread进行重新封装,结构体如下:

 

      

 

下面是对main_thread作为一个dispatch_thread的封装:

 

 

 

介绍完主要的数据结构后(当然还有其他重要的数据结构,但跟我们本文要介绍的线程部分联系不是特别紧密,这里暂不扩展介绍了),下面重点介绍各个关键流程。

 

 

原创粉丝点击