在 RedisTemplate 中使用 scan

SCAN 简介

SCAN 命令及其相关的 SSCAN 命令、 HSCAN 命令和 ZSCAN 命令都用于增量地迭代(incrementally iterate)一集元素(a collection of elements):

  • SCAN 命令用于迭代当前数据库中的数据库键。
  • SSCAN 命令用于迭代集合键中的元素。
  • HSCAN 命令用于迭代哈希键中的键值对。
  • ZSCAN 命令用于迭代有序集合中的元素(包括元素成员和元素分值)。

SCAN 和 KEYS 的区别

当 KEYS 命令被用于处理一个大的数据库时, 又或者 SMEMBERS 命令被用于处理一个大的集合键时, 它们会锁定 redis 库, 可能会阻塞服务器达数秒之久。在高并发下会导致请求大量堆积进而导致服务雪崩。有些公司在生产环境直接禁用 kyes * 命令。但是在 redis 服务器 key 的数量不大的情况下,使用 keys 也是没啥问题的。

SCAN 命令及其相关的 SSCAN 命令、 HSCAN 命令和 ZSCAN 命令都用于增量地迭代 ,它们每次执行都只会返回少量元素,不会阻塞服务器, 所以这些命令可以用于生产环境, 而不会出现像 KEYS 命令、 SMEMBERS 命令带来的问题。

SCAN 一样有它自己的问题:

  1. 因为是分段获取 key,所以它会多次请求 redis 服务器,这样势必取同样的 key,scan 耗时更长。
  2. 在对键进行增量式迭代的过程中, 键可能会被修改, 所以增量式迭代命令只能对被返回的元素提供有限的保证
  3. /**
     * redis扩展工具
     *
     * @author yuhao.wang3
     * @since 2020/2/21 23:35
     */
    public abstract class RedisHelper {
        private static Logger logger = LoggerFactory.getLogger(RedisHelper.class);
     
        /**
         * scan 实现
         *
         * @param redisTemplate redisTemplate
         * @param pattern       表达式,如:abc*,找出所有以abc开始的键
         */
        public static Set<String> scan(RedisTemplate<String, Object> redisTemplate, String pattern) {
            return redisTemplate.execute((RedisCallback<Set<String>>) connection -> {
                Set<String> keysTmp = new HashSet<>();
                try (Cursor<byte[]> cursor = connection.scan(new ScanOptions.ScanOptionsBuilder()
                        .match(pattern)
                        .count(10000).build())) {
     
                    while (cursor.hasNext()) {
                        keysTmp.add(new String(cursor.next(), "Utf-8"));
                    }
                } catch (Exception e) {
                    logger.error(e.getMessage(), e);
                    throw new RuntimeException(e);
                }
                return keysTmp;
            });
        }
    }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值