memcache(1)网络模型

来源:互联网 发布:php常用算法有哪些 编辑:程序博客网 时间:2024/06/16 11:42

        上周在公司里面跟同事一起交流了一些memcache的个人看法,后来整理了一下。主要分为:网络线程模型、内存基本结构、LRU结构、hash冲突以及hash乾坤大挪移。

 

memcache为单进程多线程结构,通信框架使用libevent(http://monkey.org/~provos/libevent/,对定时器、管道、socket、中断都进行了统一的管理,功能丰富肯定带来一些性能上面的副作用,代码值得去阅读学习)。

 

1、线程分为两种类型:主线程(接受线程)和工作线程:

    1)主线程负责完成memcache的一些初始化工作之后,启动event_base_loop循环,开始监控接受new connection,接收到new connection之后,主线程通过轮训的方式,将new connection分配到对应的线程中(当然工作线程也是由主线程启动,不然谁来启动工作线程);

    2)工作线程从主线程接受new connection后,将new connection加入到监听队列中,完成后续的所有数据通信工作,例如根据客户端命令set、get、del数据均需要在工作线程完成(工作线程的监听方式也是一个event_base_loop循环);

 

 

2、主线程与工作线程socket传递

主线程分配new connect的方式为:循环法; 

关键代码为:int tid = (last_thread + 1) % settings.num_threads;根据计算值选择对应的工作线程

 

主线程与工作线程在传递socket句柄的时候采用一个conn_queue_item,每个工作线程都对应一个conn_queue来接受主线程分配的conn_queue_item。主线程首先从conn_queue_item空闲列表中获取一个conn_queue_item元素,填充相应的信息存放到工作线程的消息队列中,然后用管道工作线程去处理新的连接。

关键代码为:

1)从空闲链表中获取空元素

if (cqi_freelist) { item = cqi_freelist; cqi_freelist = item->next; }else{

new cqi_freelist

}

2)添加到工作线程队列、管道通知

if (NULL == cq->tail) cq->head = item;else cq->tail->next = item;

write(pipefd)

3)工作线程处理新连接

item = cq->head;if (NULL != item) { cq->head = item->next; if (NULL == cq->head) cq->tail = NULL;}

 

free(item)

 

 

 

 


新连接分配处理流程图

 

原创粉丝点击