Redis(六)管道(Pipelining)

本文深入探讨了Redis Pipelining技术的工作原理及其在高延迟网络环境中提高性能的作用。通过减少请求响应的环回时间和系统状态切换开销,Pipelining能够显著提升Redis的吞吐量,实测性能提升可达20倍。文章还详细介绍了Jedis客户端的Pipelining使用方法及实战案例。

管道技术并不是Redis特有的,管道技术在计算机科学中有很多地方的应用。

来自wiki的解释:

In computing, a pipeline, also known as a data pipeline,[1] is a set of data processing elements connected in series, where the output of one element is the input of the next one. The elements of a pipeline are often executed in parallel or in time-sliced fashion. Some amount of buffer storage is often inserted between elements.

在计算机中,管道又叫做数据管道,是数据处理元件。一个元件的输出作为另一个元件的输入。管道中元素经常是并行或者是基于事件分片。在元素之间会插入缓冲区。

说白了就是传输计算元素。与计算机领域相关的管道非常多,其中平时应用开发中遇到的就是网络协议的HTTP pipelining。

HTTP Pipelining

HTTP pipelining is a technique in which multiple HTTP requests are sent on a single TCP connection without waiting for the corresponding responses.[1]

HTTP pipelining是一种技术,多个HTTP请求基于一个TCP连接以无等待匹配的响应的方式被发送。

HTTP中引入pipelining主要是为了提高性能。在一些高延迟的网络中,如果需要等待上一个HTTP请求的响应后再发送下一个请求,那么网络延迟势必是性能瓶颈之所在。pipelining为了解决这个问题,即流水线式发送HTTP请求,client不等待上一个请求的响应,只要server端按照请求的顺序返回响应即可。这样虽然无法从根本上解决网络延迟的问题,但是却可以减少request/response这种模式带来的环回时间。

Pipelining带来了以下的优势:

  • 如上所述,减少了多个请求的整体环回时间,提高了性能
  • 对于server端,能够在单位时间内接收到更多的请求,在server性能满足的前提下,提高了server端的吞吐量

同样万物平衡,Pipelining也有很多限制:

  • 请求之间应该保证无依赖,后一个请求不能依赖前一个请求的响应结果。这种场景不适合使用pipelining
  • 非幂等性请求不能使用pipelining(如post请求),同样的post请求会改变资源的状态,在使用pipelining技术中,会导致不幂等

下图引用wiki和《HTTP权威指南》中关于HTTP pipelining的描述:

参考

Pipelining
HTTP pipelining
《HTTP权威指南》

Redis-Pipelining

在看完pipelining,相信大家对管道(流水线)技术有一个初识。下面再来看下它是如何在Redis中被应用,为什么应用。

  • Redis Pipelining介绍
  • Redis Pipelining解决的问题
  • Jedis中Pipelining的使用
  • Jedis中的Pipleling的Benchmark
  • Redis Pipelining在项目实战中的应用
一.Redis Pipelining介绍

Redis是是一种client-server的request/response的模式,Redis有单独的TCP Server。

  • client发送请求请求到server端,然后需要阻塞等待server端的响应
  • server端处理请求然后返回响应给client

即如上中介绍的HTTP的request/response一样。在这种模式中,数据包必须从client发送到server端,然后再从server端返回到client端,这个时间叫做RTT(Round Trip Time)。

假设Redis Server每秒能处理100k请求,但是RTT是250ms,这样Redis Server实际每秒只能处理4个请求,而且这种影响会随着网络延迟越大而逐渐加剧。所带来的直接影响:

  • 阻塞客户端线程或进程,消耗资源,大量请求时无疑降低client性能
  • 降低server端的吞吐量

为了解决该问题,需要一种client无等待响应的方式发送请求至server的模式,即Redis pipelining。

Redis pipelining使得client能够无等待响应的方式连续发送多条命令请求至Redis Server端,然后Server端按照请求顺序返回响应结果,类似:

client> set k0 v0;
client> set k1 v1;
client> set k2 v2;
server> ok
server> ok
server> ok
二.Redis Pipelining解决的问题

从以上的Redis pipelining介绍中可以看出,Redis pipelining降低了高延迟网络中,request/response方式带来的请求应答的环回时间消耗:

  • 无序等待响应的方式发送请求,减少等待时间(特别在高延迟网络中)
  • 一次性返回响应,减少多次响应的带来的时间消耗

更重要的一点是,在request/response的方式中,逐次发送请求至server端,server端每次都需要read/write,这里的read/write是systcall,涉及到内核态和用户态的切换,非常消耗系统资源。Redis pipelining的方式尽量减少了这种系统状态的切换开销。

三.Jedis中Pipelining的使用

Pipelining急需要Redis Server端的支持又需要Redis client的支持。client需要能够不获取响应的情况下发送多个命令,server端需要编排好响应以请求的顺序返回给客户端。

Redis的经典Client jedis是支持Pipelining的。使用方式可以分为两种,获取响应方式也可以分为两种。

1.使用pipelining方式:

  • 直接使用pipelining
  • 在事务中使用pipelining

2.获取响应方式:

  • 同步,一次性获取所有请求的响应,以list方式返回
  • 同步,在调用pipelining的操作时,指定返回的响应

关于测试的代码和pipelining的api使用详情可以戮

四.Jedis中的Pipleling的Benchmark

前面第二节中分析Pipelining就是解决网络延迟,提高吞吐量。那么在使用Pipelining的情况下,相对于不使用的情况下,性能是否提高了?提高多少?

一切都需要用数据来说话。下面分别跑下测试,比较下。Jedis的测试案例中有Benchmark模块,这里直接使用其Pipelining和GetSet的Benchmark的测试程序:

执行命令数ops(no pipelining/pipelining)
1006666 ops/9090 ops
10000026870 ops/316455 ops
100000028967 ops/422922 ops

从以上的可以看出使用Pipelining的情况下大致能提高20倍的性能。

五.Redis Pipelining在项目实战中的应用

首先认识下Pipelining的特点:

  • 批量流水线发送
  • 一次返回相应的响应

两个特点决定了应用场景必须有以下特点:

  • 由于是批量流水线发送,所以每个请求之间需要无状态,即后请求不依赖前请求的响应结果
  • 由于一次返回响应,所以响应中可能会存在有些请求命令执行成功,有些失败。所以应用场景必须能够容忍数据处理错误或者数据丢失的风险,或者能够接受通过其他机制弥补丢失或者错误的数据方式

一般适用于批量缓存数据或者预加载缓存数据。因为不需要逐条发送缓存的数据,可以pipelining方式发送。因为是缓存数据,缓存的场景能够容忍某一些数据缓存失败,无非是没有命中,再次加载单条加载至缓存。

最近在做一个业务数据预警检查的项目,采用责任链模式,将需要预警检查的每条数据遍历责任链,完成数据一致性校验检查。责任链中每个检查器都是可配置生效失效,而且支持可扩展检查器。扩展性、可配置型较强,但是带来的问题即每条需要预警检查的数据遍历责任链检查器时,都需要重复的查询一些其他的表数据与配置。这里从而引入了巨大的磁盘I/O,产生性能瓶颈。

后来想如果,能将这些其他表的数据预加载进入缓存中,每次遍历需要预警检查的数据时,不从DB中查询获取,直接从缓存中获取即可。由于服务是集群的,所以需要使用分布式缓存且本地缓存容量有限。

这里最终采用懒加载的方式缓存其他表的数据或者配置,在预警检查第一条数据时,各个检查器将其他表的数据或者配置加载到缓存中,同时采用pipelining模式缓存到Redis中。

这样下条预警数据的遍历检查器时,每个检查器从缓存中获取其他表的数据或者配置即可。大幅度减少DB带来的I/O,突破性能瓶颈。

转载于:https://www.cnblogs.com/lxyit/p/9829091.html

<think>好的,我需要回答用户关于Redis管道机制的问题,包括其概念、原理、使用场景和性能优势。首先,我需要回忆Redis管道的基本知识。管道机制主要是通过减少网络往返次数来提升性能,用户可能已经通过引用资料了解了一些,我需要结合提供的引用内容来组织答案。 首先,概念部分,应该解释什么是管道机制。根据引用[3],管道技术将任务分解为个阶段并行执行,提高吞吐量。所以可以说明Redis管道允许客户端一次性发送个命令,无需等待每个响应,从而减少延迟。 然后是原理部分。引用[2]提到Redis支持管道,无论版本如何。需要详细说明客户端如何批量发送命令,服务器顺序处理并返回结果。这里需要强调网络往返次数的减少,以及服务端和客户端如何处理这些命令。 使用场景方面,引用[1]提到批量处理命令的应用,比如批量设置或获取数据。所以可以举例如批量写入日志、初始化数据等需要高吞吐量的场景。同时要提到不适用于有依赖关系的命令,或者需要原子性操作的情况。 性能优势部分,引用[1]和引用[3]都指出减少网络开销和延迟,提高吞吐量。需要具体说明相比逐条命令,管道如何节省时间,比如RTT的减少。可能还需要提到带宽优化,因为个命令可以合并发送。 接下来,我需要确保结构清晰,分点回答。同时,检查是否需要生成相关问题。根据用户指示,必须生成相关问题,放在最后。问题需要围绕Redis管道的原理、使用注意事项、与其他技术的对比等。 需要避免使用Markdown格式,使用自然的中文段落。同时,注意引用标注的位置,例如在提到减少网络延迟时引用[1][3],在说明原理时引用[2][3]。 可能还需要注意一些技术细节,比如管道与事务的区别,管道是否保证原子性,以及错误处理方式。这些内容如果用户没有提到,但可能在相关问题中出现,可以适当提及。 最后,确保语言口语化,避免使用专业术语过,或者适当解释术语。例如,RTT可能需要解释为网络往返时间。 现在开始组织答案: 概念部分:简要说明管道机制是什么,为什么有效。引用[1][3]说明其通过批量处理减少网络开销。 原理部分:客户端发送个命令而不等待响应,服务器按顺序处理,引用[2][3]支持版本和分解任务。 使用场景:批量操作、高吞吐需求,引用[1]的批量处理例子。同时指出不适用场景,比如事务需要原子性。 性能优势:减少RTT,提高吞吐量,引用[1][3]的网络优化和效率提升。举例说明时间节省。 相关问题部分:生成三个左右的问题,例如如何正确使用管道,与事务的区别,性能测试方法等。 检查是否有遗漏点,比如错误处理,或者管道与脚本的比较,但用户的问题中没有提到这些,可能不需要深入,除非在相关问题时涉及。 确保每个引用在正确的位置标注,例如在提到性能优势时引用[1][3],原理引用[2][3]。 现在将各部分用中文连贯地组织起来,分点说明,保持口语化,避免代码块,使用自然过渡。</think>### Redis管道机制详解 #### 一、概念 Redis管道Pipelining)是一种**批量命令处理技术**,允许客户端一次性发送个命令到服务器,而无需等待每个命令的单独响应。通过减少网络交互次数,显著降低了通信延迟,提升了吞吐量[^1][^3]。 #### 二、工作原理 1. **客户端批量发送**:客户端将个命令打包一次性发送给服务器,而非逐条等待响应。 2. **服务器顺序处理**:服务器按接收顺序依次执行命令,并将结果缓存在内存中。 3. **批量返回结果**:所有命令执行完毕后,服务器将结果一次性返回给客户端[^2][^3]。 例如,若需执行10条命令,传统方式需10次网络往返(RTT),而管道仅需1次RTT。 #### 三、使用场景 1. **批量数据操作**:如初始化缓存、批量写入日志或统计数据。 2. **高吞吐需求**:需要快速处理大量命令的场景(如实时排行榜更新)。 3. **低延迟敏感场景**:减少网络延迟对性能的影响[^1]。 **注意**:管道不适用于需保证原子性的操作(如事务),或命令间存在依赖关系的情况。 #### 四、性能优势 1. **减少网络开销**:合并次通信为一次,降低RTT影响。例如,100条命令耗时从$100 \times RTT$降至$1 \times RTT$[^1]。 2. **提升吞吐量**:服务器可连续处理命令,无需等待客户端确认,CPU利用率更高。 3. **带宽优化**:TCP报文合并发送,减少协议头开销。 #### 五、示例对比 - **传统模式**: ``` 客户端发送命令1 → 等待响应 → 发送命令2 → 等待响应... ``` - **管道模式**: ``` 客户端发送[命令1, 命令2, ...] → 服务器处理 → 返回[结果1, 结果2, ...] ``` #### 、注意事项 - **结果顺序性**:服务器按命令顺序返回结果,客户端需按序解析。 - **内存占用**:服务器会缓存所有结果,大量命令可能占用较内存。 - **错误处理**:若某条命令执行失败,不影响其他命令,但需遍历结果检查错误。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值