当前位置:首页 > 问答 > 正文

Redis里那个keys方法到底是啥,怎么用又有哪些坑和妙用呢?

说到Redis里的KEYS命令,你可以把它想象成在一个巨大的、没有文件夹结构的仓库里,仅凭一个可能带有通配符的“物品名称描述”,就让你瞬间找出所有符合描述的钥匙,这些钥匙对应着仓库里每一个上锁的箱子(也就是Redis里的每一个key),这个命令非常直接,但也非常“危险”,用好了是神器,用不好就是一场灾难。

它到底是啥?

简单到不能再简单了,它的作用就是让你根据一个模式(pattern),来搜索并列出当前数据库中所有匹配的key,它的语法就长这样:KEYS pattern

这个pattern就是我们说的“通配符描述”,它支持三种主要的通配符:

  1. (星号):匹配任意数量的任意字符(零个、一个或多个)。user:* 会匹配到 user:1001user:profile:1002,甚至 user: 本身。
  2. (问号):匹配一个任意字符。user:10? 会匹配 user:100user:101,但不会匹配 user:10user:1001
  3. [ ] (中括号):匹配括号内的某一个字符。user:10[01] 只会匹配 user:100user:101

如果你想知道数据库里到底存了些什么,直接敲一个 KEYS *,所有key就都出来了。

怎么用?

使用起来极其简单,在任何Redis客户端里输入命令即可。

  • 查看所有以 session: 开头的key:KEYS session:*
  • 查看所有以 product_ 开头,后面跟着任意两个字符的key:KEYS product_??
  • 查看所有以 config: 开头,并且以 dbcache 结尾的key:KEYS config:*[db,cache]

有哪些坑?(这是重中之重!)

KEYS命令最大的,也是最著名的坑就是:它会阻塞Redis服务器。

根据Redis官方文档(来源:Redis官方文档对KEYS命令的说明)明确指出,KEYS命令在执行时,会遍历整个数据库中的所有key,这个过程是单线程、同步的,Redis是单线程模型来处理命令的,这意味着当你在一个存储了数百万甚至上亿个key的数据库上执行KEYS *时,Redis服务器在这段时间内(可能是几秒甚至几十秒)将无法处理任何其他请求(比如读取、写入、删除等),这会导致所有后续的命令都被阻塞住,整个服务就像“卡死”了一样,对于线上生产环境来说,这绝对是灾难性的,很可能引发服务雪崩。

有一个铁律:绝对不要在生产环境中使用KEYS命令,尤其是在你不知道数据库规模有多大的情况下,它只应该用于调试环境,或者在你百分百确定key的数量非常少的时候。

有哪些妙用?

尽管有巨大的风险,但KEYS命令在设计上和特定场景下依然有其不可替代的价值:

  1. 数据探查与紧急调试:当线上系统出现诡异的数据问题,而你完全摸不清头脑,不知道是哪些key出了问题的时候,在业务低峰期(并且做好可能短暂影响服务的心理准备和预案后),可以用KEYS配合通配符快速定位问题key的范围,这是一种“救命”的手段。
  2. 辅助脚本与数据迁移:在一些离线的数据维护脚本中,比如你需要将某一类符合特定模式的老数据批量迁移或清理,你可以先在一个从库(不影响主库服务的副本)上使用KEYS命令找出所有这些key的列表,然后再用脚本进行后续操作,但即使这样,也要小心,因为可能会拖垮从库。
  3. 理解数据模型:对于刚接手的Redis实例,或者在自己开发测试时,用KEYS命令可以非常直观地看到当前数据是如何组织的,比如看看有没有按照预期的命名空间(如 user:{id}order:{id})来存储,有助于理解业务逻辑。

生产环境里用什么替代?

正因为KEYS的阻塞问题,Redis从2.8版本开始引入了SCAN命令家族(包括SCAN, SSCAN, HSCAN, ZSCAN)。SCAN命令的核心妙处在于它是增量式、迭代式的,不会一次性遍历所有key,而是每次只返回一小部分,并提供一个游标(cursor)供下一次查询,虽然它可能会返回重复的key(需要客户端去重),并且不是实时精确的(遍历过程中如果有key被修改或删除,可能无法完全反映),但它最大的优点是不会阻塞服务器,可以安全地在生产环境中使用。

总结一下:KEYS是一把威力巨大但没有安全开关的武器,你应该清楚地知道它的危险性,在日常开发和生产环境中,请养成使用SCAN命令的习惯来替代KEYS,这才是专业和负责任的做法。

Redis里那个keys方法到底是啥,怎么用又有哪些坑和妙用呢?