Redis现如今使用的场景越来越多?如何批量删除key呢?

有人说用KEYS命令,刚开始学Redis的时候就是用这个命令列出库中键。

KEYS命令要谨慎使用。

为何?客观别急,我们先一步步来看。

KEYS 命令

Warning: consider KEYS as a command that should only be used in production environments with extreme care. It may ruin performance when it is executed against large databases. This command is intended for debugging and special operations, such as changing your keyspace layout. Don't use KEYS in your regular application code. If you're looking for a way to find keys in a subset of your keyspace, consider using sets.

上面是官方文档声明,KEYS命令不能用在生产的环境中,这个时候如果数量过大效率是十分低的。同时也不要用KEYS正则匹配,官方建议直接用集合类型。

有人说 KEYS相当于关系性数据的库的 select *,在生产环境几乎是要禁用的。

  • KEYS命令的性能随着数据库数据的增多而越来越慢
  • KEYS命令会引起阻塞,连续的 KEYS命令足以让 Redis 阻塞

试想如果Redis阻塞超过10秒,如果有集群的场景,可能导致集群判断Redis已经故障,从而进行故障切换;

以上的情况严重会导致应用程序出现雪崩的情况。

然而,网上很多都是这么写的 redis-cli --raw keys "key前缀*" | xargs redis-cli del,千万别照炒,拿到生产环境上做实验。

顺便普及下xargs命令,这是Linux下的一个命令 。

xargs命令是给其他命令传递参数的一个过滤器,也是组合多个命令的一个工具。它擅长将标准输入数据转换成命令行参数,xargs能够处理管道或者stdin并将其转换成特定命令的命令参数。xargs也可以将单行或多行文本输入转换为其他格式,例如多行变单行,单行变多行。xargs的默认命令是echo,空格是默认定界符。这意味着通过管道传递给xargs的输入将会包含换行和空白,不过通过xargs的处理,换行和空白将被空格取代。xargs是构建单行命令的重要组件之一。

SCAN 命令

Redis从2.8版本开始支持scan命令,SCAN命令的基本用法如下:

  • 复杂度虽然也是 O(n),通过游标分步进行不会阻塞线程;

  • 有限制参数 COUNT ;

  • 同 keys命令 一样提供模式匹配功能;

  • 服务器不需要为游标保存状态,游标的唯一状态就是 scan 返回给客户端的游标整数;

scan用法

SCAN cursor [MATCH pattern] [COUNT count]
  • scan 命令提供三个参数,第一个是cursor,第二个是要匹配的正则,第三个是单次遍历的槽位
  • 第一个遍历是 cursor 值为0,然后将返回结果的第一个整数作为下一个遍历的游标,如果最后返回的到cursor的值为0就代表结束。
127.0.0.1:6379> scan 0 MATCH tony* 
1) "42"
2)  1) "tony25"
    2) "tony2519"
    3) "tony2529"
    4) "tony2510"
    5) "tony2523"
    6) "tony255"
    7) "tony2514"
    8) "tony256"
    9) "tony2511"
   10) "tony15"
127.0.0.1:6379> scan 42 MATCH tony* COUNT 1000
1) "0"
2)  1) "tony3513"
    2) "tony359"
    3) "tony4521"
    4) "tony356"
    5) "tony30"
    6) "tony320"
    7) "tony3"
    8) "tony312"

返回分为两个部分如上面的代码中, 1)代表下一次迭代的游标,2)代表本次迭代的结果集
,注意如果返回游标为0就代表全部匹配完成。

批量删除scan命令

因为KEYS命令的时间复杂度为O(n),而SCAN命令会将遍历操作分解成m次,然后每次去执行,从而时间复杂度为O(1)。也解决使用keys命令遍历大量数据而导致Redis服务器阻塞的情况。所以建议使用下边的指令进行批量的删除操作:

redis-cli --scan --pattern "key前缀*" | xargs -L 1000 redis-cli del

总结

因为Redis是但线程的KEYS在某种情况下会阻塞。有个真实真案件小哥哥生产用KEYS,最终导致服务宕机。后果很严重,产生的经济损失就不说了。

切记严重会导致程序的雪崩,删除的时候用SCAN命令,看完这篇文章应该都记住了。

Redis开发的建议

1、 数据分离


不要什么都往Redis中放,尽量放些QPS比较高的数据,内存的开销很昂贵的,可以考虑硬盘存放。


2、分业务

不同的实例单独放这样存取的时候方便些,故障的时候也不会影响其他的实例。


3、压缩

redis中有很大的单个key的值建议压缩成二进制存放。


4、失效时间

redis中设置key的失效时间,如果不设置会一直占用着内存,而且key的失效时间应该根据业务场景来设置。


5、容量

占用内存不要太大10-20G,其次键的数量控制在1千万以内。


6、监控

运维合理的监控好数据,做好Redis安全漏洞的防护和灾备。

Redis 千万不要乱用KEYS命令,不然会挨打的的更多相关文章

  1. Redis 的 KEYS 命令不能乱用啊

    KESY 命令 时间复杂度: O(N) , 假设Redis中的键名和给定的模式的长度有限的情况下,N为数据库中key的个数. Redis Keys 命令用于查找所有符合给定模式 pattern 的 k ...

  2. Redis的KEYS命令引起宕机事件

    摘要: 使用 Redis 的开发者必看,吸取教训啊! 原文:Redis 的 KEYS 命令引起 RDS 数据库雪崩,RDS 发生两次宕机,造成几百万的资金损失 作者:陈浩翔 Fundebug经授权转载 ...

  3. 关于redis的keys命令的性能问题

    KEYS pattern 查找所有符合给定模式 pattern 的 key . KEYS * 匹配数据库中所有 key . KEYS h?llo 匹配 hello , hallo 和 hxllo 等. ...

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

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

  5. Redis 禁用FLUSHALL FLUSHDB KEYS 命令

      (error) ERR unknown command 'keys'问题解决(error) ERR unknown command 'FLUSHDB' 问题解决 背景 FLUSHALL FLUSH ...

  6. redis拾趣(客户端连接,keys命令,数据备份,缓存有效期等)

    1.客户端连接 为了安全保护,redis支持绑定IP跟端口,这个通过conf配置文件中的bind跟port来设置. 绑定后登录client控制台时就需要写明ip(或者hostname)跟端口了,如: ...

  7. Redis Keys 命令 - 查找所有符合给定模式( pattern)的 key

    Redis Keys 命令用于查找所有符合给定模式 pattern 的 key .. 语法 redis KEYS 命令基本语法如下: redis 127.0.0.1:6379> KEYS PAT ...

  8. redis中keys命令带来的线上性能问题

    起因 下午接到运维反馈,生产redis有个执行keys的命令请求太慢了,要两三秒才能响应 涉及命令如下: KEYS ttl_600::findHeadFootData-15349232-*-head ...

  9. redis-避免生产环境使用keys命令

    redis作为内存数据库, 有着很高的性能, Redis能读的速度是110000次/s, 写的速度是81000次/s; 除了进行持久化操作时, redis采用的是单线程架构, 所以如果我们在开发中不恰 ...

随机推荐

  1. linux 一些简单操作

    vim   ----三种模式 1.命令模式           2.输出模式       3.底线命令模式 w(e) 移动光标到下一个单词 b 移动到光标上一个单词 数字0 移动到本行开头 $ 移动光 ...

  2. LRJ-Example-06-13-Uva1103

    pic[][]数组存储每个点的值,0或1,输入时在原图的周围加了一圈0. color[][]数组存储每个点的color值,从1开始,dfs(row, col, c) 负责对每个点着色,连通在一起的连通 ...

  3. H3C 无线覆盖原则-蜂窝式覆盖

  4. ∆ (triangle)

    2.1 题目描述 给定一个无自环重边的无向图,求这个图的三元环1的个数以及补图2的三元环个数. 2.2 输入格式 第一行 2 个数 n, m ,分别表示图的点数.边数. 接下来 m 行,每行两个数 u ...

  5. NIO 中文乱码自我解决的简单DEMO

    import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStrea ...

  6. 2019-10-30-C#-dotnet-core-局域网组播方法

    title author date CreateTime categories C# dotnet core 局域网组播方法 lindexi 2019-10-30 9:0:48 +0800 2019- ...

  7. webpack学习(一)项目中安装webpack

    如何在项目中安装webpack,webpack-cli? 前提:电脑安装了 node和npm包管理工具 1 创建项目文件夹或者在已有的项目中打开终端  输入相关命令: npm init 因为已经安装好 ...

  8. Python--day46--mysql存储过程(不常用)(包含防sql注入)

    一.存储过程: 优点:只要传很少的数据到数据库就可以了  缺点:dba管理数据库的时候可能会对数据库进行了更改了那一坨sql语句. 二.创建存储过程: 1.简单 创建存储过程: Python中使用结果 ...

  9. H3C端口状态迁移

  10. HDU - 4587 TWO NODES (图的割点)

    Suppose that G is an undirected graph, and the value of stab is defined as follows: Among the expres ...