likes
comments
collection
share

springboot整合redis使用scan代替keys方案

作者站长头像
站长
· 阅读数 50

一、为什么使用scan代替keys?

·因为redis是单线程的,使用keys命令,如果redis中的key非常庞大,那么这条命令执行时间非常长,这个时候就会阻塞到其他命令的执行,所以要redis也提供给我们另一个scan命令来解决这种常见的场景,

二、scan有什么优势呢?

  1. scan命令的时间复杂度虽然也是O(N),但它是分次进行的,不会阻塞线程。
  2. scan命令提供了limit参数,可以控制每次返回结果的最大条数。

这两个优势就帮助我们解决了上面的难题,不过scan命令也并不是完美的,它返回的结果有可能重复,因此需要客户端去重。但是这个问题很好解决,我们可以用Set集合巧妙的处理。

Redis Scan 命令用于迭代数据库中的数据库键。

SCAN 命令是一个基于游标的迭代器,每次被调用之后, 都会向用户返回一个新的游标, 用户在下次迭代时需要使用这个新游标作为 SCAN 命令的游标参数, 以此来延续之前的迭代过程。

SCAN 返回一个包含两个元素的数组, 第一个元素是用于进行下一次迭代的新游标, 而第二个元素则是一个数组, 这个数组中包含了所有被迭代的元素。如果新游标返回 0 表示迭代已结束。

 如下代码表示,从redis服务器中,扫描1000个有指定前缀的key,放入到set集合中,count是每次扫描的key个数,并不是结果集个数

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

转载自:https://juejin.cn/post/6988120359841038373
评论
请登录