在 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 一样有它自己的问题:
- 因为是分段获取 key,所以它会多次请求 redis 服务器,这样势必取同样的 key,scan 耗时更长。
- 在对键进行增量式迭代的过程中, 键可能会被修改, 所以增量式迭代命令只能对被返回的元素提供有限的保证
/*** 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 Setscan(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;});} }
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
