编者注:pipeline是Redis的一个提高吞吐量的机制,适用于多key读写场景,比如同时读取多个key的value,或者更新多个key的value。工作过程中发现挺多小伙伴都对pipeline多少有些了解,但是更深入的理解或者说有哪些坑就不知道了,下面咱们就一起分析下redis pipeline机制,揭开它的神秘面纱。

Redis本身是基于Request/Response协议(停等机制)的,正常情况下,客户端发送一个命令,等待Redis返回结果,Redis接收到命令,处理后响应。在这种情况下,如果同时需要执行大量的命令,那就是等待上一条命令应答后再执行,这中间不仅仅多了RTT(Round Time Trip),而且还频繁调用系统IO,发送网络请求。为了提升效率,这时候pipeline出现了,它允许客户端可以一次发送多条命令,而不等待上一条命令执行的结果,这和网络的Nagel算法有点像(TCP_NODELAY选项)。pipeline不仅减少了RTT,同时也减少了IO调用次数(IO调用涉及到用户态到内核态之间的切换)

要支持Pipeline,其实既要服务端的支持,也要客户端支持。对于服务端来说,所需要的是能够处理一个客户端通过同一个TCP连接发来的多个命令,可以理解为,这里将多个命令切分,和处理单个命令一样(之前老生常谈的黏包现象),Redis就是这样处理的。而客户端,则是要将多个命令缓存起来,缓冲区满了或者达到发送条件就发送出去,最后才处理Redis的应答。


注意:Redis的Pipeline和Transaction(Redis事务)不同,Transaction会存储客户端的命令,最后一次性执行,而Pipeline则是处理一条(批次),响应一条,从二者的不同处理机制来看,Redis事务中命令的执行是原子的(注意,其中一部分命令出现错误后续命令会继续执行,这里的原子说的是命令执行是完整的,中间不会被其他Redis命令所打断),而pipeline中命令的执行不一定是原子的。但是这里却有一点不同,就是pipeline机制中,客户端并不会调用read去读取socket里面的缓冲数据(除非已经发完pipeline中所有命令),这也就造成了,如果Redis应答的数据填满了该接收缓冲(SO_RECVBUF),那么客户端会通过ACK,WIN=0(接收窗口)来控制服务端不能再发送数据,那样子,数据就会缓冲在Redis的客户端应答缓冲区里面。所以需要注意控制Pipeline的大小。如下图:


这里可以设想一下,如果客户端通过ACK,WIN=0(接收窗口)来控制服务端不能再发送数据,那么数据就会堆积在服务端socket发送缓冲区中,如果服务端socket发送缓冲区也满了,那么此时服务端调用write(socket)就会阻塞或者失败。

既然提到了tcp/ip的滑动窗口概念,这里就简单总结下滑动窗口:

滑动窗口在TCP中的作用是提供TCP的可靠性和流控特性,滑动窗口可分为发送窗口和接收窗口,它们分别对应于发送缓冲区和接收缓冲区。发送窗口的大小是根据客户端接收缓冲区的大小而设定的(三次握手的目的是连接服务器指定端口,建立 TCP 连接,并同步连接双方的序列号和确认号,交换 TCP 窗口大小信息)。

发送窗口中包含的内容是已发送但还未收到Ack的数据和未发送但对端允许发送的数据。


TCP接收缓冲区中包含应用为读取数据、已接收数据(已回复ACK)、待接收,其中待接收空间可称为接收窗口。

使用pipeline过程中,要注意控制一次pipeline中的命令总大小,不能使响应结果撑爆socket接收缓冲区。这里我们思考一个问题,还有没有其他方式提高pipeline的处理性能呢?理论上是有的,比如可以使用数据压缩机制,进一步减小数据传输的总大小,不过这需要客户端和服务端提供解压缩机制,同时会耗费一定量服务器CPU。

欢迎小伙伴关注【TopCoder】阅读更多精彩好文。

如何用好redis pipeline的更多相关文章

  1. redis pipeline

    redis pipeline 简而言之就是把多个redis命令打包,一起发送给redis server,并且一起返回结果,减少客户端和服务器之间的多次“折返跑”

  2. 【spring boot】spring boot 基于redis pipeline 管道,批量操作redis命令

    spring boot 2.x 使用RedisTemplate 操作 =================================== 1.pom.xml <!--spring2.0集成r ...

  3. laravel中redis pipeline用法说明

    $res = Redis::pipeline(function($pipe) use($params) { for ($i = 0; $i < 1000; $i++) { $pipe->g ...

  4. redis 学习(11)-- redis pipeline

    redis pipeline 什么是流水线(pipeline) 首先来看 redis 执行一次操作所需要的时间: 1 次时间 = 1 次网络时间 + 1次命令时间 执行 n 次就需要: n 次时间 = ...

  5. 等待 Redis 应答 Redis pipeline It's not just a matter of RTT

    小结: 1.When pipelining is used, many commands are usually read with a single read() system call, and ...

  6. 说说 Redis pipeline

    更多技术文章,请关注我的个人博客 www.immaxfang.com 和小公众号 Max的学习札记. Redis 客户端和服务端之间是采用 TCP 协议进行通信的,是基于 Request/Respon ...

  7. (7)redis pipeline

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

  8. Redis pipeline and list

    Redis Redis 是一个开源的基于内存的数据结构存储器.通常可作为数据库,缓存和消息中介.它支持的数据结构有:字符串.哈希表.列表.集合.支持范围查询的有序集合.位图.hyperloglogs和 ...

  9. Redis Pipeline原理分析

    转载请注明出处:http://www.cnblogs.com/jabnih/ 1. 基本原理 1.1 为什么会出现Pipeline Redis本身是基于Request/Response协议的,正常情况 ...

随机推荐

  1. 百万it资源百度网盘链接分享

    自己大量时间整理的优质资源,容量达3000多G,有需要的朋友可以微我,资源截图:  面试资料: 书籍类: 视频类: 以上只是部分资源,想要资源的亲请加微信咨询. 欢迎加微信咨询,请备注资源: 独乐乐不 ...

  2. asp.net core 使用Mysql和Dapper

    序曲:学习编程最好的方式就是敲代码,没有比这个更好的方法,哪怕你看了上百G的视频,都不如你自己敲几行代码更为有效.还有要记得敲完代码然后写一篇随笔来记录一下你所学所想. 大家都知道,.netcore是 ...

  3. 夯实Java基础系列15:Java注解简介和最佳实践

    Java注解简介 注解如同标签 Java 注解概述 什么是注解? 注解的用处 注解的原理 元注解 JDK里的注解 注解处理器实战 不同类型的注解 类注解 方法注解 参数注解 变量注解 Java注解相关 ...

  4. IDEA 学习笔记之 多线程调试

    多线程调试: 在多线程调试的时候,发现一些断点会被跳过,让人很郁闷,然后上网查了下资料,发现是自己IDEA设置不对. 使用IDEA调试多线程的时候,IDEA的断点有不同的模式,只有当Thread模式下 ...

  5. Java 学习笔记之 实例变量与线程安全

    实例变量与线程安全: 不共享数据: public class NoSharedThread extends Thread { private int count = 5; public NoShare ...

  6. Redis高可用集群方案

    Redis为我们提供了哨兵,它就像一个为我们的Redis服务站岗的人,当主服务器发生异常时,他会通过投票的方式,将从服务节点升为主服务节点.当我们处理好主节点故障并重启时,原来挂掉的主节点,作为新的主 ...

  7. mac系统Intellij Idea的java环境配置:JDK + Tomcat + Maven

    一.JAVA JDK查看与配置 1.查看java路径详细信息: /usr/libexec/java_home -V 2.java默认路径 jdk1.6: /System/Library/Java/Ja ...

  8. http服务端架构演进

    摘要 在详解http报文相关文章中我们介绍了http协议是如何工作的,那么构建一个真实的网站还需要引入组件呢?一些常见的名词到底是什么含义呢? 什么叫正向代理,什么叫反向代理 服务代理与负载均衡的差别 ...

  9. vue-electron 使用sqlite3数据库,执行npm run build 报错 .NET Framework 2.0 SDK,Microsoft Visual Studio 2005[C:\temp\wechat\node_modules\sqlite3\build\binding.sln]

    问题描述 vue-electron 使用sqlite3数据库,执行npm run build 报错如下: .NET Framework 2.0 SDK,Microsoft Visual Studio ...

  10. pdfminer API介绍:pdf网页爬虫

    安装 pip install pdfminer 爬取数据是数据分析项目的第一个阶段,有的加密成pdf格式的文件,下载后需要解析,使用pdfminer工具. 先介绍一下什么是pdfminer 下面是官方 ...