Redis的KEYS 命令千万不能乱用_Redis

来源:脚本之家  责任编辑:小易  

在linux中 批量操作redis中的 keys的方法:1.统计个数:redis中名称含有OMP_OFFLINE的key的个数;src/redis-cli keys"*OMP_OFFLINE*"|wc-l2.批量删除批量删除 0号数据库中名称含有OMP_OFFLINE的key:src/redis-cli-n 0 keys"*OMP_OFFLINE*"|xargs src/redis-cli-n 0 del在redis的客户端环境中并不支持批量删除www.zgxue.com防采集请勿采集本网。

KESY 命令

查找所有符合给定模式 pattern 的 key。KEYS*匹配数据库中所有 key。KEYS h?llo 匹配 hello,hallo 和 hxllo 等。KEYS h*llo 匹配 hllo 和 heeeeello 等。KEYS h[ae]llo 匹配 hello 和 hallo,但

时间复杂度: O(N) , 假设Redis中的键名和给定的模式的长度有限的情况下,N为数据库中key的个数。

1.统计个数: redis中名称含有OMP_OFFLINE的key的个数;src/redis-cli keys\"*OMP_OFFLINE*\"|wc-l 2.批量删除 批量删除 0号数据库中名称含有OMP_OFFLINE的key: src/redis-cli-n 0 keys\"*OMP_

Redis Keys 命令用于查找所有符合给定模式 pattern 的 key

可以使用linux的xargs来做到 如: redis-cli keys\"prefix*\"|xargs*/redis-cli del 如果是访问特定的数据库,则可以: redis-cli-n 0 keys\"prefix*\"|xargs*/redis-cli-n 0 del

尽管这个操作的时间复杂度是 O(N), 但是常量时间相当低。例如,在一个普通笔记本上跑Redis,扫描100万个key只要40毫秒。

redis 有一个keys命令。语法:KEYS pattern 说明:返回与指定模式相匹配的所用的keys。该命令所支持的匹配模式如下:(1)?用于匹配单个字符。例如,h?llo可以匹配hello、hallo和hxllo等;(2)*

命令格式 KEYS pattern

首先要链接redis客户端 redis-cli 然后要通过key来查找你存的数据,抄相当于一个数组,袭有key,有value,通过key来查看value的值。keys*注:列出当前redis存储的全部key。keys W*注:列出当前

Warning: 生产环境使用 KEYS 命令需要非常小心。在大的数据库上执行命令会影响性能。这个命令适合用来调试和特殊操作,像改变键空间keyspace布局。不要在你的代码中使用 KEYS 。如果你需要一个寻找键空间中的key子集,考虑使用SCAN 或 集合结构sets。

支持的匹配模式 patterns: h?llo 匹配 hello, hallo 和 hxllo h*llo 匹配 hllo 和 heeeello h[ae]llo 匹配 hello 和 hallo, 不匹配 hillo h[^e]llo 匹配 hallo, hbllo, … 不匹配 hello h[a-b]llo 匹配 hallo 和 hbllo

使用 \ 转义你想匹配的特殊字符。

背景

1、Redis是单线程的,其所有操作都是原子的,不会因并发产生数据异常

2、使用高耗时的Redis命令是很危险的,会占用唯一的一个线程的大量处理时间,导致所有的请求都被拖慢

场景

在生产环境中执行 KEYS 命令的时,因为Redis是单线程的,KEYS 命令的性能随着数据库数据的增多而越来越慢,使用 KEYS 命令时会占用唯一的一个线程的大量处理时间,引发Redis阻塞并且增加Redis的CPU占用,导致所有的请求都被拖慢,可能造成Redis所在的服务器宕机,情况是很恶劣的,在实际生产运用的过程中请忽略掉。试想如果Redis阻塞超过10秒,如果有集群的场景,可能导致集群判断Redis已经故障,从而进行故障切换。

如果所有的线程在Redis那取不到数据,情况严重时可能会导致应用程序出现雪崩的情况,一瞬间全去数据库取数据,数据库就宕机了。

其他危险命令

但凡发现时间复杂度为O(N)的命令,都要慎重,不要在生产上随便使用。例如hgetall、lrange、smembers、zrange、sinter等命令,它们并非不能使用,但这些命令的时间复杂度都为O(N),使用这些命令需要明确N的值,否则也会出现缓存宕机。

1、flushdb 命令用于清空当前数据库中的所有 key

2、flushall 命令用于清空整个 Redis 服务器的数据(删除所有数据库的所有 key )

3、config 客户端连接后可配置服务器

如何禁用危险命令

在redis.conf中,在SECURITY这一项中,新增以下配置禁用指定命令:

rename-command FLUSHALL ""rename-command FLUSHDB ""rename-command CONFIG ""rename-command KEYS ""

另外,对于flushall命令,需要设置配置文件中appendonly no,否则服务器是无法启动。

如果想要保留命令,但是不轻易使用,可以重命名命令来设定:

rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52

TIP:更改记录到AOF文件或传输到从属服务器的命令的名称可能会导致问题。

改良建议

一、如果有这种需求的话可以自己对键值做索引,比如把各种键值存到不同的set里面,分类建立索引,这样就可以很快的得到数据,但是这样也存在一个明显的缺点,就是浪费宝贵的空间,所以还是要合理考虑,当然也可以想办法,比如对于有规律的键值,可以存储他们的始末值等等。

二、针对改良keys和smembers命令也可以使用scan命令

SCAN 命令

Redis从2.8版本开始支持scan命令,可以用来分批次扫描Redis记录,这样肯定会导致整个查询消耗的总时间变大,影响服务使用,但不会影响redis服务卡顿,SCAN命令的基本用法如下:

命令格式 SCAN cursor [MATCH pattern] [COUNT count]

SCAN 命令提供三个参数,第一个是cursor(游标),第二个是要匹配的正则,第三个是单次遍历的槽位

SCAN 命令及其相关的 SSCAN 命令、 HSCAN 命令和 ZSCAN 命令都用于增量地迭代(incrementally iterate)一集元素(a collection of elements): 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 命令的基本用法

SCAN 命令是一个基于游标的迭代器(cursor based iterator):SCAN 命令每次被调用之后, 都会向用户返回一个新的游标, 用户在下次迭代时需要使用这个新游标作为 SCAN 命令的游标参数, 以此来延续之前的迭代过程。

当 SCAN 命令的游标参数被设置为 0 时, 服务器将开始一次新的迭代, 而当服务器向用户返回值为 0 的游标时, 表示迭代已结束。

以下是一个 SCAN 命令的迭代过程示例:

redis 127.0.0.1:6379> scan 01) "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 171) "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 , 这表示迭代已经结束, 整个数据集(collection)已经被完整遍历过了。

以 0 作为游标开始一次新的迭代, 一直调用 SCAN 命令, 直到命令返回游标 0 , 我们称这个过程为一次完整遍历(full iteration)。

SCAN 命令的保证(guarantees)

SCAN 命令, 以及其他增量式迭代命令, 在进行完整遍历的情况下可以为用户带来以下保证:从完整遍历开始直到完整遍历结束期间, 一直存在于数据集内的所有元素都会被完整遍历返回;这意味着, 如果有一个元素, 它从遍历开始直到遍历结束期间都存在于被遍历的数据集当中, 那么 SCAN 命令总会在某次迭代中将这个元素返回给用户。

然而因为增量式命令仅仅使用游标来记录迭代状态, 所以这些命令带有以下缺点: 同一个元素可能会被返回多次。处理重复元素的工作交由应用程序负责, 比如说, 可以考虑将迭代返回的元素仅仅用于可以安全地重复执行多次的操作上。 如果一个元素是在迭代过程中被添加到数据集的, 又或者是在迭代过程中从数据集中被删除的, 那么这个元素可能会被返回, 也可能不会, 这是未定义的(undefined)。

SCAN 命令每次执行返回的元素数量

增量式迭代命令并不保证每次执行都返回某个给定数量的元素。

增量式命令甚至可能会返回零个元素, 但只要命令返回的游标不是 0 , 应用程序就不应该将迭代视作结束。

不过命令返回的元素数量总是符合一定规则的, 在实际中: 对于一个大数据集来说, 增量式迭代命令每次最多可能会返回数十个元素 而对于一个足够小的数据集来说, 如果这个数据集的底层表示为编码数据结构(encoded data structure,适用于是小集合键、小哈希键和小有序集合键), 那么增量迭代命令将在一次调用中返回数据集中的所有元素。

最后, 用户可以通过增量式迭代命令提供的 COUNT 选项来指定每次迭代返回元素的最大值。

COUNT 选项

虽然增量式迭代命令不保证每次迭代所返回的元素数量, 但我们可以使用 COUNT 选项, 对命令的行为进行一定程度上的调整。

基本上, COUNT 选项的作用就是让用户告知迭代命令, 在每次迭代中应该从数据集里返回多少元素。

虽然 COUNT 选项只是对增量式迭代命令的一种提示(hint), 但是在大多数情况下, 这种提示都是有效的。 COUNT 参数的默认值为 10 。 在迭代一个足够大的、由哈希表实现的数据库、集合键、哈希键或者有序集合键时, 如果用户没有使用 MATCH 选项, 那么命令返回的元素数量通常和 COUNT 选项指定的一样, 或者比 COUNT 选项指定的数量稍多一些。 在迭代一个编码为整数集合(intset,一个只由整数值构成的小集合)、 或者编码为压缩列表(ziplist,由不同值构成的一个小哈希或者一个小有序集合)时, 增量式迭代命令通常会无视 COUNT 选项指定的值, 在第一次迭代就将数据集包含的所有元素都返回给用户。

并非每次迭代都要使用相同的 COUNT 值

用户可以在每次迭代中按自己的需要随意改变 COUNT 值, 只要记得将上次迭代返回的游标用到下次迭代里面就可以了

MATCH 选项

和 KEYS 命令一样, 增量式迭代命令也可以通过提供一个 glob 风格的模式参数, 让命令只返回和给定模式相匹配的元素, 这一点可以通过在执行增量式迭代命令时, 通过给定 MATCH参数来实现。

以下是一个使用 MATCH 选项进行迭代的示例:

redis 127.0.0.1:6379> sadd myset 1 2 3 foo foobar feelsgood(integer) 6redis 127.0.0.1:6379> sscan myset 0 match f*1) "0"2) 1) "foo" 2) "feelsgood" 3) "foobar"

需要注意的是, 对元素的模式匹配工作是在命令从数据集中取出元素之后, 向客户端返回元素之前的这段时间内进行的, 所以如果被迭代的数据集中只有少量元素和模式相匹配, 那么迭代命令或许会在多次执行中都不返回任何元素。

以下是这种情况的一个例子:

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 10001) "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"

如你所见, 以上的大部分迭代都不返回任何元素。

在最后一次迭代, 我们通过将 COUNT 选项的参数设置为 1000 , 强制命令为本次迭代扫描更多元素, 从而使得命令返回的元素也变多了。

并发执行多个迭代

在同一时间, 可以有任意多个客户端对同一数据集进行迭代, 客户端每次执行迭代都需要传入一个游标, 并在迭代执行之后获得一个新的游标, 而这个游标就包含了迭代的所有状态, 因此, 服务器无须为迭代记录任何状态。

中途停止迭代

因为迭代的所有状态都保存在游标里面, 而服务器无须为迭代保存任何状态, 所以客户端可以在中途停止一个迭代, 而无须对服务器进行任何通知。

即使有任意数量的迭代在中途停止, 也不会产生任何问题。

使用错误的游标进行增量式迭代

使用间断的(broken)、负数、超出范围或者其他非正常的游标来执行增量式迭代并不会造成服务器崩溃, 但可能会让命令产生未定义的行为。

未定义行为指的是, 增量式命令对返回值所做的保证可能会不再为真。

只有两种游标是合法的:

1、在开始一个新的迭代时, 游标必须为 0 。

2、增量式迭代命令在执行之后返回的, 用于延续(continue)迭代过程的游标。

迭代终结的保证

增量式迭代命令所使用的算法只保证在数据集的大小有界(bounded)的情况下, 迭代才会停止, 换句话说, 如果被迭代数据集的大小不断地增长的话, 增量式迭代命令可能永远也无法完成一次完整迭代。

从直觉上可以看出, 当一个数据集不断地变大时, 想要访问这个数据集中的所有元素就需要做越来越多的工作, 能否结束一个迭代取决于用户执行迭代的速度是否比数据集增长的速度更快。

时间复杂度:

增量式迭代命令每次执行的复杂度为 O(1) , 对数据集进行一次完整迭代的复杂度为 O(N) , 其中 N 为数据集中的元素数量。

返回值:

SCAN 命令、 SSCAN 命令、 HSCAN 命令和 ZSCAN 命令都返回一个包含两个元素的 multi-bulk 回复:回复的第一个元素是字符串表示的无符号 64 位整数(游标), 回复的第二个元素是另一个 multi-bulk 回复, 这个 multi-bulk 回复包含了本次被迭代的元素。

SCAN 命令返回的每个元素都是一个数据库键。

SSCAN 命令返回的每个元素都是一个集合成员。

HSCAN 命令返回的每个元素都是一个键值对,一个键值对由一个键和一个值组成。

ZSCAN 命令返回的每个元素都是一个有序集合元素,一个有序集合元素由一个成员(member)和一个分值(score)组成。

更多用法可查看Redis SCAN命令:

http://doc.redisfans.com/key/scan.html

参考:

https://redis.io

https://www.dazhuanlan.com/2019/12/17/5df832fd189f6

​总结

到此这篇关于Redis的KEYS 命令千万不能乱用的文章就介绍到这了,更多相关Redis的KEYS 命令内容请搜索真格学网以前的文章或继续浏览下面的相关文章希望大家以后多多支持真格学网!

可以使用命令:redis-cli -p端口2113 -hIP地址 keys "*" |wc -l如果5261是集群:redis-cli -c -p端口 -hIP地址 keys "*" |wc -l(多了4102个-c)注意keys 命令只能列出1653当前的节点的key的数量本回答被提问者采纳,dbsize------------------------------------------------,自己用一个变量做计数器内容来自www.zgxue.com请勿采集。


  • 本文相关:
  • redis命令使用技巧之keys的相关操作
  • redis不使用 keys 命令获取键值信息的方法
  • windows环境下redis cluster环境搭建(图文)
  • redis 命令整理并说明如何使用
  • redis中五种数据类型简单操作
  • redis string 类型和 hash 类型学习笔记与总结
  • redis实现信息已读未读状态提示
  • 关于redis未授权访问漏洞利用的介绍与修复建议
  • 详解redis用链表实现消息队列
  • 详解ssh框架和redis的整合
  • redis sentinel实现高可用配置的详细步骤
  • 在redis集群中使用pipeline批量插入的实现方法
  • redis那个命令可以统计key的数量?
  • 如何批量删除redis中keys
  • redis命令行计算某个key占用多大的空间
  • Redis 如何获取记录 的个数?? 现在知道 keys pattern 可以获取该pattern的所以key,但是如何获取key个数
  • redis.keys返回为什么是一个集合
  • 如何批量删除Redis下特定pattern的keys
  • 如何批量删除Redis下特定pattern的keys
  • Redis 有没有什么命令可以查询当前库有多少个 key
  • 如何读取redis中的key值中的结果
  • 如何批量删除Redis下特定pattern的keys
  • 网站首页网页制作脚本下载服务器操作系统网站运营平面设计媒体动画电脑基础硬件教程网络安全mssqlmysqlmariadboracledb2mssql2008mssql2005sqlitepostgresqlmongodbredisaccess数据库文摘数据库其它首页redis命令使用技巧之keys的相关操作redis不使用 keys 命令获取键值信息的方法windows环境下redis cluster环境搭建(图文)redis 命令整理并说明如何使用redis中五种数据类型简单操作redis string 类型和 hash 类型学习笔记与总结redis实现信息已读未读状态提示关于redis未授权访问漏洞利用的介绍与修复建议详解redis用链表实现消息队列详解ssh框架和redis的整合redis sentinel实现高可用配置的详细步骤在redis集群中使用pipeline批量插入的实现方法超强、超详细redis数据库入门教程redis常用命令、常见错误、配置技redis操作命令总结redis中5种数据结构的使用场景介64位windows下安装redis教程redis中使用redis-dump导出、导入redis中统计各种数据大小的方法redis常用命令小结让redis在你的系统中发挥更大作用centos 6.6下redis安装配置记录redis启动流程介绍redis安装和配置_动力节点java学院整理redis基本类型和使用方法详解ubuntu下安装redis的2种方法分享redis3.2.6配置文件详细中文说明详解用redis实现session功能在cenos系统下安装和配置redis数据库的教利用redis如何实现自动补全功能redis全量复制与部分复制示例详解redis的lru机制介绍
    免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
    Copyright © 2017 www.zgxue.com All Rights Reserved