redis服务器模型分析

redis的服务器程序采用的是单进程,单线程的模型来处理客户端的请求。对读写等事件的响应是通过对epoll函数的包装来做到的。
下图是整个服务器模型原理图。



首先我们来说明下整个服务器初始化的过程:
1.初始化asEventLoop。
2.初始化服务器socket监听,并且绑定acceptTcpHandler事件函数,以应对建立客户端连接的请求。
3.绑定beforesleep函数到eventLoop,并且调用aeMain来启动epoll主循环。
4.主循环响应客户端要求建立连接的请求。
5.主循环读取客户端命令,并执行。
6.如有数据回写则初始化化writeEvent,将数据提交到c-replay队列。主循环需要处理此事件的时候则读取数据写回客户端。


由此可见redis的实际实际处理速度完全依靠主循环的执行效率。假如同时有多个客户端并发访问服务器,则服务器处理能力在一定情况下将会下降,下面用实际的测试过程来说明。

由于我的测试数据是在模拟器下的虚拟机中的出来的,所以没有实际的生产环境参考价值,只是用来说明模型与并发处理能力之间的关系。

先看下客户端连接数分别为1,10,50,横坐标为客户端并发线程数,纵坐标为服务端实际吞吐量大小。



再来看下响应时间



由此可见:
1.当服务端并发连接客户端越多,它的实际吞吐量是呈下降趋势。
2.除去1个连接的时候由于客户端并发线程竞争1个连接资源的开销外,其他情况下,服务端响应客户端时间均比较稳定。

结论:
1.由于服务器采用单进程单线程的模型,服务器实际响应客户请求其实是先来后到的串行模式,只要服务器算法OK,那么单个请求响应时间绝对OK。
2.假如你要提升服务器的并发能力,那么可以采用在单台机器部署多个redis进程的方式。

redis采用自己实现的事件分离器,效率比较高,内部采用非阻塞的执行方式,吞吐能力比较大。

不过,因为一般的内存操作都是简单存取操作,线程占用时间相对较短,主要问题在io上,因此,redis这种模型是合适的,但是如果某一个线程出现问题导致线程占用很长时间,那么reids的单线程模型效率可想而知.

引自网络:

总体来说快速的原因如下: 
1)绝大部分请求是纯粹的内存操作(非常快速) 
2)采用单线程,避免了不必要的上下文切换和竞争条件 
3)非阻塞IO 
内部实现采用epoll,采用了epoll+自己实现的简单的事件框架。epoll中的读、写、关闭、连接都转化成了事件,然后利用epoll的多路复用特性,绝不在io上浪费一点时间 

这3个条件不是相互独立的,特别是第一条,如果请求都是耗时的,采用单线程吞吐量及性能可想而知了。应该说redis为特殊的场景选择了合适的技术方案。

http://my.oschina.net/zhenglingfei/blog/409925

猜你喜欢

转载自m635674608.iteye.com/blog/2284832
今日推荐