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

想在 Redis 里找到某个值到底得怎么查才靠谱呢,实操分享给你看看

你知道准确的 Key(这是最理想的情况)

这就像你知道保险箱的钥匙是哪一把,这是 Redis 最快、最“靠谱”的查询方式。

操作命令(以命令行为例,代码里道理一样):

# 如果存的是字符串
GET user:1001:name
# 如果存的是哈希(Hash)里的一个字段
HGET user:1001 profile name
# 如果存的是整个对象(比如JSON字符串)
GET user:1001

啥时候用? 当你存储数据时,就已经规划好了后续要怎么取,用户注册后,你用一个固定的 Key 模式来存用户信息,像 user:{用户ID}:name,下次只要拿到用户 ID,你就能直接拼出 Key,瞬间拿到值。

靠谱总结:这是最快的“直达”方式,设计 Key 的时候,就得想好以后怎么用。

你不知道完整的 Key,但记得 Key 的大致模样

这就像你忘了保险箱钥匙具体是哪把,但记得钥匙串长啥样,这时候就得用 KEYS 命令,但这个命令要极度小心使用

操作命令:

# 查找所有以 "user:1001" 开头的 key
KEYS user:1001:*
# 查找所有包含 "cache" 的 key
KEYS *cache*
# 查找以 "session" 开头,以特定模式结尾的 key
KEYS session:???

为啥要小心? 因为 KEYS 命令会遍历数据库里的所有 Key,在一个有数百万甚至更多 Key 的生产环境里,这个命令会直接卡死 Redis 服务器,导致所有请求超时,它就像是在一个巨大的仓库里,不开灯,让你摸黑找一个箱子,你得把所有箱子摸一遍才行。

那怎么办?更靠谱的替代方案:SCAN

SCAN 命令是 KEYS 的安全版,它不会一次性返回所有结果,而是分批、游标式的扫描,不会阻塞服务器太久。

操作命令:

# 开始扫描,每次返回一部分匹配的 key 和下一个游标位置
SCAN 0 MATCH user:* COUNT 100
# 如果返回的游标不是0,就用返回的游标继续扫描,直到游标为0表示结束
SCAN 17 MATCH user:* COUNT 100

靠谱总结:在生产环境,忘掉 KEYS,用 SCAN,虽然慢点,但不会搞崩服务。

你不知道 Key,但你知道想找的“值”可能是什么

这是最棘手的情况,Redis 原生并不支持通过“值”来反查 Key,你不能像在数据库里那样“搜索内容”,那是不是就没辙了?也不是,有几种“曲线救国”的办法。

方法1:反向索引(最常用、最有效的设计技巧)

这招是解决问题的核心思路,你在存数据的时候,就多存一份“地图”。

  • 例子:你要通过用户名“张三”来查找用户信息。

  • 操作

    1. 正常存用户数据:SET user:1001 '{"name":"张三", "age":30}'
    2. 再存一个反向索引SET user:name:张三 1001 (这个 Key 的值是用户ID)
  • 查询时

    1. 先用 GET user:name:张三 拿到用户ID:1001。
    2. 再用 GET user:1001 拿到完整的用户信息。

方法2:使用 Redis 的集合(Set)或有序集合(Sorted Set)

如果你的值是某个集合的成员,可以通过集合来查。

  • 例子:查找属于“北京”这个城市的用户。
  • 操作
    1. 把用户ID加到“北京”这个集合里:SADD city:北京 1001 1002 1003
    2. 查询时:SMEMBERS city:北京,就能得到所有用户ID的列表,然后再用场景一的方法去取每个用户的详情。

方法3:忍痛全扫描(极端情况下的最后手段)

如果数据量不大,或者上面两种方法都没法用,你只能用脚本遍历所有 Key,然后检查它们的值。同样,要用 SCAN 而不是 KEYS

  • 操作思路(用 Lua 脚本或程序代码)
    1. SCAN 遍历所有 Key。
    2. 对每个 Key,用 TYPE 命令判断其数据类型。
    3. 根据不同类型,用 GET(字符串)、HGETALL(哈希)、LRANGE(列表)等命令取出值。
    4. 在程序内存中判断值是否匹配你的条件。

这个方法非常非常慢,效率极低,只能是万不得已时的选择。

终极靠谱建议

想在 Redis 里高效查值,功夫在诗外,关键取决于你如何设计数据存储结构

  1. 设计阶段多思考:在往 Redis 存数据之前,先问自己:“我以后会通过哪些条件来查这个数据?”
  2. 建立反向索引:这是解决复杂查询的银弹,多用几个 Key 的空间,换来查询的飞速提升,这笔买卖非常划算。
  3. 利用好合适的数据结构:不要什么都用 String 存,比如需要排序用 Sorted Set,需要关系用 Set/Hash,需要消息队列用 List/Stream。
  4. 远离 KEYSFLUSHALL:这是 Redis 运维的两大“自杀式”命令,一定要牢记。

在 Redis 里找值,更像是在一个设计好的地图上按图索骥,而不是在一个杂乱无章的仓库里大海捞针,你把“地图”(也就是索引)设计得越好,找起来就越“靠谱”。

想在 Redis 里找到某个值到底得怎么查才靠谱呢,实操分享给你看看