网站首页 > 技术文章 正文
scan 命令和 keys的区别
首先我们先说说keys命令
KEYS * 匹配数据库中所有 key 。
KEYS h?llo 匹配 hello , hallo 和 hxllo 等。
KEYS h*llo 匹配 hllo 和 heeeeello 等。
KEYS h[ae]llo 匹配 hello 和 hallo ,但不匹配 hillo
特殊符号用 \ 隔开
时间复杂度:
O(N), N 为数据库中 key 的数量。
返回值:
符合给定模式的 key 列表。
首先 keys 是阻塞式命令 redis的命令执行是单线程的,同一时间只能执行单个命令。这也就造成了生产环境如果使用这个命令会造成 阻塞,其他的服务不能调用redis 严重点 服务可能会挂掉。
scan 命令
SCAN cursor [MATCH pattern] [COUNT count]
SCAN 命令用于迭代当前数据库中的数据库键。
SSCAN 命令用于迭代集合键中的元素。
HSCAN 命令用于迭代哈希键中的键值对。
ZSCAN 命令用于迭代有序集合中的元素(包括元素成员和元素分值)。
- 以上列出的四个命令都支持增量式迭代, 它们每次执行都只会返回少量元素, 所以这些命令可以用于生产环境, 而不会出现像 KEYS 命令、 SMEMBERS 命令带来的问题 —— 当 KEYS 命令被用于处理一个大的数据库时, 又或者 SMEMBERS 命令被用于处理一个大的集合键时, 它们可能会阻塞服务器达数秒之久。不过, 增量式迭代命令也不是没有缺点的: 举个例子, 使用 SMEMBERS 命令可以返回集合键当前包含的所有元素, 但是对于 SCAN 这类增量式迭代命令来说, 因为在对键进行增量式迭代的过程中, 键可能会被修改, 所以增量式迭代命令只能对被返回的元素提供有限的保证(offer limited guarantees about the returned elements)。
- 因为 SCAN 、 SSCAN 、 HSCAN 和 ZSCAN 四个命令的工作方式都非常相似, 所以这个文档会一并介绍这四个命令, 但是要记住: SSCAN 命令、 HSCAN 命令和 ZSCAN 命令的第一个参数总是一个数据库键。 而 SCAN 命令则不需要在第一个参数提供任何数据库键 —— 因为它迭代的是当前数据库中的所有数据库键。
SCAN 命令是一个基于游标的迭代器(cursor based iterator):
SCAN 命令每次被调用之后, 都会向用户返回一个新的游标,
用户在下次迭代时需要使用这个新游标作为 SCAN 命令的游标参数, 以此来延续之前的迭代过程。
当 SCAN 命令的游标参数被设置为 0 时, 服务器将开始一次新的迭代,
而当服务器向用户返回值为 0 的游标时, 表示迭代已结束
SCAN 命令的基本用法
SCAN cursor [MATCH pattern] [COUNT count]
cursor :游标位置 pattern:匹配的值 count:每次渐进的值并不是返回结果的数量 也可以理解为每次扫描的值这个 值也并不是越大越好,测 试中500w数据 设置为15000时效率最好。
- 注意 :Count 参数越大,Redis 阻塞时间也会越长,需要取舍。开始不知道直接设置了Integer.MAX_VALUE 结果上线直接凉凉堵塞死
- 并且返回的值中会存在重复的key 且是无序的 所以要注意去重。
public void setRedisinfo() {
ScanOptions scanOptions = new ScanOptions.ScanOptionsBuilder()
.match("*B*")
.count(15000).build();
Cursor<Map.Entry<String, Long>> searchkey = redisTemplate.opsForHash().scan("searchkey", scanOptions);
while (searchkey.hasNext()){
Map.Entry<String, Long> next = searchkey.next();
log.info(next.getKey()+":"+next.getValue());
}
}
redis 中的数据 匹配 B
下面我们说一下 redis 的模糊匹配 并且 忽略大小写
redis 是支持 正则的 但是 只支持 通配符的方式 : [Aa][Bb][Cc]
//这里返回 [Aa][Bb][Cc]
public static String UnA(String string){
char[] charArr=string.toCharArray();
String res="";
for (char c : charArr) {
if(check(c)){
String ups=String.valueOf(c).toUpperCase();
String lows=String.valueOf(c).toLowerCase();
res+="["+ups+""+lows+"]";
}
}
return res;
}
public static boolean check(char c) {
if (((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))) {
return true;
} else {
return false;
}
}
我们测试下忽略大小写 匹配 B b
@Test
public void setRedisinfo() {
ScanOptions scanOptions = new ScanOptions.ScanOptionsBuilder()
//.match("*观八虏铰惑*")
.match("*"+UnA("B")+"*")
.count(15000).build();
Cursor<Map.Entry<String, Long>> searchkey = redisTemplate.opsForHash().scan("searchkey", scanOptions);
while (searchkey.hasNext()){
Map.Entry<String, Long> next = searchkey.next();
log.info(next.getKey()+":"+next.getValue());
}
log.info(searchkey.toString());
}
获取到的结果
另外redis 的其他命令可以去 doc.redisfans.com/ 这里查看
ok 坑就踩到这。。。下一个坑见!
作者:青衣画白扇
链接:
https://juejin.cn/post/7091098560111837221
猜你喜欢
- 2025-06-24 java文本对比工具源码1(java比较文本相似度)
- 2025-06-24 线上系统性能太差,我手写了字符串切割函数,性能提升10倍以上
- 2025-06-24 QT之QString(qty是什么单位的缩写)
- 2025-06-24 50个Java编程技巧,免费送给大家(java编程教程)
- 2025-06-24 Spring Boot中如何设计出一个高效的分布式并发锁?
- 2025-06-24 你只会用 split?试试 StringTokenizer,性能可以快 4 倍
- 2025-06-24 Spring AOP接口限流实战!三行注解解决高并发,代码可复制
- 2025-06-24 最快速度、方便的对象复制工具 Mapper Struct 的高阶应用
- 2025-06-24 Qt数字转QString保留小数点位数的方法
- 2025-06-24 Java泛型中通配符T/E/K/V解析,告别类型焦虑
- 1506℃桌面软件开发新体验!用 Blazor Hybrid 打造简洁高效的视频处理工具
- 481℃MySQL service启动脚本浅析(r12笔记第59天)
- 460℃启用MySQL查询缓存(mysql8.0查询缓存)
- 455℃服务器异常重启,导致mysql启动失败,问题解决过程记录
- 441℃「赵强老师」MySQL的闪回(赵强iso是哪个大学毕业的)
- 436℃Dify工具使用全场景:dify-sandbox沙盒的原理(源码篇·第2期)
- 418℃mysql服务怎么启动和关闭?(mysql服务怎么启动和关闭)
- 416℃MySQL server PID file could not be found!失败
- 最近发表
- 标签列表
-
- cmd/c (64)
- c++中::是什么意思 (83)
- 标签用于 (65)
- 主键只能有一个吗 (66)
- c#console.writeline不显示 (75)
- pythoncase语句 (81)
- es6includes (73)
- windowsscripthost (67)
- apt-getinstall-y (86)
- node_modules怎么生成 (76)
- chromepost (65)
- c++int转char (75)
- static函数和普通函数 (76)
- el-date-picker开始日期早于结束日期 (70)
- js判断是否是json字符串 (67)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- & (66)
- java (73)
- js数组插入 (83)
- linux删除一个文件夹 (65)
- mac安装java (72)
- eacces (67)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)