请求/响应协议和RTT

Redis是一个使用客户端/服务器模型(也被称作请求/响应协议)的TCP服务器。

这说明通常来讲一个一个请求的实现有以下步骤:

  • 客户端发送请求到服务器,并从socket中以堵塞的方式读取服务器的响应数据。
  • 服务器对发动的命令进行处理并把响应数据发回客户端。

比如发送连续四个命令就会像这样:

  • 客户端: INCR X
  • 服务端: 1
  • 客户端: INCR X
  • 服务端: 2
  • 客户端: INCR X
  • 服务端: 3
  • 客户端: INCR X
  • 服务端: 4

客户端和服务端通过网络连接。这个连接可能非常快(本地回环接口)也可能非常慢(互联网上相隔很多跳数的两台主机)。不论网络延迟是多少,数据包从客户端发到服务端并从服务端返回客户端都有一个时间。

这个时间被称作环路时间。显而易见,当客户端需要一次发送很多请求时(比如一次向一个List添加很多元素,或者向一个数据库添加很多Key),这个环路时间会对性能造成非常大的影响。如果环路时间是250毫秒(在网络连接非常慢的情况下),即使服务端能每秒处理10万个请求,我们一秒最大也只能处理四个请求。

即使我们用的是本地回环接口,本地环路时间会短得多(比如在我本机上用ping测试是0.044毫秒),但是如果你要一次进行大量写操作,这个时间依然不少。

幸运的是我们有一种方法来优化这种使用场景。

Redis管道

一个请求/响应服务器能够做到在客户端还没有读取上个返回值的时候就处理新的请求。通过这种方式客户端就可以在不获取每次请求的响应的情况下给服务端一次发送多个命令,并在未来的某个时间一次获得这些所有的响应。

这就叫做管道,这种技术早在多年前就被广泛应用。比如很多POP3协议的实现方案就支持管道,极大的提高了从服务器上下载新邮件的速度

Redis在很早的时候就支持管道,所以无论你现在用的是什么版本,你都可以在Redis中使用管道。以下是一个使用原生netcat工具的例子:

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

这次我们不在每次调用都产生RTT的花销,所有命令加起来只产生一次RTT花销。

To be very explicit, with pipelining the order of operations of our very first example will be the following:

为了显示清楚,第一个例子中我们进行操作如果使用管道就会以下面的顺序执行:

  • 客户端: INCR X
  • 客户端: INCR X
  • 客户端: INCR X
  • 客户端: INCR X
  • 服务端: 1
  • 服务端: 2
  • 服务端: 3
  • 服务端: 4

务必要注意:当客户端使用管道发送多条命令时,服务端会把所有的响应都放入队列,这会带来额外的内存开销。所以如果你想使用管道来一次发送多条命令,最好给定一合理的个命令数上限值,比如10000条命令,之后读取响应,之后再次发送另外的10000条命令并循环往复。这样请求速度不会有大的改变,但是额外内存的使用量只会相当于缓存这10000条回复所需要的上限值。

一些性能指标

以下的性能检测中我们会用到Redis的Ruby客户端,使用管道,来测试管道对于速度的提升:

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 系统上的性能指标,由于延迟只来源于本地回环接口,RTT时间非常短,管道机制只提供了最小的性能提升:

without pipelining 1.185238 seconds
with pipelining 0.250783 seconds

可以看出使用管道后有了五倍的性能提升。

管道VS脚本

由于脚本执行于服务端,所以使用Redis脚本(可用于Redis2.6或以上版本)可以使某些原本使用管道的场景执行得更有效率。脚本一个很大的优势在于它的读写操作的延迟相当小,因此能使如read, compute, write之类的操作执行的非常快(管道在这个场景下表现就差强人意,因为管道在执行写之前需要先得到读请求的响应和返回值)。

有些时候应用希望可以通过管道发送EVLA或者EVALSHA命令。这也是完全可以做的到的并且Redis通过SCRIPT LOAD命令显式支持这种操作(并保证EVALSHA操作不会执行失败)。

Redis教程02——管道(Pipelining)的更多相关文章

  1. .NET客户端实现Redis中的管道(PipeLine)与事物(Transactions)

    序言 Redis中的管道(PipeLine)特性:简述一下就是,Redis如何从客户端一次发送多个命令,服务端到客户端如何一次性响应多个命令. Redis使用的是客户端-服务器模型和请求/响应协议的T ...

  2. Redis中的管道(PipeLine)与事物(Transactions)

    Redis中的管道(PipeLine)与事物(Transactions) 序言 Redis中的管道(PipeLine)特性:简述一下就是,Redis如何从客户端一次发送多个命令,服务端到客户端如何一次 ...

  3. [译]Vulkan教程(02)概况

    [译]Vulkan教程(02)概况 这是我翻译(https://vulkan-tutorial.com)上的Vulkan教程的第2篇. This chapter will start off with ...

  4. 【redis】pipeline - 管道模型

    redis-pipeline 2020-02-10: 因为我把github相关的wiki删了,所以导致破图...待解决.(讲真github-wiki跟project是2个url,真的不好用) 因为用的 ...

  5. Redis教程——检视阅读

    Redis教程--检视阅读 参考 Redis教程--菜鸟--蓝本--3.2.100 Redis教程--w3c--3.2.100 Redis教程--w3c--Redis开发运维实践指南 Redis教程- ...

  6. redis教程

    windows下安装redis: http://jingyan.baidu.com/article/49ad8bce40174f5834d8fa24.html redis教程: http://www. ...

  7. 【Zigbee技术入门教程-02】一图读懂ZStack协议栈的基本架构和工作机理

    [Zigbee技术入门教程-02]一图读懂ZStack协议栈的基本架构和工作机理 广东职业技术学院  欧浩源  ohy3686@foxmail.com Z-Stack协议栈是一个基于任务轮询方式的操作 ...

  8. phpredis 中文手册和redis 教程

    phpredis 中文手册  :   http://www.cnblogs.com/zcy_soft/archive/2012/09/21/2697006.html 手册: http://www.cn ...

  9. 【Zigbee技术入门教程-02】一图读懂ZStack协议栈的核心思想与工作机理

    [Zigbee技术入门教程-02]一图读懂ZStack协议栈的核心思想与工作机理 广东职业技术学院  欧浩源   Z-Stack协议栈是一个基于任务轮询方式的操作系统,其任务调度和资源分配由操作系统抽 ...

随机推荐

  1. Object-C添加方法

    给实例变量添加getter方法: #import <Cocoa/Cocoa.h> @interface Photo:NSObject { NSString *caption; NSStri ...

  2. 怎样在win7上远程连接linux系统

    window操作系统的电脑 一台安装了linux系统的服务器 putty.exe小软件 方法/步骤   在前面的环境和软件都有的情况下,双击putty.exe软件,如下图:   在软件界面中的:Hos ...

  3. java 反射取得方法入参类型的泛形

    package TestReflectClass; import java.util.List; /** * Created by wangyang on 2016/12/16. */ public ...

  4. IO流基础加强

    字节流对象:InputStream,OutputStream 缓冲字节流对象:BufferedInputStream , BufferedOutputStream 用法和字符流对象一样,但也有区别, ...

  5. go和swift

    你生命中的有些东西终究会失去,比如我住了6年的陈寨,这个聚集了郑州十几万IT民工的地方,说拆就拆了.再比如我玩了3年的坦克英雄,这个带给我太多快乐的游戏,说停就停了. 编程对我而言是种爱好,我上学6年 ...

  6. 学 Android 是一种什么样的体验?

    转眼间 2016 年的电量已不足 20%,不禁感慨 How Time Flies!不知不觉 Android 移动开发已经走过了八年的光阴,在这八年的时间中,Android 开发从最初的简单调用系统 A ...

  7. 获取Ip 的地域等信息接口-实例

    今天项目要用到 查询访问网站用户的IP 然后网上查询了 资料还很多 不过有些已经失效了 在这总结下 腾讯,pconline 的API已经失效 不能使用 淘宝的IP接口地址: http://ip.tao ...

  8. [译]36 Days of Web Testing(二)

    Day 7: Http 和 Https Why? 当在网络上传输一些私人,敏感信息时,应该采用加密的手段来保证这些信息在传输的过程中不被侦测到.Https协议正是这种实现机制. Https是一种广泛使 ...

  9. Objective-C 入门(给新人的)

    http://www.hengxinsoft.com/2010/12/objective-c-%E5%85%A5%E9%97%A8%EF%BC%88%E7%BB%99%E6%96%B0%E4%BA%B ...

  10. [BZOJ 1018] [SHOI2008] 堵塞的交通traffic 【线段树维护联通性】

    题目链接:BZOJ - 1018 题目分析 这道题就说明了刷题少,比赛就容易跪..SDOI Round1 Day2 T3 就是与这道题类似的..然而我并没有做过这道题.. 这道题是线段树维护联通性的经 ...