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 ...
随机推荐
- 断点调试 breakpoints(修改request)
目录 1.抓取信息 2.点击breakpoints勾选断点 3.复制抓取的信息 4.点击proxy再点断点设置 5.点击勾选然后add添加其下如图 6.点击确定 7.刷新百度,charles出现的页面 ...
- IEEE754标准浮点数表示与舍入
原文地址:https://blog.fanscore.cn/p/26/ 友情提示:本文排版不太好,但内容简单,请耐心观看,总会搞懂的. 1. 定点数 对于一个无符号二进制小数,例如101.111,如果 ...
- 六. Vue CLI详解
1. Vue CLI理解 1.1 什么是Vue CLI 如果你只是简单写几个Vue的Demo程序, 那么你不需要Vue CLI,如果你在开发大型项目那么你需要它, 并且必然需要使用Vue CLI. 使 ...
- 冲刺随笔——Day_Seven
这个作业属于哪个课程 软件工程 (福州大学至诚学院 - 计算机工程系) 这个作业要求在哪里 团队作业第五次--Alpha冲刺 这个作业的目标 团队进行Alpha冲刺 作业正文 正文 其他参考文献 无 ...
- JZOJ2020年8月11日提高组T1 密码
JZOJ2020年8月11日提高组T1 密码 题目 Description 在浩浩茫茫的苍穹深处,住着上帝和他的神仆们,他们闲谈着下界的凡人俗事,对人世间表现的聪明智慧,大加赞赏.今天他们正在观赏大地 ...
- 基于 MongoDB 动态字段设计的探索
一.业务需求 假设某学校课程系统,不同专业课程不同 (可以动态增删),但是需要根据专业不同显示该专业学生的各科课程的成绩,如下: 专业 姓名 高等数学 数据结构 计算机 张三 90 85 计算机 李四 ...
- Model/View开发小结
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 Model/View开发是PyQt和Qt中重要的框架之一,老猿认为另外两个就是信号槽机制和事件机制, ...
- 「生产事故」MongoDB复合索引引发的灾难
前情提要 11月末我司商品服务的MongoDB主库曾出现过严重抖动.频繁锁库等情况. 由于诸多业务存在插入MongoDB.然后立即查询等逻辑,因此项目并未开启读写分离. 最终定位问题是由于:服务器自身 ...
- Java获取不到请求的真实IP
问题 最近在写博客浏览量的时候,设计了这么一个逻辑:同一个IP浏览一遍文章,5分钟内不刷新次数.就需要在服务器端得到用户的真实IP,我代码是这样写的(从网上找的方法): public static S ...
- POI2009 KON-Ticket Inspector
题目链接 Description 一辆火车依次经过 \(n\) 个车站,顺序是 \(1, 2, 3, ..., n - 1, n\).给定 \(A_{i, j}\) 表示从 \(i\) 站上车,\(j ...