# Redis之 管道(PipeLine)和批量(Batch操作)
# 管道(PipeLine)
Redis 的 管道 (pipelining) (opens new window)是用来打包多条无关命令批量执行,以减少多个命令分别执行带来的网络交互时间。在一些批量操作数据的场景,使用管道可以显著提升 Redis 的读写性能。
# 原理演示
# 使用方法
// in NodeJS
const [[, key1], [,key2]] = await redis.pipeline().get(`key1`).get(`key2`).exec();
console.log(key1, key2);
1
2
3
2
3
# 适用场景
在批量操作(查询和写入)数据时,我们应尽量避免多次跟 Redis 的网络交互。这时,可以使用管道实现,也可以 Redis 内嵌 Lua 脚本实现。需要注意的是:
- 管道只适用于无因果关联的多命令操作,否则就需要借助 Lua 脚本实现批量操作。
- 在实际应用中,Redis 往往不可能是单机部署,如果想要在集群中使用管道,可以部署为一主多从架构,此时所有节点的数据都一致,随机选取节点使用管道即可。
# 与multi区别
pipeline
,将一系列命令打包发给redis服务端。如果只是为了一下执行多条redis命令,无需事物和原子性。multi
,相当于一个redis的transaction的。multi
具有原子性,pipeline
不具有。在不需要事务的情况下,pipeline
的性能10倍高于multi
。
# 总结
正确使用pipeline对性能的提升十分明显。 但是使用管道时 Redis 会缓存之前命令的结果,最后一并输出给终端,因此所打包的命令不宜太多,否则内存使用会很严重。
pipeline并未保证原子性。即同一个pipeline中的命令在redis-server被执行的顺序可以保证,但不保证其中不会穿插其余的客户端请求的命令。
# Batch 操作
# 优势
- 性能优异,因为是单条指令操作,因此性能略优于其他批量操作指令。
# 缺点
- 批量命令不保证原子性,存在部分成功部分失败的情况,需要应用程序解析返回的结果并做相应处理。
- 批量命令在key数目巨大时存在RRT与key数目成比例放大的性能衰减,会导致单实例响应性能(RRT)严重下降。
# 相关具体命令
mget
(适用与string类型) (opens new window)mset
(适用于string类型) (opens new window)hmget
(适用于hash类型) (opens new window)hmset
(适用于hash类型) (opens new window)
# 其他操作方法
随口一提一个小方法,批量执行多个del
操作。
// in NodeJs
const keys = [ 'key1', 'key2'];
redis.del(...keys);
// or
redis.unlink(...keys)
1
2
3
4
5
2
3
4
5