那谁的技术博客

感兴趣领域:高性能服务器编程,存储,算法,Linux内核
随笔 - 210, 文章 - 0, 评论 - 1183, 引用 - 0
数据加载中……

memcached采用的网络模型

memcached采用的网络模型是早前提到的半同步半异步的网络模型.

简单的说,大致流程就是:主线程负责接收新的连接,接收到新的连接之后,选择一个worker副线程,将该新连接push到副线程的连接队列中.主副线程之间通过管道进行通讯,因此主线程将新的连接push到工作线程之后,主线程要向该副线程的管道中写一个字符,而每个副线程也都有自己的poll set, 其中会包含自己的管道fd, 副线程也会通过多路复用I/O来监控管道的情况,一旦可读,说明有新的连接到来,此时从连接队列中取出新连接,将其fd加入到自身的poll set中,最后对该连接的业务逻辑处理也全都在该副线程中进行(读数据,处理,发送回应等).

这个模型有以下的好处:
1) 接收操作只在主循环中处理,因此不会出现惊群现象.
2) 主副线程分工明确, 主线程仅负责I/O, 副线程负责业务逻辑处理.我认为这个可以抽象出来作为一般服务器的网络I/O架构, 以后要使用的时候只需要将业务逻辑处理函数传递进行就好了.简单的说,就是主线程负责接客,副线程负责服务.
3) 多个副线程之间不会有影响.因为大家都有各自独立的连接队列.主线程在新连接到来的时候是如何选择处理副线程的呢?很简单,有一个计数器last_thread, 每次将last_thread加一,再模线程数来选择线程ID.

缺点是:
假如业务逻辑是类似于web服务器之类的, 那么一个简单的请求也需要这个比较繁琐的操作的话(最重要的是,很可能一个进程就能处理完的事情,非得从一个线程接收再到另一个线程去处理), 那么显然代价是不值得的.所以说,所谓的服务器网络模型的选择, 其实没有一套通吃的方案, 还是按照具体的业务逻辑具体来分析吧.

需要补充的是,主副线程之间相互通信采用的管道,现在新版的linux内核已经提供一种新的API:eventfd(),简单的说,有以下好处:1)管道需要分配两个fd,一个读一个写,而eventfd一个fd就搞定了. 2) 管道需要不定长的缓冲区,往里面写数据才能通知读一端有数据到来,而eventfd现在可以使用定长的数据了. 3) 最后,听说eventfd性能上比管道要好,这个没有做过测试了.反正, 对于简单的类似上面分析的那样通知机制, 用管道似乎太"重量级"了一点.

eventfd的man page在.




posted on 2010-03-11 20:30 那谁 阅读(13857) 评论(6)  编辑 收藏 引用 所属分类: 服务器设计memcached

评论

# re: memcached采用的网络模型  回复  更多评论   


比喻得好!

# re: memcached采用的网络模型  回复  更多评论   

这个模型。。只能处理各个连接间没有数据交互的情况。。不晓得是不。。请指正
2010-03-12 13:30 | 小阳

# re: memcached采用的网络模型  回复  更多评论   

另外。。这个其实和unp上的多个父子进程一起accept很相似。。只是你接受连接做了个简单的分配。。前者是内核来唤醒的accept..我记得那个大侠说过。。现在Linux貌似已经解决惊群现象了。。。
2010-03-12 13:35 | 小阳

# re: memcached采用的网络模型  回复  更多评论   

@小阳
你的理解是正确的.

2010-03-12 14:02 | 那谁

# re: memcached采用的网络模型  回复  更多评论   

有个疑问:假设主线程负责网络I/O,业务逻辑由线程池(只负责业务)处理,现在某个client连续发送了两个数据包,交给线程池处理,可能会导致乱序,怎么解决这个问题。
2010-06-03 17:24 | JustCodeIT

# re: memcached采用的网络模型  回复  更多评论   

很好的文章,值得分享。
2016-08-12 22:48 | 纽约网站设计

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理