redis服务器模型分析
2016-03-10 16:05
218 查看
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
下图是整个服务器模型原理图。
首先我们来说明下整个服务器初始化的过程:
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
相关文章推荐
- Redis 到底有多快[译文]
- redis cluster jedis client 示例
- redis与spring的完全集成
- redis中各种数据类型对应的jedis操作命令
- Windows下安装并设置Redis
- 几款开源的图形化Redis客户端管理软件
- Jedis 是 Redis 官方首选的 Java 客户端开发包
- redis 五种数据类型的使用场景
- redis-cluster研究和使用
- 基于Jedis实现Redis分片的理解
- Redis分区
- windows下安装redis
- Redis实战系列(1) 运行多个实例以充分发挥多核处理器的能力
- Redis常用命令
- redis 用setbit(bitmap)统计活跃用户
- redis事务中的WATCH
- redis 的两种持久化方式及原理
- redis sharding方案
- 利用Redis的有序集合做购物车商品相关性分析
- Redis五种数据类型介绍