Redis 管道技术——Pipeline
# 前言
当我们谈论Redis数据处理和存储的优化方法时,「Redis Pipeline」无疑是一个不能忽视的重要技术。
在使用Redis的过程中,频繁的网络往返操作可能会引发严重的性能问题,尤其是当大量并发操作需要快速响应的时候。这就是我们需要使用Redis Pipeline的原因。
# Pipeline介绍
Redis 客户端执行一条命令分四个过程:
发送命令——〉命令排队 ——〉命令执行 ——〉返回结果
通常情况下 Redis 是单行执行的,客户端先向服务器发送请求,服务端接收并处理请求后再把结果返回给客户端,这种处理模式在非频繁请求时不会有任何问题。
如果出现集中大批量的请求时,因为每个请求都要经历先请求再响应的过程,这就会造成网络资源浪费,此时就需要管道技术来把所有的命令整合一次发给服务端,再一次响应给客户端,这样就能大大的提升了 Redis 的响应速度。
Pipeline就是通过将多个命令打包到一起然后一次性发送给 Redis 服务器,以减少网络通信次数和延迟,提高操作效率。
普通命令模式,如下图所示:
管道模式,如下图所示:
# 管道技术解决了什么问题?
管道技术解决了多个命令集中请求时造成网络资源浪费的问题,加快了 Redis 的响应速度,让 Redis 拥有更高的运行速度。但要注意的一点是,管道技术本质上是客户端提供的功能,而非 Redis 服务器端的功能。
# Pipeline使用
public List<String> batchGet(List<String> keyList) {
List<Object> objects = template.executePipelined(new RedisCallback<String>() {
@Override
public String doInRedis(RedisConnection redisConnection) throws DataAccessException {
StringRedisConnection stringRedisConnection = (StringRedisConnection) redisConnection;
for (String key : keyList) {
stringRedisConnection.get(key);
}
return null;
}
});
List<String> collect = objects.stream().map(val -> String.valueOf(val)).collect(Collectors.toList());
return collect;
}
public void batchInsert(List<Map<String, String>> saveList,int timeout, TimeUnit unit ) {
template.executePipelined(new SessionCallback<Object>() {
@Override
public <K, V> Object execute(RedisOperations<K, V> redisOperations) throws DataAccessException {
for (Map<String, String> map : saveList) {
for (Map.Entry<String,String> entry:map.entrySet()){
template.opsForValue().set(entry.getKey(),entry.getValue());
}
}
return null;
}
});
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# Pipeline的优缺点
- Pipeline 每批打包的命令不能过多,因为 Pipeline 方式打包命令再发送,那么 Redis 必须在处理完所有命令前先缓存起所有命令的处理结果。这样就有一个内存的消耗,可以将大量命令拆分为多个小的Pipeline命令完成。
- Pipeline 操作是非原子性的,如果要求原子性的,不推荐使用 Pipeline。使用 lua 脚本可以保证安全。
# 总结
Peline
是 Redis 的一个提高吞吐量的机制,适用于多 key 读写场景,比如同时读取多个key
的value
,或者更新多个key
的value
,并且允许一定比例的写入失败、实时性也没那么高,那么这种场景就可以使用了。
上次更新: 2024/04/09, 08:33:56