redis常⽤操作(管道(pipeline)实现批量操作,Redis模糊匹
配等)
试了很多种错误的⽅法,现将⾃⼰测试成功redis管道pipeline批量操作的⽅法和redis常⽤操作以及⼀些关于springboot+redis的概念分享给⼤家
开发环境准备:
spring boot 2.x
使⽤RedisTemplate 操作
springboot项⽬pom引⼊redis依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
怎样登录qq邮箱
<!-- Redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
Jedis是Redis官⽅推荐的⾯向Java的操作Redis的客户端,⽽RedisTemplate是SpringDataRedis中对JedisApi的⾼度封装。SpringDataRedis相对于Jedis来说可以⽅便地更换Redis的Java客户端,⽐Jedis多了⾃动管理连接池的特性,⽅便与其他Spring框架进⾏搭配使⽤.
redisTemplate
1. redisTemplate
1. redisTemplate默认使⽤的是JDK序列化,但是可以主动设置
2. redisTemplate执⾏两条命令其实是在两个连接⾥完成的,因为redisTemplate执⾏完⼀个命令就会对其关闭,但是redisTemplate
额外为什么提供了RedisCallback和SessionCallBack两个接⼝
StringRedisTemplate
1. StringRedisTemplate继承RedisTemplate,只是提供字符串的操作,复杂的Java对象还要⾃⾏处理
RedisCallback和SessionCallBack:
电视节目制作1. 作⽤: 让RedisTemplate进⾏回调,通过他们可以在同⼀条连接中执⾏多个redis命令
2. SessionCalback提供了良好的封装,优先使⽤它,redisCallback使⽤起来有点复杂(很多⼯作需要我们⾃⼰来完成)还是优先选择
SessionCalback
redis 基础操作
redisTemplate模糊匹配删除
String key = "urRole:*";
redisTemplate.delete(key);
Redis模糊查询
可以通过Redis中keys命令进⾏获取key值,具体命令格式:keys pattern
⽂中提到redis中允许模糊查询的有3个通配符,分别是:*,?,[]
其中:
*:通配任意多个字符
:通配单个字符
[]:通配括号内的某⼀个字符
使⽤通配符拿到keys
Set<String> keysUrRole = redisTemplate.keys("urRole:" + "*");
批量查询
Set<String> keysList = stringRedisTemplate.keys(keys);
List<String> strings = stringRedisTemplate.opsForValue().multiGet(keysList);
介绍一种美食作文Redis管道(pipeline)流操作
总的来说Redis的管道可以在⼤量数据需要⼀次性操作完成的时候,使⽤Pipeline进⾏批处理,将多次操作合并成⼀次操作,可以减少链路层的时间消耗。
流⽔线:
redis的读写速度⼗分快,所以系统的瓶颈往往是在⽹络通信中的延迟。
redis可能会在很多时候处于空闲状态⽽等待命令的到达。
为了解决这个问题,可以使⽤redis的流⽔线,流⽔线是⼀种通讯协议,类似⼀个队列批量执⾏⼀组命令。
redis的管道 pipeline批量t
//耗时:309;
@ApiOperation(value = "redis的管道 pipeline 添加数据测试")
public void redistest(){
log.info("redistest开始");
// 开始时间
long start = System.currentTimeMillis();
RedisSerializer stringSerializer = new StringRedisSerializer();
redisTemplate.tKeySerializer(stringSerializer);
redisTemplate.tValueSerializer(stringSerializer);
List<String> result = utePipelined(new SessionCallback() {国家公务员考试报名官网
//执⾏流⽔线
@Override
public Object execute(RedisOperations operations) throws DataAccessException { //批量处理的内容
for (int i = 0; i < 10000; i++) {
operations.opsForValue().t("redistest:" + "k" + i, "v" + i);
}
//注意这⾥⼀定要返回null,最终pipeline的执⾏结果,才会返回给最外层
return null;
}
});
// 结束时间
long end = System.currentTimeMillis();
陈庚大将
log.info("运⾏时间:"+(end-start));
}
此处与未使⽤管道流⽔线操作做对⽐后续其他操作就不⼀⼀对⽐了
未使⽤流⽔线处理10000次请求:
//耗时:5692;
public class RedisTest {
@Autowired
private RedisTemplate redisTemplate;
@Test
public void test(){
诺怎么组词
// 开始时间
long start = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
redisTemplate.opsForValue().t("k"+i,"v"+i);
}
// 结束时间
long end = System.currentTimeMillis();
System.out.println(end-start);
}
}
redis的管道 pipeline批量 delete
@ApiOperation(value = "redis的管道 pipeline删除测试")
public void redisDeletetest(){
log.info("redistest开始");
// 开始时间
long start = System.currentTimeMillis();
RedisSerializer stringSerializer = new StringRedisSerializer();
redisTemplate.tKeySerializer(stringSerializer);
redisTemplate.tValueSerializer(stringSerializer);
//执⾏流⽔线
@Override
public Object execute(RedisOperations operations) throws DataAccessException { //批量处理的内容
for (int i = 0; i < 20000; i++) {
//operations.opsForValue().t("redistest:"+"k"+i,"v"+i);
承诺书样本
operations.delete("redistest:"+"k"+i);
System.out.println(i);
}
return null;
}
});
// 结束时间
long end = System.currentTimeMillis();
log.info("运⾏时间:"+(end-start));
}
redis的管道 pipeline批量 GET
/**
* redis 批量操作其中⼀种⽅式
* redis pipeline 管道技术
*/
@RequestMapping(value = "/redisPipeline", method = RequestMethod.GET)
@ApiOperation(value = "redis的管道 pipeline GET测试")
public void redisPipeline(){
RedisSerializer stringSerializer = new StringRedisSerializer();
stringRedisTemplate.tKeySerializer(stringSerializer);
stringRedisTemplate.tValueSerializer(stringSerializer);
List<String> keys=new ArrayList();
for (int i = 0; i < 200; i++) {
keys.add("redistest:"+"k"+i);
怎么做橡皮泥
}
//调⽤通道批量获取
Map<String, Object> stringObjectMap = batchQueryByKeys(keys, true);
System.out.println(stringObjectMap.size());
}
/**
*
* @param keys
* @param uParallel 是否使⽤并⾏平⾏流
* @return
*/
public Map<String,Object> batchQueryByKeys(List<String> keys,Boolean uParallel){ if(null == keys || keys.size() == 0 ){
return null;
}
if(null == uParallel){
uParallel = true;
}
List<Object> results = utePipelined(
new RedisCallback<Object>() {
new RedisCallback<Object>() {
@Override
public Object doInRedis(RedisConnection connection) throws DataAccessException {
StringRedisConnection stringRedisConn = (StringRedisConnection)connection;
for(String key:keys) {
<(key);
}
return null;
}
});
if(null == results || results.size() == 0 ){return null;}
Map<String,Object> resultMap = null;
if(uParallel){
Map<String,Object> resultMapOne = Collections.synchronizedMap(new HashMap<String,Object>());
keys.parallelStream().forEach(t -> {
resultMapOne.put((keys.indexOf(t)));
});
resultMap = resultMapOne;
}el{
Map<String,Object> resultMapTwo = new HashMap<>();
for(String t:keys){
resultMapTwo.put((keys.indexOf(t)));
}
resultMap = resultMapTwo;
}
return resultMap;
}
在这⾥要说明下我实现的管道pipeline批量获取使⽤的是RedisCallback对象实现的,原因是我使⽤SessionCalback对象来实现时调⽤get⽅法总是获取null最后也没找到原因所以使⽤了RedisCallback对象来实现的批量获取,如果有哪位⼤神了解SessionCalback对象的实现⽅法求指点⼀⼆ 哈哈。。。。
批量操作multi和pipeline效率的⽐较
multi和pipeline的区别在于multi会将操作都即刻的发送⾄redis服务端queued起来,每条指令queued的
操作都有⼀次通信开销,执⾏exec时redis服务端再⼀⼝⽓执⾏queued队列⾥的指令,pipeline则是在客户端本地queued起来,执⾏exec时⼀次性的发送给redis服务端,这样只有⼀次通信开销。⽐如我有5个incr操作,multi的话这5个incr会有5次通信开销,但pipeline只有⼀次。
所以在批量操作使⽤pipeline效率会更⾼。
关于⽂章提到的并⾏执⾏的流的说明请移步⽂章: