流水线功能的目的:通过减少客户端与服务器之间的通信次数来提高程序的执行效率

一、通信

在一般情况下, 用户每执行一个 Redis 命令,客户端与服务器都需要进行一次通信:客户端会将命令请求发送给服务器,而服务器则会将执行命令所得的结果返回给客户端。

当程序执行一些复杂的操作时, 客户端可能需要执行多个命令, 并与服务器进行多次通信。

假设我们正在构建一个为图书打标签(tag)的网站,这个网站上的每本图书都可以被打上任意多个标签。并且为了记录哪些标签的图书是最多人阅览的,我们会为每个标签创建一个点击计数器,每当用户浏览网站上的某本书时,程序就会对该书拥有的各个标签的点击计数器执行增一操作。
举个例子,对于《Redis in Action》这本书,用户可能会给它打上“计算机”、“编程”、“数据库”和“Redis”这四个标签,每次当《Redis in Action》的页面被访问时,程序就会对这四个标签的点击计数器执行增一操作:

  1. INCR tag::计算机::click_counter
  2. INCR tag::编程::click_counter
  3. INCR tag::数据库::click_counter
  4. INCR tag::Redis::click_counter

对于这个点击计数程序来说,客户端要执行的 INCR 命令次数取决于书本的标签数量,而标签的数量越多, 要执行的 INCR 命令就越多。
下图展示了《Redis in Action》的页面被查看时,客户端和服务器之间进行的通信情况。

因为 Redis 服务器的性能非常高,所以当一个命令请求抵达服务器之后,服务器通常很快就会将命令执行完毕,并向客户端返回命令的执行结果。
在多数情况下,客户端在执行 Redis 命令时,大部分等待时间都耗费在了发送命令请求和接收命令回复上面。

二、流水线功能

对于前面展示的点击计数器这种需要执行多个命令的程序来说, 如果我们能减少程序执行时, 客户端与服务器之间的通信次数, 就能够有效地提升程序的性能, 而 Redis 的流水线功能(pipeline)就是为此而设置的。
Redis 的流水线功能允许客户端一次将多个命令请求发送给服务器, 并将被执行的多个命令请求的结果在一个命令回复中全部返回给客户端, 使用这个功能可以有效地减少客户端在执行多个命令时需要与服务器进行通信的次数。

以前面列出的点击计数器为例, 我们可以将多条 INCR 命令都包裹到一个流水线里面执行, 使得程序在执行 N 个 INCR 命令时所需的通信次数从 N 次降低为一次。
下图展示了流水线功能是如何将更新《Redis in Action》各个标签的点击计数器所需的通信次数从四次降低为一次的。

三、Python 客户端中的流水线功能

各个 Redis 客户端使用流水线功能的方法都不一样, 以下代码展示了在使用 Python 客户端的情况下, 开启流水线功能来更新《Redis in Action》各个标签的点击计数器的方法:

  1. from redis import Redis
  2. # 创建 Redis 客户端
  3. client = Redis()
  4. # 创建一个流水线对象,包裹四个 INCR 命令
  5. # transaction=False 表示关闭事务功能,只使用流水线功能
  6. # 关于事务方面的详细信息我们稍后就会介绍
  7. pipeline = client.pipeline(transaction=False)
  8. pipeline.incr('tag::计算机::click_counter')
  9. pipeline.incr('tag::编程::click_counter')
  10. pipeline.incr('tag::数据库::click_counter')
  11. pipeline.incr('tag::Redis::click_counter')
  12. # 以流水线形式发送被包裹的四个命令
  13. pipeline.execute()

以流水线方式执行的多个命令的结果会在一个命令回复中被返回, 以下是上面的计数器更新代码的执行结果:

  1. # 多个命令的结果会以列表的形式返回
  2. # 列表的第一个项 10087 是 tag::计算机::click_counter 的值
  3. # 第二个项 5001 是 tag::编程::click_counter 的值
  4. # 第三个项 3421 是 tag::数据库::click_counter 的值
  5. # 第四个项 1001 是 tag::Redis::click_counter 的值
  6. [10087, 5001, 3421, 1001]

四、小结

在一般情况下,用户每执行一个 Redis 命令,客户端和服务器都需要进行一次通信:客户端向服务器发送命令请求,而服务器则会将执行命令所得的命令回复返回给客户端;
在大多数情况下, 执行命令时的绝大部分时间都耗费在了发送命令和接收回复的过程上,因此减少客户端与服务器之间的通信次数,可以有效地提高程序的执行效率;
流水线可以将多条命令打包一起发送,并且在一次回复中接收所有被执行命令的结果,使用这个功能可以有效地提升程序在执行多条命令时的效率;

Redis附加功能之Redis流水线pipeline的更多相关文章

  1. Redis附加功能之Redis事务

    一.事务 Redis 的事务功能允许用户将多个命令包裹起来,然后一次性地.按顺序地执行被包裹的所有命令.在事务执行的过程中,服务器不会中断事务而改去执行其他命令请求,只有在事务包裹的所有命令都被执行完 ...

  2. Redis附加功能之键过期功能

    一.键过期功能的相关命令 二.设置生存时间 Redis 提供了两个命令来设置键的生存时间(TTL,time to live),它们分别是: 如果给定的键不存在,那么 EXPIRE 和 PEXPIRE ...

  3. Redis(三)Redis附加功能

    一.慢查询分析 许多存储系统(例如MySql)提供慢查询日志帮助开发和运维人员定位系统存在的慢操作. 所谓慢查询日志就是系统在命令执行前后计算每条命令的执行时间,当超过预设阈值,就将这条命令的相关信息 ...

  4. 【redis 学习系列08】Redis小功能大用处02 Pipeline、事务与Lua

    3.Pipeline 3.1 Pipeline概念 Redis客户端执行一条命令分为如下四个过程: (1)发送命令 (2)命令排队 (3)命令执行 (4)返回结果 其中(1)和(4)称为Round T ...

  5. 【redis 学习系列07】Redis小功能大用处01 慢查询分析以及Redis Shell

    Redis提供了5种数据结构已经足够强大,但除此之外,Redis还提供了诸如慢查询分析.功能强大的Redis Shell.Pipeline.事务与Lua脚本.Bitmaps.HyperLogLog.发 ...

  6. 3.Redis高级功能

    3.Redis高级功能3.1 慢查询分析3.1.1 慢查询的两个配置参数3.1.2 最佳实践3.1.3 单线程架构3.2 Redis Shell3.2.1 redis-cli 详解3.2.2 redi ...

  7. Redis学习笔记7--Redis管道(pipeline)

    redis是一个cs模式的tcp server,使用和http类似的请求响应协议.一个client可以通过一个socket连接发起多个请求命令.每个请求命令发出后client通常会阻塞并等待redis ...

  8. 就publish/subscribe功能看redis集群模式下的队列技术(一)

    Redis 简介 Redis 是完全开源免费的,是一个高性能的key-value数据库. Redis 与其他 key - value 缓存产品有以下三个特点: Redis支持数据的持久化,可以将内存中 ...

  9. (3)redis队列功能

    Redis队列功能介绍 List 常用命令: Blpop删除,并获得该列表中的第一元素,或阻塞,直到有一个可用 Brpop删除,并获得该列表中的最后一个元素,或阻塞,直到有一个可用 Brpoplpus ...

随机推荐

  1. js Number越界比较.

    Javascript number超过16位就无法比较了,所以自己写了一个. 用到的数组函数 1.Array.reverse() 方法将一个 Array 对象中的元素位置进行反转.在执行过程中,这个方 ...

  2. 【Java安装】Centos6.8 安装Java1.6

    安装java 1.6 Centos6.8安装完成后,一般都安装了java,为了安装java1.6,需要卸载系统自带的java,主要步骤: 先安装java1.6,目的:为了防止先卸载系统自带java时, ...

  3. php require和include区别

    require的使用方法如:require("myfile.php"),这个语句通常放在PHP脚本程序的最前面.PHP程序在执行前,就会先读入require()语句所引入的文件,使 ...

  4. KindEditor得不到textarea值的解决方法----摘至天涯

    以前有朋友遇到过这个问题,就是KindEditor在火狐下或者其他浏览器下都无法得到textarea文本框的值,点击表单提交按钮得到的是空白.昨天天涯PHP博客[http://blog.phpha.c ...

  5. poj1160 post office

    题目大意:有n个乡村,现在要建立m个邮局,邮局只能建在乡村里.现在要使每个乡村到离它最近的邮局距离的总和尽量小,求这个最小距离和. n<300,p<30,乡村的位置不超过10000. 分析 ...

  6. 使用NSOperation使用,创建线程中传递多个参数

    参考:http://blog.csdn.net/dqjyong/article/details/7677557 参考:http://stackoverflow.com/questions/232761 ...

  7. Titan-红号楼宗谱案例

    一. 简介 titan:存储,查询图形结构的数据库.分布式集群环境下,可支持数以千亿级别的点和边,同时支持上千个并发的实时的复杂图形遍历,支持ACID事务. 架构:支持以下3方面的自由组合 (1)节点 ...

  8. jstl标签库基础教程及其使用代码

    概述 在 JSP 页面中,使用标签库代替传统的 Java 片段语言来实现页面的显示逻辑已经不是新技术了,然而,由自定义标签很容易造成重复定义和非标准的实现.鉴于此,出现了 JSTL ( JSP Sta ...

  9. PLSQL_性能优化工具系列09_SQL Plan Management

    2014-09-24 Created By BaoXinjian

  10. 把centos 的mysql 重装一下 把原来的lnmp删除,怎么备份还原数据库

    mysqldump --lock-all-tables -u root -p --databases mydb > /opt/database/mydb.sql,或者直接备份mysql的数据存储 ...