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

Redis里怎么快速拿到所有键和值,别复杂其实挺简单的

想在Redis里快速拿到所有键和值,最直接、最广为人知的方法就是使用 KEYS 命令,这个命令简单到像在电脑上按Ctrl+F搜索文件一样。(来源:Redis官方文档对KEYS命令的描述)

最“傻瓜”的方法:KEYS 配合 GET

你脑子里想的可能就是这两步:

  • 第一步:拿到所有的键。 打开你的Redis命令行(比如用redis-cli),输入:

    KEYS *

    这个号就像通配符,代表匹配所有键,回车之后,Redis会把当前数据库里所有的键名一个不拉地列出来。

  • 第二步:根据键名去拿值。 你再用一个叫GET的命令,挨个对着上面列表里的键,把值取出来,比如你看到一个键叫username,你就输入:

    GET username

    就能得到username对应的值。

这里有个巨大的“坑”,你必须知道!(来源:几乎所有Redis使用教程和最佳实践都会强调这一点)

KEYS * 这个命令在键很少的时候,比如就几百几千个,你用起来会觉得飞快,没问题,但如果你的Redis数据库里存了几十万、几百万甚至更多的键,这个命令就会成为一个“灾难命令”。

Redis里怎么快速拿到所有键和值,别复杂其实挺简单的

为什么是灾难呢?因为KEYS命令是阻塞式的,想象一下,Redis这个管家是在一个单线程的小房间里工作的,同一时间只能干一件事,你让他用KEYS *,就相当于命令他:“停下手里所有的话,把整个仓库里所有货物的清单目录给我手抄一份!” 在他埋头苦干抄清单的这段时间里,仓库大门是锁着的,其他所有想来存东西、取东西的客户(也就是你的其他应用程序)全得在门口傻等着,直到他抄完清单为止,如果仓库货物极多,这个等待时间可能会非常长,导致你的网站或应用卡死、超时。

*在任何正式的生产环境(就是你真正在线上运行的业务系统)中,绝对禁止使用`KEYS `命令。**

更安全、推荐的方法:SCAN

那既想拿到所有键值,又不想让服务器卡死,该怎么办呢?Redis提供了一个更好的工具叫SCAN。(来源:Redis官方文档为解决KEYS阻塞问题而引入了SCAN命令)

你可以把SCAN理解成一个“智能扫描器”,它不像KEYS那样一次性搬空仓库,而是每次只逛一小块区域,拿一小部分钥匙,然后告诉你:“我今天先逛到这,下次你从这个货架号开始继续逛。” 这样它就不会长时间霸占着管家(Redis单线程)不让干活。

它的用法是这样的:

Redis里怎么快速拿到所有键和值,别复杂其实挺简单的

  • 第一步:开始扫描。 你第一次输入:

    SCAN 0

    这里的0代表从最开始扫描,回车后,Redis会返回两部分东西:

    1. 一个数字,比如17,这个数字是“游标”(cursor),相当于下次扫描的起点位置,你不用管它具体是什么,记下来就行。
    2. 一个列表,里面是这次扫描找到的一部分键。
  • 第二步:继续扫描。 你把上一步拿到的那个游标数字(比如17),作为下一次SCAN命令的参数:

    SCAN 17

    它又会返回一个新的游标(比如35)和另一部分键。

  • 第三步:循环直到结束。 你就这样一次次地用新游标执行SCAN命令,直到某一次返回的游标变成0,当游标是0的时候,就恭喜你,代表整个数据库已经全部扫描完毕了。

这个过程就像翻一本很厚的书,你一次只看几页,而不是试图一次性把整本书的内容都塞进脑子里。

Redis里怎么快速拿到所有键和值,别复杂其实挺简单的

如何连键带值一起拿?

上面说的SCANKEYS都只拿到了键名,值还得用GET去取,如果你需要同时拿到键和值,有一个更高效的命令组合:SCAN + TYPE + 对应的获取命令。

因为Redis的值有不同类型,比如字符串(String)、哈希(Hash)、列表(List)等,取值的命令不一样。

  • 对于字符串(String),用GET keyname
  • 对于哈希(Hash),用HGETALL keyname 可以一次性拿到这个哈希的所有字段和值。
  • 对于列表(List),用LRANGE keyname 0 -1 可以拿到列表的所有元素。

一个更完整的流程是:

  1. SCAN命令遍历所有键。
  2. 对于SCAN返回的每一个键,先用TYPE keyname命令看看它是什么类型。
  3. 根据不同的类型,使用对应的命令(GET, HGETALL等)把值取出来。

有没有一键搞定所有键值的方法?

你可能想问,有没有一个命令能像KEYS *一样简单,但又不像它那么危险,能直接返回所有键值对呢?很遗憾,Redis官方并没有提供这样的一个万能命令,主要是因为数据结构和安全性的考虑。

有一个非查询性质的、用于备份的命令可以间接实现这个效果,那就是SAVEBGSAVE。(来源:Redis持久化机制)这两个命令会把内存中所有的数据以一种格式(RDB)完整地 dump(转储)到一个文件里,你可以用第三方工具来解析这个RDB文件,从而看到里面所有的键值,但这明显已经脱离了“在Redis里快速拿到”这个简单场景,属于数据备份和离线分析的范畴了,过程比较重,不适合实时查询。

  • 玩一玩、数据量小:用 KEYS * 列出所有键,然后挨个 GET,简单粗暴,但千万别在生产环境用。
  • 动真格的、数据量大:用 SCAN 命令分批遍历所有键,这是唯一正确、安全的选择,然后根据每个键的TYPE,用对应的命令(GET, HGETALL等)取值。
  • 记住核心原则:避免任何可能阻塞Redis服务器的操作,尤其是在你非常重要的业务系统上。

希望这个直接的解释能帮到你。