Redis中的管道Pipeline操作

程序源代码

共 1888字,需浏览 4分钟

 ·

2020-07-28 13:22

点击上方蓝色字体,选择“设为星标

回复”资源“获取更多资源

大数据技术与架构
点击右侧关注,大数据开发领域最强公众号!

暴走大数据
点击右侧关注,暴走大数据!

Redis默认每次执行请求都会创建和断开一次连接池的操作,如果想执行多条命令的时候会在这件事情上消耗过多的时间,因此我们可以使用Redis的管道来一次性发送多条命令并返回多个结果,节约发送命令和创建连接的时间提升效率。

介绍

在前面我们介绍过Redis的事务和lua脚本操作,事实上在各语言版本的Redis中都有管道(Pipeline)的功能,本篇以python版作为示例,当我们使用python给redis发送命令时会经历下面的步骤:


  • 客户端发送请求,获取socket,阻塞等待返回;

  • 服务端执行命令并将结果返回给客户端;

而当执行的命令较多时,这样的一来一回的网络传输所消耗的时间被称为RTT(Round Trip Time),显而易见,如果可以将这些命令作为一个请求一次性发送给服务端,并一次性将结果返回客户端,会节约很多网络传输的消耗,可以大大提升响应时间。


官网:https://redis.io/topics/pipelining


逐个命令请求:

管道请求:

使用

管道的使用很简单,python版代码如下,在管道中可以选择是否开启事务,默认是开启的,这里的事务与Redis的事务一样为弱事务性不是真正的事务:

import redis #创建连接池获取连接pool = redis.ConnectionPool(host='wykd', port=6379,password='123456', decode_responses=True)rp1 = redis.Redis(connection_pool=pool) #创建管道,可以选择开启或关闭事务,这里的事务与Redis事务一样是弱事务型pipe = rp1.pipeline(transaction=True)#在管道中添加命令pipe.set('new','123')pipe.set('name', 'wyk2')pipe.set('company', 'csdn2')pipe.hincrby('hage','wyk',1) #这个命令会报错,因为hage为hash类型不能使用get命令,此时无论开启关闭事务,管道中的其他命令也依然会正常执行#pipe.get('hage')  #也可以用下面的语法将多个命令拼接到一起# pipe.set('name', 'wyk').set('company', 'csdn').hset('hage', 'wyk',28).hincrby('hage','wyk',1) #执行pipeline里的脚本pipe.execute()


当管道中有命令报错时,无论管道是否开启事务都不会影响其他脚本的执行:

在管道中可以一次性获取多个命令的返回值,以列表形式:

pipe.get('name').get('company').hget('hage', 'wyk')res = pipe.execute()print(res)

对比Lua脚本

Redis的Script会当成一个命令,具有原子性,在执行Script的时候不会被其他的命令插入,因此更适合于处理事务;而管道虽然也会将多个命令一次性传输到服务端,但在服务端执行的时候仍然是多个命令,如在执行CMD1的时候,外部另一个客户端提交了CMD9,会先执行完CMD9再执行管道中的CMD2,因此事实上管道是不具有原子性的。


就场景上来说,正因为Lua脚本会被视为一个命令去执行,因为Redis是单线程执行命令的,所以我们不能在lua脚本里写过于复杂的逻辑,否则会造成阻塞,因此lua脚本适合于相对简单的事务场景。


而管道因为不具有原子性,因此管道不适合处理事务,但管道可以减少多个命令执行时的网络消耗,可以提高程序的响应速度,因此管道更适合于管道中的命令互相没有关系,不需要有事务的原子性,且需要提高程序响应速度的场景。


尾巴

管道可以提升我们程序中的响应时间,同时我们不能完全依赖于它的"事务"机制,只需要把管道当做"批处理"工具即可,在某些场合下,更需要结合管道和lua脚本一起使用。


欢迎点赞+收藏+转发朋友圈素质三连



文章不错?点个【在看】吧! ?

浏览 23
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报