SpringBoot中使用Redis的keys替代方案scan

众所周知redis的keys命 在测试环境这样开发没有问题, 由于项目对redis依赖比较大, 就网上找了一些关于redis的keys命令, 得知keys命令执行的时候会严重阻塞线上其它命令的正常请求, 于是做了以下替代方案

      前同事留下的坑 优化redis时候记录下,也可以代码循环手动删除对应的key

  

/**
     *  获取指定前缀的一系列key
     *  使用scan命令代替keys, Redis是单线程处理,keys命令在KEY数量较多时,
     *  操作效率极低【时间复杂度为O(N)】,该命令一旦执行会严重阻塞线上其它命令的正常请求
     * @param keyPrefix
     * @return
     */
    public Set<String> keys(String keyPrefix) {
        String realKey = "*" + keyPrefix + "*";
        try {
            return redisTemplate.execute((RedisCallback<Set<String>>) connection -> {
                Set<String> binaryKeys = new HashSet<>();
                Cursor<byte[]> cursor = connection.scan(new ScanOptions.ScanOptionsBuilder().match(realKey).count(Integer.MAX_VALUE).build());
                while (cursor.hasNext()) {
                    binaryKeys.add(new String(cursor.next()));
                }
                return binaryKeys;
            });
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     *  删除指定前缀的一系列key
     * @param keyPrefix
     */
    public void removeAll(String keyPrefix) {
        try {
            Set<String> keys = keys(keyPrefix);
            redisTemplate.delete(keys);
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

生成环境不可直接用!!!      错误用法

 Set<String> keys = redisUtil.keys(accessTokenKey + ":*");
redisUtil.del(keys);

 

posted @ 2022-02-09 10:18  山河永慕~  阅读(1017)  评论(0编辑  收藏  举报