在 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 scan(RedisTemplate redisTemplate, String pattern) {return redisTemplate.execute((RedisCallback>) connection -> {Set keysTmp = new HashSet<>();try (Cursor 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;});}
    }


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部