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序列化策略,会有前缀
在这里插入图片描述

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用RedisTemplate的scan方法可以遍历Redis中的所有key,如果需要删除特定的key,可以在遍历时进行判断并执行删除操作。 具体操作步骤如下: 1. 获取RedisTemplate对象。 2. 调用RedisTemplate的execute方法,传入RedisCallback回调函数。 3. 在回调函数中调用RedisConnection的scan方法,获取key的游标cursor和当前扫描到的keys。 4. 遍历keys,判断是否需要删除,需要则调用RedisConnection的del方法删除key。 5. 如果游标cursor返回0,则表示遍历完成,退出循环。 示例代码如下: ``` @Autowired private RedisTemplate<String, Object> redisTemplate; public void deleteKeys(String pattern) { redisTemplate.execute((RedisCallback<Void>) connection -> { ScanOptions options = ScanOptions.scanOptions().match(pattern).build(); String cursor = ScanParams.SCAN_POINTER_START; do { ScanResult<byte[]> scanResult = connection.scan(cursor.getBytes(), options); List<byte[]> keys = scanResult.getResult(); for (byte[] key : keys) { String keyStr = new String(key, StandardCharsets.UTF_8); if (needDelete(keyStr)) { connection.del(key); } } cursor = scanResult.getStringCursor(); } while (!"0".equals(cursor)); return null; }); } private boolean needDelete(String key) { // 判断是否需要删除key的逻辑 } ``` 其中,deleteKeys方法接收一个字符串类型的参数pattern,用于指定需要删除的key的模式,例如:"user:*"表示删除以"user:"开头的所有key。needDelete方法用于判断是否需要删除当前遍历到的key,根据实际需求自行实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值