KEYS命令使用很简单。
redis> MSET one 1 two 2 three 3 four 4
redis> KEYS *o*
1) "four"
2) "one"
3) "two"
redis> KEYS t??
1) "two"
redis> KEYS *
1) "four"
2) "three"
3) "one"
4) "two"
redis>
但由于KEYS命令一次性返回所有匹配的key,所以,当redis中的key非常多时,对于内存的消耗和redis服务器都是一个隐患,
对于Redis 2.8以上版本给我们提供了一个更好的遍历key的命令 SCAN 该命令的基本格式:
SCAN cursor [MATCH pattern] [COUNT count]
SCAN
每次执行都只会返回少量元素,所以可以用于生产环境,而不会出现像
KEYS
或者
SMEMBERS
命令带来的可能会阻塞服务器的问题。
SCAN
命令是一个基于游标的迭代器。这意味着命令每次被调用都需要使用上一次这个调用返回的游标作为该次调用的游标参数,以此来延续之前的迭代过程
当
SCAN
命令的游标参数(即cursor)被设置为 0 时, 服务器将开始一次新的迭代, 而当服务器向用户返回值为 0 的游标时, 表示迭代已结束。
简单的迭代演示:
redis 127.0.0.1:6379> scan 0
1) "17"
2) 1) "key:12"
2) "key:8"
3) "key:4"
4) "key:14"
5) "key:16"
6) "key:17"
7) "key:15"
8) "key:10"
9) "key:3"
10) "key:7"
11) "key:1"
redis 127.0.0.1:6379> scan 17
1) "0"
2) 1) "key:5"
2) "key:18"
3) "key:0"
4) "key:2"
5) "key:19"
6) "key:13"
7) "key:6"
8) "key:9"
9) "key:11"
在上面这个例子中, 第一次迭代使用 0 作为游标, 表示开始一次新的迭代。第二次迭代使用的是第一次迭代时返回的游标 17 ,作为新的迭代参数 。
显而易见,SCAN命令的返回值 是一个包含两个元素的数组, 第一个数组元素是用于进行下一次迭代的新游标, 而第二个数组元素则又是一个数组, 这个数组中包含了所有被迭代的元素。
注意:返回的游标不一定是递增的,可能后一次返回的游标比前一次的小。
在第二次调用 SCAN 命令时, 命令返回了游标 0 , 这表示迭代已经结束, 整个数据集已经被完整遍历过了。
full iteration :以 0 作为游标开始一次新的迭代, 一直调用 SCAN 命令, 直到命令返回游标 0 , 我们称这个过程为一次完整遍历。
SCAN增量式迭代命令并不保证每次执行都返回某个给定数量的元素,甚至可能会返回零个元素, 但只要命令返回的游标不是 0 , 应用程序就不应该将迭代视作结束。
不过命令返回的元素数量总是符合一定规则的, 对于一个大数据集来说, 增量式迭代命令每次最多可能会返回数十个元素;而对于一个足够小的数据集来说,可能会一次迭代返回所有的key
COUNT选项
对于增量式迭代命令不保证每次迭代所返回的元素数量,我们可以使用
COUNT
选项, 对命令的行为进行一定程度上的调整。COUNT 选项的作用就是让用户告知迭代命令, 在每次迭代中应该从数据集里返回多少元素。使用COUNT 选项对于对增量式迭代命令相当于一种提示, 大多数情况下这种提示都比较有效的控制了返回值的数量。
注意:
COUNT选项并不能严格控制返回的key数量,只能说是一个大致的约束。并非每次迭代都要使用相同的 COUNT 值,用户可以在每次迭代中按自己的需要随意改变 COUNT 值, 只要记得将上次迭代返回的游标用到下次迭代里面就可以了。
MATCH 选项
类似于KEYS 命令,增量式迭代命令通过给定 MATCH 参数的方式实现了通过提供一个 glob 风格的模式参数, 让命令只返回和给定模式相匹配的元素。
MATCH 选项
对元素的模式匹配工作是在命令从数据集中取出元素后和向客户端返回元素前的这段时间内进行的, 所以如果被迭代的数据集中只有少量元素和模式相匹配, 那么迭代命令或许会在多次执行中都不返回任何元素。
以下是这种情况的一个例子:
redis 127.0.0.1:6379> scan 0 MATCH *11*
1) "288"
2) 1) "key:911"
redis 127.0.0.1:6379> scan 288 MATCH *11*
1) "224"
2) (empty list or set)
redis 127.0.0.1:6379> scan 224 MATCH *11*
1) "80"
2) (empty list or set)
redis 127.0.0.1:6379> scan 80 MATCH *11*
1) "176"
2) (empty list or set)
redis 127.0.0.1:6379> scan 176 MATCH *11* COUNT 1000
1) "0"
2) 1) "key:611"
2) "key:711"
3) "key:118"
4) "key:117"
5) "key:311"
6) "key:112"
7) "key:111"
8) "key:110"
9) "key:113"
10) "key:211"
11) "key:411"
12) "key:115"
13) "key:116"
14) "key:114"
15) "key:119"
16) "key:811"
17) "key:511"
18) "key:11"
redis 127.0.0.1:6379>
可以看出,以上的大部分迭代都不返回任何元素。在最后一次迭代, 我们通过将 COUNT 选项的参数设置为 1000 , 强制命令为本次迭代扫描更多元素, 从而使得命令返回的元素也变多了。
基于SCAN的这种安全性,建议大家在生产环境都使用SCAN命令来代替KEYS,不过注意,该命令是在2.8.0版本之后加入的,如果你的Redis低于这个版本,则需要升级Redis。
下面用PHP代码演示SCAN命令的使用:
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
/* 设置遍历的特性为不重复查找,该情况下扩展只会scan一次,所以可能会返回空集合 */
$redis->setOption(Redis::OPT_SCAN, Redis::SCAN_NORETRY);
$it = NULL;
$pattern = '*';
$count = 50; // 每次遍历50条,注意是遍历50条,遍历出来的50条key还要去匹配你的模式,所以并不等于就能够取出50条key
$keysArr = $redis->scan($it, $pattern, $count);
if ($keysArr)
foreach ($keysArr as $key)
echo $key . "\n";
} while ($it > 0); //每次调用 Scan会自动改变 $it 值,当$it = 0时 这次遍历结束 退出循环
echo '---------------------------------------------------------------------------------' . "\n";
/* 设置扩展在一次scan没有查找出记录时 进行重复的scan 直到查询出结果或者遍历结束为止 */
$redis->setOption(Redis::OPT_SCAN, Redis::SCAN_RETRY);
$it = NULL;
$pattern = '*';
$count = 50; // 每次遍历50条,注意是遍历50条,遍历出来的50条key还要去匹配你的模式,所以并不等于就能够取出50条key
//这种用法下我们只需要简单判断返回结果是否为空即可, 如果为空说明遍历结束
while ($keysArr = $redis->scan($it, $pattern, $count))
foreach ($keysArr as $key)
echo $key . "\n";
执行结果:
[root@localhost php]# /usr/local/php/bin/php scan.php
places
cities
---------------------------------------------------------------------------------
places
cities
注意:如果php执行报错 请升级到较新版本的Redis扩展
更多请参考:
Thai's all!
redis-cli -a password -n 0 --scan --pattern "keys*" | sed '/./{s/^/"&/;s/$/&a...
来自: Jeffery的博客
从Redis v2.8开始,SCAN命令已经可用,它允许使用游标从keyspace中检索键。
对比KEYS命令,虽然SCAN无法一次性返回所有匹配结果,但是却规避了阻塞系统这个高...
来自: 琦彦
以前的项目中有用到redis的keys命令来获取某些key,这个命令在数据库特别大的情况会block很长一段时间,所以有很大的安全隐患,所以这次打算优化一下。官网建议使用scan命令来代替。于是就用了...
来自: yaoxiaofeng_000的专栏
熟悉Redis的人都知道,它是单线程的。因此在使用一些时间复杂度为O(N)的命令时要非常谨慎。可能一不小心就会阻塞进程,导致Redis出现卡顿。
有时,我们需要针对符合条件的一部分命令进行操作,比如删...
来自: K_Ohaha的博客
SpringRedisTemplate针对这个Scan进行了封装,示例使用(针对最新库spring-data-redis-1.8.1.RELEASE):Set execute = redisTempl...
来自: 张哈希的博客
Scan cursor [match pattern] [count count]
cursor:游标,每次scan都会返回一个游标,用以继续下次的扫描。游标从0开始遍历,到...
来自: AJun的博客
今天在看项目中大神写的框架中关于redis存储相关代码时,发现了再获取set数据类型的全部元素时,采用的是sscan函数,而不是采用的smembers函数,这两个到底有什么区别呢?
来自: dhklsl的专栏
http://www.h5min.cn/article/56448.htm
这篇文章主要介绍了超强、超详细Redis入门教程,本文详细介绍了Redis数据库各个方面的知识,需要的朋友可以...
来自: liqingtx的专栏
下面先来了解HotSpot虚拟机中的7种垃圾收集器:Serial、ParNew、Parallel Scavenge、Serial Old、Parallel Old、CMS、G1,先介绍一些垃圾收集的相...
来自: tjiyu的博客
一开始使用 keys() 这种形式,大发现网上大量文章表示,这种形式会非常耗费内存。
于是改一下方式,使用hash, (key hkey hvalue),把要模糊查询的值放到hkey上面。然后使用s...
来自: zling工作室
Redis 自带了一个叫 redis-benchmark 的工具来模拟 N 个客户端同时发出 M 个请求。 (类似于 Apache ab 程序)。你可以使用 redis-benchmark -h 来查...
来自: shendeguang的专栏
关于Redis大键(Key),我们从[空间复杂性]和访问它的[时间复杂度]两个方面来定义大键。
前者主要表示 Redis键的占用内存大小;后者表示 Redis集合数据类型(set/hash/list/...
来自: 斜阳雨陌
系统中使用了spring data redis中的一个redisTemplate.keys()方法,用来模糊匹配,开始在测试时,满足一切的开发功能,部署到线上后,过了大概半天,服务器出现了很高的延迟,...
来自: abcde
>>> import redis
>>> conn = redis.Redis(host='localhost', ...
来自: cheegoday的专栏
之前在做统计相关功能的时候,使用到了redis的keys,但是,跑了一段时间后,被运维的慢查询给抓出来了,说这个太慢了,需要10ms(平常的命令只需要2-3ms),并且keys会造成阻塞,影响其他...
来自: 卖克的专栏
在redis中是支持使用通配符的使用,例如‘?’或是’’,所以我们在获取redis里面的某个db里面的所有数据可以用 `keys `这样的指令来实现。但是存在一个问题就是这样做的话,在数据量很大的情况...
来自: clamaa的专栏
一、redis学习 01/ nosql介绍 NoSQL:一类新出现的数据库(not only sql),它的特点:1、 不支持SQL语法2、 存储结构跟传统关系型数据库中的那种关系表完全不同,nosq...
来自: Tomorrow never comes
Redis是一个远程内存数据库,它不仅性能强劲,而且还具有复制特性以及为解决问题而生的独一无二的数据模型。Redis提供了5种不同类型的数据结构,各式各样的问题都可以很自然地映射到这些数据结构上:Re...
来自: 郭先生的博客
Redis实现键对应多值作者:chszs,未经博主允许不得转载。经许可的转载需注明作者和博客主页:http://blog.csdn.net/chszsRedis服务器提供了很多流行的数据结构,比如Ma...
来自: chszs的专栏
1、Serial收集器:古老的单线程收集器,作用于新生代。单线程的意义并非仅仅是只使用一条线程进行垃圾回收,更重要的是,在进行垃圾回收的时候,必须暂停其他所有的工作线程,因此,用户体验很不好。单实际上...
来自: yanqiaoli的博客
转载自:http://www.cnblogs.com/zhangyu1024/p/5229887.html语法:KEYS pattern
说明:返回与指定模式相匹配的所用的keys。
该命令所支持...
来自: 皓月如我的专栏
JedisCluster中不支持keys模糊查询
在非集群环境下,可以直接创建JedisPool对象,然后调用getResource()方法获取Jedis连接对象,然后就可以调用Jedis API操...
来自: 从不吹牛逼
1、redis的del命令不像keys命令一样可以支持正则,所以有时候,想要删除一些无用的key的时候,只能用管道和linux命令组合起来达到目的,使用的例子见最下面。
2、redis的作者anti...
来自: zhiyuan_2007的专栏
$ redis-cli eval "local t1=redis.call('KEYS','a*')
for k,v in pairs(t1) do
redis.call('del',v)
pr...
来自: lcathm的专栏
工作中遇到一个问题,redis中存储了大量的key,而且没有设置时效,其中很大一部分后来都没用了,导致redis体积庞大,查询缓慢。服务器版本为windows,网上搜索到很多批量删除的方法都是Linu...
来自: Purse的博客
本文转自:http://blog.csdn.net/qq_27623337/article/details/53201202众所周知,当redis中key数量越大,keys 命令执行越慢,而且最重要的...
来自: jeffrey11223的博客
SCANSCAN cursor [MATCH pattern] [COUNT count]SCAN 命令及其相关的 SSCAN 命令、 HSCAN 命令和 ZSCAN 命令都用于增量地迭代(incre...
来自: 程序猿_三产
像keys或者smembers命令,需要遍历数据集合中的所有元素。在一个大的数据库中使用,可能会阻塞服务器较长的一段时间,造成性能问题,因此不适用与生产环境。
在Redis2.8.0...
来自: 程序员的自我修养
Scan cursor [match pattern] [count count]
Scan 命令及其相关的sscan命令、HSCAN命令和ZSCAN命令都用于增量的迭代(incerme...
来自: kfengqingyangk的博客
一、前言Redis是Key-Value数据库,存储的时候需要一个唯一的Key值,查询的时候根据根据key值进行查询,但是Redis毕竟只是key-value存储,所以有很多局限性。例如:(1)无法实现...
来自: 徐刘根的博客
Questions
在数据库内我们可以通过like关键字、%、*或者REGEX关键字进行模糊匹配。而在Redis内我们如何进行模糊匹配呢?集群情况Redis Cluster的情况是否和单机一致呢?前...
来自: Be yourself.
Restful API 近年来应用越来越广泛,各大互联网公司纷纷推出了自己的 Restful API 服务。
本文将从实际应用出发,从 REST 到 Restful 再到 Restful API...
来自: wbliu的专栏
一、概述最近在springboot项目引入thymeleaf模板时,使用非严格标签时,运行会报错。默认thymeleaf模板对html5标签是严格检查的。二、在项目中加NekoHTML库在Maven中...
来自: Luck_ZZ的博客
我们可能经常会用到这一功能,比如有时,我们不希望用户没有进行登录访问后台的操作页面,而且这样的非法访问会让系统极为的不安全,所以我们常常需要进行登录才授权访问其它页面,否则只会出现登录页面,当然我的思...
来自: 沉默的鲨鱼的专栏
对于J2EE项目导入导出Excel是最普通和实用功能,本工具类使用步骤简单,功能强大,只需要对实体类进行简单的注解就能实现导入导出功能,导入导出操作的都是实体对象.
请看一下这个类都有哪些功能:
来自: 李坤 大米时代 第五期
分享一个新浪微博的爬虫,基于 Scrapy + MongoDB 实现,号称一小时可爬千万条数据。作者:LiuXingMing来源:http://blog.csdn.net/bone_ace/artic...
来自: 大数据公社
x264是一个 H.264/MPEG4 AVC 编码器,本指南将指导新手如何创建高质量的H.264视频。
对于普通用户通常有两种码率控制模式:crf(Constant Rate Fact...
来自: dancing_night的专栏
问题场景描述整个项目通过Maven构建,大致结构如下:
核心Spring框架一个module spring-boot-base
service和dao一个module server-core
提供系统...
来自: 开发随笔
2018-2-10更新:
新增了适用于Selenium3.8.1+FireFox57的Python版本的实现
https://github.com/ANBUZHIDAO/myFirefoxDriv...
来自: wwwqjpcom的专栏