管道技术(Pipeline)是客户端提供的一种批处理技术,用于一次处理多个Redis,从而提高整个交互的性能。
通常情况下Redis是单线程执行的,客户端先向服务器发送请求,服务端接收并处理请求、然后把结果返回给客户端,这种处理模式在非频繁请求时不会出现任何问题。
但如果出现集中大批量请求时,因为每个请求都要经历先请求再响应的过程,这就会造成网络资源浪费。此时就需要管道技术来把所有的命令整合起来,一次性发送给服务端,服务端处理完毕之后一次性响应给客户端,这样就大大地提高了Redis的响应速度。
普通命令模式和管道模式的区别,如下图所示:
管道中命令越多,管道技术的作用就更大,相比于普通模式来说执行效率就越高。
管道技术解决了什么问题?
管道技术解决了多个命令集中请求时造成网络资源浪费的问题,加快了 Redis 的响应速度,让 Redis 拥有更高的运行速度。但要注意的一点是,管道技术本质上是客户端提供的功能,而非 Redis 服务器端的功能。
管道技术使用
我们使用Python提供的redis模块来实现管道操作,我们之前说的事务在Python中也是通过管道实现的。
import time
import redis
client = redis.Redis(host="47.94.174.89", decode_responses="utf-8")
# 生成一千个键值对,以列表的形式存储,[(0, 0), (1, 1), ..., (1000, 1000)]
k_v = list(zip(range(1000), range(1000)))
start = time.perf_counter()
for _ in k_v:
client.set(_[0], _[1])
print(f"不通过管道, 耗时: {time.perf_counter() - start}")
# 删除设置的key
client.delete(*range(1000))
# 通过管道
start = time.perf_counter()
pipeline = client.pipeline()
for _ in k_v:
pipeline.set(_[0], _[1])
pipeline.execute() # 提交
print(f"通过管道, 耗时: {time.perf_counter() - start}")
"""
不通过管道, 耗时: 7.9951645
通过管道, 耗时: 0.021514000000001587
"""
从上面的结果可以看出,管道技术要比普通的执行快了 371.6 倍,当然这里的命令比较单一,不同的命令得到的速度上的差异会有不同。但是很明显,管道技术确实要比普通的命令执行快上很多很多。
管道技术需要注意的事项
管道技术虽然有它的优势,但在使用时还需注意以下几个细节:
发送的命令数量不会被限制,但输入缓存区也就是命令的最大存储体积为 1GB,当发送的命令超过此限制时,命令不会被执行,并且会被 Redis 服务器端断开此链接;
如果管道的数据过多可能会导致客户端的等待时间过长,导致网络阻塞;
部分客户端自己本身也有缓存区大小的设置,如果管道命令没有没执行或者是执行不完整,可以排查此情况或较少管道内的命令重新尝试执行。
总结
使用管道技术可以解决多个命令执行时的网络等待,它是把多个命令整合到一起发送给服务器端处理之后统一返回给客户端,这样就免去了每条命令执行后都要等待的情况,从而有效地提高了程序的执行效率,但使用管道技术也要注意避免发送的命令过大,或管道内的数据太多而导致的网络阻塞。