Redis是一个CS结构的TCP服务器,使用”请求-应答”的模式。,客户端发起一个请求是这样的步骤:

  • 客户端发送一个请求给服务器,然后等待服务器的响应,一般客户端使用阻塞模式来等待服务器响应。
  • 服务器收到请求并处理完毕后,发送结果给客户端。

  举个例子,发送下面4个命令大概就是这样的顺序:

  • 客户端发送: INCR X
  • 服务器响应: 1
  • 客户端发送: INCR X
  • 服务器响应: 2
  • 客户端发送: INCR X
  • 服务器响应: 3
  • 客户端发送: INCR X
  • 服务器响应: 4

  客户端和服务器通过网络连接,网速可以非常快, 也可以非常慢。不管是快还是慢,消息包从客户端到服务器,再从服务器返回到客户端,总是要需要时间的。这个时间被称之为RTT(Round Trip Time,往返延时)。显然,当客户端需要发送多条请求时(比如往一个list中加很多元素,或者往一个数据库中填充很多keys),这个往返延时会影响到性能。假设网络非常慢,往返延时达到250毫秒,就算服务器每秒可以处理10万个请求,客户端也只能每秒处理4个请求。就算使用环回接口,往返延时非常小,如果需要执行很多写的操作, 也是要浪费许多时间的。

  幸好我们有办法改进这种情况。

Redis Pipelining

“请求-响应”模式的服务器在处理完一个请求后就开始处理下一个请求,不管客户端是否读取到前一个请求的响应结果。这让客户端不需要发一个请求等一个响应的串行,可以一次发送多个请求,再最后一次性读取所有响应。这就叫pipelining(管道化),这种技术几十年来广泛的使用。比如很多POP3协议支持这个特性,大大的加速了从服务器上下载新邮件的速度。

Redis在很早的版本就支持pipeling,所以无论你用的是什么版本的redis,都可以用pipelining。下面是一个使用netcat的演示例子:

$ (printf "PING\r\nPING\r\nPING\r\n"; sleep 1) | nc localhost 6379
+PONG
+PONG
+PONG

  我们的第一个例子,如果使用pipeline,客户端的请求和服务器的响应顺序就是如下:

  • 客户端发送: INCR X
  • 客户端发送: INCR X
  • 客户端发送: INCR X
  • 客户端发送: INCR X
  • 服务器响应: 1
  • 服务器响应: 2
  • 服务器响应: 3
  • 服务器响应: 4

  注意:当客户端使用pipelining发送很多请求时,服务器将在内存中使用队列存储这些指令的响应。所以批量发送的指令数量,最好在一个合理的范围内,比如每次发1万条指令,读取完响应后再发送另外1万条指令。2万条指令,一次性发送和分2次发送,对客户端来说速度是差不多的,但是对服务器来说,内存占用差了1万条响应的大小。

性能测试

  下面是我们用Redis Ruby客户端测试使用pipelining带来的性能改进:

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
       }
   }
end bench("without pipelining") {
   without_pipelining
}
bench("with pipelining") {
   with_pipelining
}

在我的Mac OS X系统中运行上面的脚本,由于使用环回接口往返延时非常小,这样pipeling带来的优化非常小。可以得到下面的结果:

without pipelining 1.185238 seconds
with pipelining 0.250783 seconds

  从结果可以看到,使用pipelining技术,我们的传输速度提高了5倍。

管道化 VS 脚本

大部分使用pipelining的情况都可以用Redis脚本(2.6或高于2.6的版本才支持)来代替,使之更高效的在服务器端执行。使用脚本的最大好处是,在最小的延迟下可以读和写,比如可以:让“读,计算,写”这样一个流程非常快(pipeling不能处理这种情景,因为客户端需要得到响应之后才能计算和写)。有时候,应用程序可能需要在一个pipeline中发送多个EVAL或EVALSHA指令,redis的SCRITP LOAD指令能很好的满足这种需求(它保证了EVALSHA不会有调用失败的风险)。

Redis 请求应答模式和往返延时 Pipelining的更多相关文章

  1. 网络io模式(服务器请求应答模式)

    2014年1月19日 22:07:41 这几天看nginx 和 Apache的视频教程(马哥和邹老师)了解到了一些网络io模式(nginx的相关配置项为sendfile) 这里简单记录下来以备后用 A ...

  2. WCF服务创建与使用(请求应答模式)

    不说废话,直接上代码.以下服务创建是在独立的WCF类库中,若采用WCF应程程序,定义及创建服务代码均相同,但文件名不同,是CalculatorService.svc 第一步,定义服务契约(Servic ...

  3. [老老实实学WCF] 第九篇 消息通信模式(上) 请求应答与单向

    老老实实学WCF 第九篇 消息通信模式(上) 请求应答与单向 通过前两篇的学习,我们了解了服务模型的一些特性如会话和实例化,今天我们来进一步学习服务模型的另一个重要特性:消息通信模式. WCF的服务端 ...

  4. WCF分布式开发步步为赢(10):请求应答(Request-Reply)、单向操作(One-Way)、回调操作(Call Back).

    WCF除了支持经典的请求应答(Request-Reply)模式外,还提供了什么操作调用模式,他们有什么不同以及我们如何在开发中使用这些操作调用模式.今天本节文章里会详细介绍.WCF分布式开发步步为赢( ...

  5. activeMQ的request-response请求响应模式

    一:为什么需要请求响应模式 在消息中间中,生产者只负责生产消息,而消费者只负责消费消息,两者并无直接的关联.但是如果生产者想要知道消费者有没有消费完,或者用不用重新发送的时候,这时就要用到请求响应模式 ...

  6. 理解Redis的反应堆模式

    1. Redis的网络模型 Redis基于Reactor模式(反应堆模式)开发了自己的网络模型,形成了一个完备的基于IO复用的事件驱动服务器,但是不由得浮现几个问题: 为什么要使用Reactor模式呢 ...

  7. 7.redis 集群模式的工作原理能说一下么?在集群模式下,redis 的 key 是如何寻址的?分布式寻址都有哪些算法?了解一致性 hash 算法吗?

    作者:中华石杉 面试题 redis 集群模式的工作原理能说一下么?在集群模式下,redis 的 key 是如何寻址的?分布式寻址都有哪些算法?了解一致性 hash 算法吗? 面试官心理分析 在前几年, ...

  8. 突破Java面试-Redis集群模式的原理

    1 面试题 Redis集群模式的工作原理说一下?在集群模式下,key是如何寻址的?寻址都有哪些算法?了解一致性hash吗? 2 考点分析 Redis不断在发展-Redis cluster集群模式,可以 ...

  9. [WCF编程]10.操作:请求/应答操作

    一.调用操作概述 WCF除了支持经典的服务端-客户端的请求/应答操作外,还提供了对其他操作类型的内建支持,包括:即发即弃的单向调用:允许服务将调用返回给客户端的双向回调:允许客户端或服务器处理大量负荷 ...

随机推荐

  1. 20155203 《信息安全技术》 实验2 Windows口令破解

    实验目的 了解Windows口令破解原理 对信息安全有直观感性认识 能够运用工具实现口令破解 系统环境 Windows 实验工具 LC5 SuperDic(密码字典生成器) 实验原理 口令破解方法 口 ...

  2. 2016-2017-20155329 《Java程序设计》第十周学习总结

    学号 2016-2017-20155329 <Java程序设计>第十周学习总结 教材学习内容总结 学习目标 了解计算机网络基础 OSI分层(7层):物理层.数据链路层.网络层.传输层.会话 ...

  3. # 2017-2018-1 20155336《信息安全技术》实验二——Windows口令破解

    2017-2018-1 20155336<信息安全技术>实验二——Windows口令破解 实验原理 口令破解方法 口令破解主要有两种方法:字典破解和暴力破解. 字典破解是指通过破解者对管理 ...

  4. 20155339 《信息安全技术》实验二、Windows口令破解实验报告

    20155339 <信息安全技术>实验二.Windows口令破解实验报告 实验目的 了解Windows口令破解原理 对信息安全有直观感性认识 能够运用工具实现口令破解 系统环境 Windo ...

  5. 20145209 2016-2017-2 《Java程序设计》课程总结

    20145209 2016-2017-2 <Java程序设计>课程总结 每周作业链接汇总 预备作业01 http://www.cnblogs.com/liuyiyang/p/6194319 ...

  6. 关于快速沃尔什变换(FWT)的一些个人理解

    定义 FWT是一种快速完成集合卷积运算的算法. 它可以用于求解类似 $C[i]=\sum\limits_{j⊗k=i}A[j]*B[k]$ 的问题. 其中⊗代表位运算中的|,&,^的其中一种. ...

  7. dotnet core在Task中使用依赖注入的Service/EFContext

    C#:在Task中使用依赖注入的Service/EFContext dotnet core时代,依赖注入基本已经成为标配了,这就不多说了. 前几天在做某个功能的时候遇到在Task中使用EF DbCon ...

  8. spring源码-aop增强-5.2

    一.aop增强就是针对于不同的切面进行的相关增强,目的当然是更好的支持相关应用和解耦. 二.默认的aop增强类有AspectJMethodBeforeAdvice.AspectJMethodBefor ...

  9. 有关Laravel 4 的 Homestead 安装部署的细节

    对于Vagrant,我是相见恨晚的.有时候抽出几个小时的时间学会一种工具,对于将来可以节省几十甚至几百小时的时间. Vagant最大的好处就是节省了安装配置运行环境的时间,统一开发环境,同时可以最大限 ...

  10. swift实现UItableview上拉下拉刷新模块

    最近用写个项目 发现上拉下拉刷新模块没找到合适的 so 自己写了一个 由于最近忙 教程就不写了 里面有 直接贴地址https://github.com/DaChengTechnology/DCRefr ...