Redis系列(十八)、Redis中的管道pipeline操作(Python)

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


目录

介绍

使用

对比Lua脚本

尾巴


Redis6系列文章

Redis系列(一)、CentOS7下安装Redis6.0.3稳定版

Redis系列(二)、数据类型之字符串String 

Redis系列(三)、数据类型之哈希Hash

Redis系列(四)、数据类型之列表List

Redis系列(五)、数据类型之无序集合Set

Redis系列(六)、数据类型之有序集合ZSet(sorted_set)

Redis系列(七)、常用key命令

Redis系列(八)、常用服务器命令 

Redis系列(九)、Redis的“事务”及Lua脚本操作

Redis系列(十)、详解Redis持久化方式AOF、RDB以及混合持久化

Redis系列(十一)、Redis6新特性之ACL安全策略(用户权限管理)

Redis系列(十二)、Redis6集群搭建及原理(主从、哨兵、集群)

Redis系列(十三)、pub/sub发布与订阅(对比List和Kafka)

Redis系列(十四)、Redis6新特性之RESP3与客户端缓存(Client side caching)

Redis系列(十五)、Redis6新特性之集群代理(Cluster Proxy)

Redis系列(十六)、Redis6新特性之IO多线程

Redis系列(十七)、Redis中的内存淘汰策略和过期删除策略


介绍

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

  1. 客户端发送请求,获取socket,阻塞等待返回;
  2. 服务端执行命令并将结果返回给客户端;

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

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

逐个命令请求:

Redis系列(十八)、Redis中的管道pipeline操作(Python)_第1张图片

管道请求:

Redis系列(十八)、Redis中的管道pipeline操作(Python)_第2张图片

使用

管道的使用很简单,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()

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

Redis系列(十八)、Redis中的管道pipeline操作(Python)_第3张图片

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

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

Redis系列(十八)、Redis中的管道pipeline操作(Python)_第4张图片

对比Lua脚本

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

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

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

尾巴

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

 

希望本文对你有帮助,请点个赞鼓励一下作者吧~ 谢谢!

你可能感兴趣的:(#,Redis,Redis,管道,pipeline,script,事务)