redis scan 命令指南

1. 模糊查询键值

redis 中模糊查询keykeysscan等,一下是一些具体用法。

-- 命令用法: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就不会,因为它每次执行只返回少量的元素,所以这个命令可以用于生产环境,而不会像keyssmembers命令一样,当数据库很大时,可能会锁住数秒,这对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. 参考

scan 命令

在RedisTemplate中使用scan代替keys指令

用redis的scan命令代替keys命令,以及在spring-data-redis中遇到的问题

redis scan 命令指南的更多相关文章

  1. Redis Scan命令

    原地址:https://www.cnblogs.com/tekkaman/p/4887293.html [Redis Scan命令] SCAN cursor [MATCH pattern] [COUN ...

  2. redis scan命令使用

      以前的项目中有用到redis的keys命令来获取某些key,知道看了这篇文章 https://mp.weixin.qq.com/s/SGOyGGfA6GOzxwD5S91hLw.安全起见,这次打算 ...

  3. Redis SCAN命令实现有限保证的原理

    SCAN命令可以为用户保证:从完整遍历开始直到完整遍历结束期间,一直存在于数据集内的所有元素都会被完整遍历返回,但是同一个元素可能会被返回多次.如果一个元素是在迭代过程中被添加到数据集的,又或者是在迭 ...

  4. 用redis的scan命令代替keys命令,以及在spring-data-redis中遇到的问题

    摘要 本文主要是介绍使用redis scan命令遇到的一些问题总结,scan命令本身没有什么问题,主要是spring-data-redis的问题. 需求 需要遍历redis中key,找到符合某些pat ...

  5. Redis中的Scan命令的使用

    Redis中有一个经典的问题,在巨大的数据量的情况下,做类似于查找符合某种规则的Key的信息,这里就有两种方式,一是keys命令,简单粗暴,由于Redis单线程这一特性,keys命令是以阻塞的方式执行 ...

  6. Redis中的Scan命令踩坑记

    1 原本以为自己对redis命令还蛮熟悉的,各种数据模型各种基于redis的骚操作.但是最近在使用redis的scan的命令式却踩了一个坑,顿时发觉自己原来对redis的游标理解的很有限.所以记录下这 ...

  7. redis 迭代命令SCAN、SSCAN、HSCAN、ZSCAN

    SCAN 命令用于迭代当前数据库中的数据库键.SSCAN 命令用于迭代集合键中的元素.HSCAN 命令用于迭代哈希键中的键值对.ZSCAN 命令用于迭代有序集合中的元素(包括元素成员和元素分值). S ...

  8. redis 《scan命令》

    此命令十分奇特建议参考文档:http://redisdoc.com/database/scan.html#scan     222222222222222并非每次迭代都要使用相同的 COUNT 值. ...

  9. Redis常用命令

    Redis常用命令Redis提供了丰富的命令对数据库和各种数据类型进行操作,这些命令可以再Linux终端使用.1.键值相关命令2.服务器相关命令 一.键值相关命令 1.get get 键值 当 key ...

随机推荐

  1. Java数组作业

    1 //输入一组数(10个),找出最大值,并给出最大值的位置 2 package test; 3 4 public class test1_1 { 5 public static double max ...

  2. 14_TTS

    TTS(Text to speech)为语音合成的意思.本课程主要介绍了TTS的使用方法. 1 package cn.eoe.tts; 2 3 import java.util.Locale; 4 i ...

  3. 解决 Zuul 中 OAuth2 报 unauthorized 错误

    问题描述 微服务中使用 OAuth2 鉴权,直接访问正常,通过 Zuul 访问报错: { "error": "unauthorized", "erro ...

  4. 老猿学5G扫盲贴:N6接口用户平面协议栈对应的网络分层模型

    在网络通信模型中,都对应有分层的网络结构,如开放式系统互联(OSI)的七层模型(物理层.数据链路层.网络层.传输层.会话层.表示层和应用层)以及TCP/IP四层(网络接口层.网络层.传输层和应用层)模 ...

  5. PyQt(Python+Qt)学习随笔:树型部件QTreeWidget中判断项是否首列跨所有列展示的isFirstItemColumnSpanned方法

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 在前面<PyQt(Python+Qt)学习随笔:QTreeWidgetItem项是否首列跨所有 ...

  6. PLSQL Developer 工具应用

    用户scott使用: 解锁scott: 第一步:登陆管理员 SQL语句:Sqlplus sys/tiger as sysdba 第二步:解锁scott SQL语句:Alter user scott a ...

  7. Python Flask后端异步处理(一)

    Flask是Python中有名的轻量级同步Web框架,但是在实际的开发中,可能会遇到需要长时间处理的任务,此时就需要使用异步的方式来实现,让长时间任务在后台运行,先将本次请求的相应状态返回给前端,不让 ...

  8. 【软件测试部署基础】webpack的认识

    1. 什么是webpack webpack 是一个 JavaScript 应用程序的静态模块打包器(module bundler). 它做的事情就是分析你的项目结构,找到JavaScript模块以及其 ...

  9. 代码审计【根据功能点定向审计】BugFree ZSWin重装案例

    (哦对了!这些CMS代码不要安装在服务器上,先不说它们用来代码审计本身就是有漏洞的,而且在网上下载下来,也不能保证没有源码是否被篡改而留有后门,就安装在本地进行代码审计的练习即可) 我们先下载BugF ...

  10. 攻防世界 ctf web进阶区 unserialize

    进入到题目的界面,看到以下源码 构造payload=?code=O:4:"xctf":1:{s:4:"flag";s:3:"111";} 结 ...