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

Redis里想知道所有key咋查,命令和方法都有哪些呢?

在Redis里,如果你想查看数据库里存了哪些key,有几个命令可以用,但每个都有自己的特点和使用时需要注意的地方,最直接、最广为人知的命令就是 KEYS 命令。

(来源:Redis官方文档 KEYS命令) KEYS 命令的用法很简单,你只需要在命令行里输入 KEYS 后面跟一个模式(pattern),如果你想查看所有的key,就用通配符星号(),也就是输入 `KEYS ,这个命令会把你当前连接的数据库里所有的key的名字都列出来,你存了user:1001product:abcsession:xyz这些key,执行KEYS 后,它们就会全部显示在屏幕上,你还可以用更复杂的模式,比如KEYS user:` 来只查找所有以 "user:" 开头的key。

*非常重要的一点是,在生产环境中要极其小心地使用 `KEYS 命令。(来源:Redis官方警告以及众多运维实践)** 为什么呢?因为Redis是单线程的,它可以同时处理很多个客户端的连接请求,但实际执行命令的只有一个核心线程,当你执行KEYS 的时候,如果数据库里的key数量非常庞大,比如有几百万、几千万个,这个命令会一次性把所有key的名字都捞出来,这个过程可能会需要好几秒钟甚至更长时间,在这段时间里,Redis的这个主线程就被KEYS命令完全占用了,无法处理其他的任何读写请求,比如有用户要登录、要查询数据,这些操作全部会被阻塞住,直到KEYS命令执行完,这就会导致服务像卡住了一样,对于线上正在使用的系统来说,这简直是灾难性的,很可能引起服务超时甚至中断,通常只有在开发、测试环境,或者你非常确定当前Redis实例没有重要负载时,才敢小心地使用KEYS `。

正因为 KEYS 命令有这种在生产环境下使用的风险,Redis从2.8版本开始提供了一个更安全、更适合在生产环境中使用的替代命令——SCAN

(来源:Redis官方文档 SCAN命令) SCAN 命令的设计思路和 KEYS 一次性返回所有结果完全不同,它采用了一种叫做“迭代”的方式,你可以把它想象成翻一本很厚的书,KEYS 命令是让你一口气把整本书的所有页码内容都背下来,而 SCAN 是让你一页一页地翻看,每次只看一小部分。SCAN 命令每次执行只返回一小部分key(数量可以大致控制),同时还会返回一个“游标”(cursor),当你下次想继续获取剩下的key时,需要带着这个游标再次执行 SCAN,这样分批处理的好处是,每次操作只占用很少的服务器资源,不会长时间阻塞Redis,其他请求可以正常处理,不会对服务性能造成明显影响。

SCAN 命令的基本用法是 SCAN [游标],第一次使用 SCAN 命令都是基于Redis客户端命令行交互的语境,使用口语化、生活化的表达,就像你在和朋友聊天或者自言自语一样自然切换语气,可以加入思考过程,但最终输出必须是合规的。

  • 避免使用复杂的编程术语,用比喻和日常语言解释。
  • 每次执行 SCAN 命令,它都会返回两个东西:一个是下一个需要使用的游标值,另一个是一个列表,里面包含本次扫描到的部分key,当返回的游标值是0时,就表示所有的key都已经遍历完毕,迭代结束了,举个例子,你第一次输入 SCAN 0,它可能返回 (5, [key1, key2, key3]),意思是“我从头开始扫,找到了3个key,下次你从第5个位置继续扫”,然后你接着输入 SCAN 5,它可能返回 (0, [key4, key5]),这时游标是0,并且又给了你两个key,这就说明全部key都找完了,虽然看起来比 KEYS 麻烦一点,需要多次操作,但这是为了保证服务稳定性的一个必要妥协。SCAN 命令也同样支持模式匹配,SCAN 0 MATCH user:* 就能分批找出所有以 user: 开头的key。

除了上面这两个核心命令,还有一些相关的信息值得了解,Redis默认有16个数据库,编号从0到15。(来源:Redis官方文档 SELECT命令) 你上面用的 KEYSSCAN 默认只针对当前选中的数据库(默认是0号库)进行操作,如果你想知道当前Redis实例中所有数据库的key的总数,或者某个特定数据库里大概有多少个key,可以使用 INFO 命令。(来源:Redis官方文档 INFO命令) 输入 INFO keyspace,它会返回类似 db0:keys=100,expires=0 这样的信息,告诉你0号数据库有100个key,其中0个设置了过期时间,这能让你快速对数据量有个整体把握,而不用真的去遍历所有key。

需要特别注意的是,无论 KEYS 还是 SCAN,它们返回的都只是key的名字,并不会直接返回key对应的值,如果你想知道某个key里面存的是什么,需要再使用 GET(对于字符串类型)、HGETALL(对于哈希类型)、LRANGE(对于列表类型)等相应的数据读取命令。

在Redis里查所有key:

  1. 快速但有风险的方法:用 KEYS *,仅限测试或空库使用。
  2. 安全且推荐的方法:用 SCAN 命令分批迭代,适合任何环境。
  3. 辅助方法:用 INFO keyspace 查看各个数据库的key数量统计。

在生产环境中,对待 KEYS * 一定要像对待一把锋利的刀一样,非常小心,最好避免直接使用,而是养成使用 SCAN 的习惯。

Redis里想知道所有key咋查,命令和方法都有哪些呢?