请求/响应协议和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. 第1条:了解Objective-C 语言的起源

    1.OC语言是由Smalltalk演化而来.该语言使用“消息结构” 而 非“函数调用”. 使用“消息结构”的语言,其运行时所执行的代码由运行环境来决定: 编译器不需要关心接收消息的对象是什么类型,只在 ...

  2. P次方数 英雄会 csdn 高校俱乐部

    题目: 一个整数N,|N| >= 2, 如果存在整数x,使得N = x * x * x... (p个x相乘) =x^p,则称N是p次方数,给定32位内的整数N,求最大的P.例如N=5,输出1,N ...

  3. PHP设计模式之:建造者模式

    建造者模式: 将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示的设计模式; 目的: 消除其他对象复杂的创建过程 结构图: 优点: 建造者模式可以很好的将一个对象的实现与相关的“业 ...

  4. 【实习记】2014-08-23网络安全XSS与CSRF总结

        XSS:脚本中的不速之客XSS:跨站脚本(Cross-site scripting)CSRF:冒充用户之手CSRF:跨站请求伪造(Cross-site request forgery) 谷歌搜 ...

  5. jQuery插件综合应用(二)文字为主的页面

    一.介绍 文字内容是每个网站都有的内容,网站在展示文字内容时,总是比图片.视频等富媒体内容要难一些,因为富媒体容易被用户接受.尤其是越多的文字内容越难以被用户通篇的阅读,跳跃式阅读往往是阅读的主要方式 ...

  6. supervisor进程管理

    install :  apt-get install supervisor crete  a  xxxx.conf  file at   /etc/supervisor/conf.d the cont ...

  7. iOS: AFNetworking手动配置(iOS7.1, AF2.2.4)

    一.下载AFNetworking. 二.将AFNetworking-master下的AFNetworking目录拖入到项目中 三.为项目添加Linking to a Library or Framew ...

  8. SQL脚本小笔记

    --表添加字段.说明--- --脚本 alter table 表名 ADD 字段名 FLOAT(类型) NOT NULL Default 0(默认值) EXECUTE sp_addextendedpr ...

  9. python重要的函数代码块

    注意:现在python3.3.5中print打印语句有了新写法: 1. python指定生成随机数 >>> import random >>> >>&g ...

  10. Technology Trader

    zoj2071:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2071 题意:题意一些零件,每一个零件会有一个花费,然后用这 ...