概述
redis是一个高性能的单线程的key-value数据库。它的执行过程为:
发送命令 -> 待执行队列 -> 命令执行 -> 返回结果
如果我们使用redis进行批量插入数据,正常情况下相当于将以上四个步骤批量执行N次。发送命令
和返回结果
称为Round Trip Time(RTT,往返时间)。那要是有些场景需要批量执行一些命令,那不是GG。
所以Redis提供了pipeline管道机制,它能将一组Redis命令进行组装,通过一次RTT传输给Redis,并将这组Redis命令的执行结果按顺序返回给客户端。
但是如果一次性查询大量key,也是会堵塞在redis的,所以拆分成几个小的pipline比较合适。或者使用游标去查询数据。
注意点
- Pipeline是非原子的,在上面原理解析那里已经说了就是 Redis
实际上还是一条一条的执行的,而执行命令是需要排队执行的,所以就会出现原子性问题。 - Pipeline中包含的命令不要包含过多。
- Pipeline每次只能作用在一个 Redis 节点上。
- Pipeline 不支持事务,因为命令是一条一条执行的。
使用demo
序列化和反序列化方式设置
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Autowired
private RedisConnectionFactory redisConnectionFactory;
@Bean
public RedisTemplate<String, String> redisTemplate() {
RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
return redisTemplate;
}
}
批量get使用demo
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
@Component
public class RedisClusterPipelineDemo {
@Autowired
private RedisTemplate<String, String> redisTemplate;
public Map<String, String> executePipeline() {
Map<String, String> resultMap = redisTemplate.executePipelined((RedisCallback<Map<String, String>>) connection -> {
ScanOptions scanOptions = ScanOptions.scanOptions().match("key*").build();
Cursor<byte[]> cursor = connection.scan(scanOptions);
Map<String, String> map = new HashMap<>();
while (cursor.hasNext()) {
byte[] keyBytes = cursor.next();
String key = redisTemplate.getStringSerializer().deserialize(keyBytes);
byte[] valueBytes = connection.get(keyBytes);
String value = redisTemplate.getStringSerializer().deserialize(valueBytes);
map.put(key, value);
}
return map;
});
return resultMap;
}
}