Spring RedisTemplate实现scan操作

老生常谈,keys不安全,因为

  • keys的操作会导致数据库暂时被锁住,其他的请求都会被堵塞;业务量大的时候会出问题

Spring RedisTemplate实现scan

1. hscan sscan zscan

  • 例子中的"field"是值redis的key,即从key为"field"中的hash中查找
  • redisTemplate的opsForHash,opsForSet,opsForZSet 可以 分别对应 sscan、hscan、zscan
  • 也可以使用 (JedisCommands) connection.getNativeConnection() 的 hscan、sscan、zscan 方法实现cursor遍历,参照下文2.2章节
复制代码
try {
    Cursor<Map.Entry<Object,Object>> cursor = redisTemplate.opsForHash().scan("field",
    ScanOptions.scanOptions().match("*").count(1000).build());
    while (cursor.hasNext()) {
        Map.Entry<Object,Object> entry = cursor.next();
        Object key = entry.getKey();
        Object valueSet = entry.getValue();
    }
    //关闭cursor
    cursor.close();
} catch (IOException e) {
    e.printStackTrace();
}
复制代码

 

  • cursor.close(); 游标一定要关闭,不然连接会一直增长;可以使用client lists info clients info stats 命令查看客户端连接状态,会发现scan操作一直存在
  • 我们平时使用的redisTemplate.execute 是会主动释放连接的,可以查看源码确认
  • 代码虽然只是调用一次scan方法,但是spring-data-redis已经对scan做了封装,这个scan结合cursor.hasNext会多次redis scan,最终拿到所有match的结果

2. scan

2.1 使用spring-data-redis封装好的scan方法

复制代码
    public Set<String> scan(String matchKey) {
        Set<String> keys = redisTemplate.execute((RedisCallback<Set<String>>) connection -> {
            Set<String> keysTmp = new HashSet<>();
            Cursor<byte[]> cursor = connection.scan(new ScanOptions.ScanOptionsBuilder()
                            .match("*" + matchKey + "*").count(1000).build()); while (cursor.hasNext()) { keysTmp.add(new String(cursor.next())); } return keysTmp; }); return keys; }
复制代码

 

  项目中我用的就是这种方法来代替 

Set keys = redisTemplate.keys(uploadTag + entity.getCaseNo() + ":*");

 

  

posted @   佩洛君  阅读(10359)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
点击右上角即可分享
微信分享提示