redistemplate查询大量key,单机scan扫描;RedisTemplate和StringRedisTemplate的区别
Posted 好大的月亮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了redistemplate查询大量key,单机scan扫描;RedisTemplate和StringRedisTemplate的区别相关的知识,希望对你有一定的参考价值。
RedisTemplate和StringRedisTemplate的区别
StringRedisTemplate
是继承RedisTemplate
,但是两者的数据是不共通的;也就是说StringRedisTemplate
只能管理StringRedisTemplate
里面的数据,RedisTemplate
只能管理RedisTemplate中
的数据。
序列化策略两者也不同
- StringRedisTemplate默认采用的是String的序列化策略,保存的key和value都是采用此策略序列化保存的。
- RedisTemplate默认采用的是JDK的序列化策略,保存的key和value都是采用此策略序列化保存的。
RedisTemplate使用的序列类在在操作数据的时候,比如说存入数据会将数据先序列化成字节数组然后在存入Redis数据库,这个时候打开Redis查看的时候,
你会看到你的数据不是以可读的形式展现的,而是以字节数组显示,类似下面
当然从Redis
获取数据的时候也会默认将数据当做字节数组转化,这样就会导致一个问题,当需要获取的数据不是以字节数组存在redis
当中时,而是正常的可读的普通字符串的时候,RedisTemplate
就无法获取导数据,这个时候获取到的值就是NULL
。这个时候StringRedisTempate
就派上了用场。
所以当你使用RedisTemplate
获取不到数据的时候请检查一下是不是Redis
里面的数据是可读形式而非字节数组.
综上
当你的redis数据库里面本来存的是字符串数据或者你要存取的数据就是字符串类型数据的时候,那么你就使用StringRedisTemplate
即可,
但是如果你的数据是复杂的对象类型,而取出的时候又不想做任何的数据转换,直接从Redis
里面取出一个对象,那么使用RedisTemplate
是更好的选择。
keys在扫描大key的时候会阻塞redis进程,可以使用scan分批获取
要注意使用redistemplate的scan操作不支持redis集群
//要指定类型,不然下面del删除操作不会成功,不指定泛型操作的不是字面上的key
@Autowired
private RedisTemplate<String,String> redisTemplate;
private Set<String> scanTargetKeys(String keyWords)
return redisTemplate.execute((RedisCallback<Set<String>>) connection ->
Set<String> keysTmp = new HashSet<>();
Cursor<byte[]> cursor = connection.scan(
new ScanOptions.ScanOptionsBuilder().match(
keyWords + "*"
).count(scanCount).build()
);
while (cursor.hasNext())
keysTmp.add(new String(cursor.next()));
return keysTmp;
);
.
.
.
//调用上面的方法
Set<String> keys = scanTargetKeys(cacheName);
if(!ObjectUtils.isEmpty(keys))
redisTemplate.delete(keys);
RedisTemplate没有指定泛型默认使用jdk序列化策略,会有前缀
以上是关于redistemplate查询大量key,单机scan扫描;RedisTemplate和StringRedisTemplate的区别的主要内容,如果未能解决你的问题,请参考以下文章
项目中redisTemplate设置的key,redis客户端上查询不到的问题
RedisTemplate 获取redis中以某些字符串为前缀的KEY列表