redis scan 命令指南
redis scan 命令指南
1. 模糊查询键值
redis 中模糊查询key有 keys,scan等,一下是一些具体用法。
-- 命令用法:keys [pattern]
keys name* -- 查询以name开始的key
-- 命令用法:scan cursor [match pattern] [COUNT count]
scan 0 match name*
更多命令请参考:http://doc.redisfans.com/key/scan.html
2. keys 注意事项
虽然 keys的速度非常快,但是在一个大的数据库中,使用它还是可能造成性能问题,如果你需要从一个数据集中查找特定的key,你最好还是用 Redis 集合结构(set)来代替。
也就是说,keys 命令在生产环境不可以随便用,因为keys 会锁住 redis,并增加redis 的cpu 占用,所以很多公司的redis都禁用了这个命令。
而scan就不会,因为它每次执行只返回少量的元素,所以这个命令可以用于生产环境,而不会像keys,smembers命令一样,当数据库很大时,可能会锁住数秒,这对10000Qps的redis来说是毁灭性的伤害。
3. scan 使用方式
这里使用redisTemplate来执行Redis命令,具体例子如下:
-- 1.单次查询
(ScanPageResult) redisTemplate.execute((RedisCallback<ScanPageResult>) conn -> {
MultiKeyCommands commands = (MultiKeyCommands) conn.getNativeConnection();
ScanParams scanParams = new ScanParams();
scanParams.count(CommonConst.BATCH_SIZE_200);
scanParams.match(pattern);
ScanPageResult result = new ScanPageResult();
ScanResult<String> scanResult = commands.scan(cursor, scanParams);
Set<String> keys = Sets.newHashSet();
if (scanResult.getStringCursor() != null) {
keys.addAll(scanResult.getResult());
if (!"0".equals(scanResult.getStringCursor())) {
result.setNextCursor(scanResult.getStringCursor());
}
}
result.setKeys(keys);
return result;
});
-- ScanPageResult 是自己构造的对象,存储返回的keys和cursor
-- 2. 查询所有
do {
result = CacheUtil.scanForPage(pattern, result.getNextCursor());
if (result == null) {
break;
}
Set<String> keys = result.getKeys();
doSomething(keys);
} while (!"0".equals(result.getNextCursor()));
稍微解释一下,因为scan命令只会返回少量数据,而不是所有数据,所以它还需要返回一个:记录上次查询到的位置标识,这个在redis里被称为cursor(游标)。
所以下次再次查询的时候需要传入上一次返回的cursor继续查询,直到cursor=0为止,标识迭代结束,查询完毕。
一般第一次查询传入的cursor=0,作为初始查询,然后根据结果判断是否进行下一次查询。
3.1 scan 命令的保证
因为是增量式迭代查询,以保证查询所有的结果,所以,在查询间隔中新增的key,不一定会被返回。
另外,因为新增或删除key都会改变redis key的索引,所以,多次查询也会有重复的元素出现,所以使用scan命令,一定需要保证业务处理可重复执行。
然而因为增量式命令仅仅使用游标来记录迭代状态, 所以这些命令带有以下缺点:
同一个元素可能会被返回多次。 处理重复元素的工作交由应用程序负责, 比如说, 可以考虑将迭代返回的元素仅仅用于可以安全地重复执行多次的操作上。
如果一个元素是在迭代过程中被添加到数据集的, 又或者是在迭代过程中从数据集中被删除的, 那么这个元素可能会被返回, 也可能不会, 这是未定义的(undefined)。
3.2 并发执行多个迭代
在同一时间, 可以有任意多个客户端对同一数据集进行迭代, 客户端每次执行迭代都需要传入一个游标, 并在迭代执行之后获得一个新的游标, 而这个游标就包含了迭代的所有状态, 因此, 服务器无须为迭代记录任何状态。
3.3 使用错误的游标进行增量式迭代
使用间断的(broken)、负数、超出范围或者其他非正常的游标来执行增量式迭代并不会造成服务器崩溃, 但可能会让命令产生未定义的行为。
未定义行为指的是, 增量式命令对返回值所做的保证可能会不再为真。
只有两种游标是合法的:
- 在开始一个新的迭代时, 游标必须为 0 。
- 增量式迭代命令在执行之后返回的, 用于延续(continue)迭代过程的游标。
4. 参考
用redis的scan命令代替keys命令,以及在spring-data-redis中遇到的问题
redis scan 命令指南的更多相关文章
- Redis Scan命令
原地址:https://www.cnblogs.com/tekkaman/p/4887293.html [Redis Scan命令] SCAN cursor [MATCH pattern] [COUN ...
- redis scan命令使用
以前的项目中有用到redis的keys命令来获取某些key,知道看了这篇文章 https://mp.weixin.qq.com/s/SGOyGGfA6GOzxwD5S91hLw.安全起见,这次打算 ...
- Redis SCAN命令实现有限保证的原理
SCAN命令可以为用户保证:从完整遍历开始直到完整遍历结束期间,一直存在于数据集内的所有元素都会被完整遍历返回,但是同一个元素可能会被返回多次.如果一个元素是在迭代过程中被添加到数据集的,又或者是在迭 ...
- 用redis的scan命令代替keys命令,以及在spring-data-redis中遇到的问题
摘要 本文主要是介绍使用redis scan命令遇到的一些问题总结,scan命令本身没有什么问题,主要是spring-data-redis的问题. 需求 需要遍历redis中key,找到符合某些pat ...
- Redis中的Scan命令的使用
Redis中有一个经典的问题,在巨大的数据量的情况下,做类似于查找符合某种规则的Key的信息,这里就有两种方式,一是keys命令,简单粗暴,由于Redis单线程这一特性,keys命令是以阻塞的方式执行 ...
- Redis中的Scan命令踩坑记
1 原本以为自己对redis命令还蛮熟悉的,各种数据模型各种基于redis的骚操作.但是最近在使用redis的scan的命令式却踩了一个坑,顿时发觉自己原来对redis的游标理解的很有限.所以记录下这 ...
- redis 迭代命令SCAN、SSCAN、HSCAN、ZSCAN
SCAN 命令用于迭代当前数据库中的数据库键.SSCAN 命令用于迭代集合键中的元素.HSCAN 命令用于迭代哈希键中的键值对.ZSCAN 命令用于迭代有序集合中的元素(包括元素成员和元素分值). S ...
- redis 《scan命令》
此命令十分奇特建议参考文档:http://redisdoc.com/database/scan.html#scan 222222222222222并非每次迭代都要使用相同的 COUNT 值. ...
- Redis常用命令
Redis常用命令Redis提供了丰富的命令对数据库和各种数据类型进行操作,这些命令可以再Linux终端使用.1.键值相关命令2.服务器相关命令 一.键值相关命令 1.get get 键值 当 key ...
随机推荐
- Foreground-aware Image Inpainting
引言 语义分割得到边缘信息指导修复其三 存在问题:现在的图像修复方法主要的通过周围像素来修复,当修复区域与前景区域(显著物体)有交叠时,由于修复区域缺失前景与背景的时间内容导致修复结果不理想. 提出方 ...
- 测试中:ANR是什么
1.ANR 的定义 ANR(Application Not Responding),用户可以选择"等待"而让程序继续运行,也可以选择"强制关闭".所以一个流畅的 ...
- UPX使用教程
UPX是一个通用可执行文件压缩器,由于其具有: 压缩率高:压缩效果优于zip/gzip: 解压速度快:在奔腾133上即可达到大约10MB/秒: 压缩的可执行文件没有额外的内存开销: 安全:可以列表,检 ...
- 老猿学5G专栏文章目录
☞ ░ 前往老猿Python博文目录 ░ 一.3GPP规范文档及其他推荐阅读博文 老猿学5G扫盲贴:3GPP规范文档命名规则及同系列文档阅读指南 老猿学5G扫盲贴:3GPP规范中部分与计费相关的规范序 ...
- 第三十八章、PyQt输入部件:QKeySequenceEdit快捷键输入部件使用案例
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 一.功能简介 Key Sequence Edit输 ...
- CentOS下安装SublimeText
1.Install the GPG key: sudo rpm -v --import https://download.sublimetext.com/sublimehq-rpm-pub.gpg 2 ...
- RedHat-Linux操作指令第1篇
不同的linux系统切换方式会稍有一点差别 从图形界面切换到字符界面:Alt+F(1-8) 或者 Alt+Ctrl+Shift+F(1-8) 从字符界面切换回图形界面:Alt+F7 字符界面启动到图形 ...
- CNVD漏洞证书(2)
第二张CNVD的原创漏洞证书. 关于证书申请可以看我之前写的这篇博客: https://www.cnblogs.com/Cl0ud/p/12720413.html 继续加油
- Hive基本原理及配置Mysql作为Hive的默认数据库
Hive是什么? Hive是基于Hadoop之上的数据仓库: Hive是一种可以存储.查询.分析存储在hadoop中的大规模数据 Hive定义了简单的类SQL查询语言,成为HQL,它允许熟悉SQL的用 ...
- JVM 垃圾回收?全面详细安排!
写在前面: 小伙伴儿们,大家好!今天来学习Java虚拟机相关内容,作为面试必问的知识点,来深入了解一波! 思维导图: image-20201207153125210 1,判断对象是否死亡 我们在进行垃 ...