转载于:http://www.itxuexiwang.com/a/shujukujishu/redis/2016/0216/141.html

一、请求应答协议和RTT:

Redis是一种典型的基于C/S模型的TCP服务器。在客户端与服务器的通讯过程中,通常都是客户端率先发起请求,服务器在接收到请求后执行相应的任务,最后再将获取的数据或处理结果以应答的方式发送给客户端。在此过程中,客户端都会以阻塞的方式等待服务器返回的结果。见如下命令序列:

代码如下:

Client: INCR X
    Server: 1
    Client: INCR X
    Server: 2
    Client: INCR X
    Server: 3
    Client: INCR X
    Server: 4

在每一对请求与应答的过程中,我们都不得不承受网络传输所带来的额外开销。我们通常将这种开销称为RTT(Round Trip Time)。现在我们假设每一次请求与应答的RTT为250毫秒,而我们的服务器可以在一秒内处理100k的数据,可结果则是我们的服务器每秒至多处理4条请求。要想解决这一性能问题,我们该如何进行优化呢?
    
二、管线(pipelining):

Redis在很早的版本中就已经提供了对命令管线的支持。在给出具体解释之前,我们先将上面的同步应答方式的例子改造为基于命令管线的异步应答方式,这样可以让大家有一个更好的感性认识。

代码如下:

Client: INCR X
    Client: INCR X
    Client: INCR X
    Client: INCR X#p#分页标题#e#
    Server: 1
    Server: 2
    Server: 3
    Server: 4

从以上示例可以看出,客户端在发送命令之后,不用立刻等待来自服务器的应答,而是可以继续发送后面的命令。在命令发送完毕后,再一次性的读取之前所有命令的应答。这样便节省了同步方式中RTT的开销。
    最后需要说明的是,如果Redis服务器发现客户端的请求是基于管线的,那么服务器端在接受到请求并处理之后,会将每条命令的应答数据存入队列,之后再发送到客户端。
    
三、Benchmark:

以下是来自Redis官网的测试用例和测试结果。需要说明的是,该测试是基于loopback(127.0.0.1)的,因此RTT所占用的时间相对较少,如果是基于实际网络接口,那么管线机制所带来的性能提升就更为显著了。

代码如下:

require 'rubygems'
    require 'redis'
    
    def bench(descr)
        start = Time.now
        yield
        puts "#{descr} #{Time.now-start} seconds"
    end
    
    def without_pipelining
        r = Redis.new
        10000.times {
            r.ping
        }
    end
    
    def with_pipelining
        r = Redis.new
        r.pipelined {
            10000.times {
                r.ping
            }#p#分页标题#e#
        }
    end
    
    bench("without pipelining") {
        without_pipelining
    }
    bench("with pipelining") {
        with_pipelining
    }
    //without pipelining 1.185238 seconds
    //with pipelining 0.250783 seconds

最新文章

  1. HDU 5908 Abelian Period(暴力+想法题)
  2. JS运动基础(三) 弹性运动
  3. GAE初探-一鼻子灰
  4. 【学习笔记】移动Web手册(PPK力作)
  5. hdu 3415
  6. 运行eclipse提示 The requested resource () is not available.
  7. 【转】FFMPEG 库移植到 VC 需要的步骤
  8. yii2 and short_open_tag
  9. Another Look at Events(再谈Events)
  10. 互联网程序设计c++
  11. js 玩一玩
  12. php中查询mysql如何在IN array中用
  13. MySQL (六)--外键、联合查询、子查询
  14. python3.6安装Scrapy
  15. 【USACO】股票市场
  16. 【XSY1522】灯 乱搞
  17. DataTabe使用Linq实现 Group
  18. spring生命周期流程图
  19. mysql 案例~关于pt-osc工具的用途
  20. Mybatis的多对多映射

热门文章

  1. python核心编程(第二版)习题
  2. 使用extjs6官方模板admin-dashboard
  3. MATLAB 画出三个通信小区cell边界示意图
  4. spring自动装配
  5. 代码规范、GitHub提交源码的标准 答题人-杨宇杰
  6. 【解题报告】BZOJ2550: [Ctsc2004]公式编辑器
  7. Oracle Blob 字段的模糊查询
  8. 几个非常有用的js小函数
  9. 怎样让.bat文件开机自启动
  10. .NET Framework 基础知识总结