Redis 模式匹配:KEYS vs SCAN 及 Go 实战示例

简介: Redis支持通配符匹配(*、?、[])查找key,但`KEYS`命令会阻塞服务,严禁用于生产;推荐使用非阻塞的`SCAN`命令分批遍历,配合规范命名(如`user:1001:profile`)和合理COUNT值,确保线上稳定。

在使用 Redis 时,我们经常需要按某种命名规则查找一批 key,比如:

  • user:1001:profile
  • user:1002:profile
  • session:abc123
  • session:def456

此时就需要用到 Redis 的模式匹配(Pattern Matching)功能。Redis 提供了两个关键命令:KEYS 和 SCAN。它们都能匹配 key,但使用场景和风险差异巨大。


🔍 1. 通配符匹配规则

Redis 支持以下通配符:

模式 含义 示例匹配(pattern = "user:*")
* 匹配任意数量字符(含 0) user:1, user:100:info, user:
? 匹配单个字符 user:a? → user:a1, user:ab ✅;user:abc ❌
[abc] 匹配括号中任一字符 log:[123] → log:1, log:2 ✅
[a-z] 匹配区间内任一字符 temp:[a-c] → temp:a, temp:c ✅

💡 实际开发建议:统一 key 命名规范,比如 namespace:id:field,让匹配更可靠。


⚠️ 2. KEYS 命令:快但危险!

KEYS user:*
  • ✅ 简单直接:一次性返回所有匹配 key
  • ❌ 阻塞 Redis 单线程!大数据量时可能导致服务卡顿甚至超时
  • 🚫 严禁在生产环境使用(除非你 100% 确认 key 总数极少)

✅ Go 示例(仅限开发/调试)

package main

import (
    "context"
    "fmt"
    "github.com/redis/go-redis/v9"
)

func main() {
   
    rdb := redis.NewClient(&redis.Options{
   
        Addr: "localhost:6379",
    })

    ctx := context.Background()
    keys, err := rdb.Keys(ctx, "user:*").Result()
    if err != nil {
   
        panic(err)
    }

    fmt.Println("Found keys:", keys)
    // Output: [user:1001:profile user:1002:profile]
}

📌 注意:Keys() 是 KEYS 命令的封装,切勿用于线上。


✅ 3. SCAN 命令:安全、分批、推荐!

SCAN 0 MATCH user:* COUNT 10
→ 返回 [cursor, [key1, key2, ...]]
  • ✅ 非阻塞:每次只查一小批,不影响线上服务
  • ✅ 游标迭代:直到 cursor 回到 0 表示结束
  • ✅ 完美适配生产环境大规模 key 遍历

Go 实战:安全遍历所有匹配 key

package main

import (
    "context"
    "fmt"
    "github.com/redis/go-redis/v9"
)

func scanKeys(ctx context.Context, rdb *redis.Client, pattern string, count int64) ([]string, error) {
   
    var keys []string
    var cursor uint64 = 0

    for {
   
        var err error
        var scanned []string
        scanned, cursor, err = rdb.Scan(ctx, cursor, pattern, count).Result()
        if err != nil {
   
            return nil, err
        }

        keys = append(keys, scanned...)

        // cursor == 0 表示迭代结束
        if cursor == 0 {
   
            break
        }
    }

    return keys, nil
}

func main() {
   
    rdb := redis.NewClient(&redis.Options{
   
        Addr: "localhost:6379",
    })
    ctx := context.Background()

    keys, err := scanKeys(ctx, rdb, "user:*", 10) // 每次最多查 10 个
    if err != nil {
   
        panic(err)
    }

    fmt.Println("Scanned keys:", keys)
    // Output: [user:1001:profile user:1002:profile]
}

⚙️ 参数说明:

  • cursor: 初始为 0,后续用上一次返回的 cursor
  • pattern: "user:*", "session:*" 等
  • count: 建议值(非精确),如 10/100。太小效率低,太大影响性能。

✅ 即使 Redis 有百万 key,SCAN 也能零感知完成遍历。


🛠️ 4. 最佳实践总结

项目 建议
✅ 生产环境 只用 SCAN,禁用 KEYS
✅ 命名规范 使用层级命名:{type}:{id}:{field}(如 order:20251203001:status)
✅ 性能调优 COUNT 初始可设 100;若响应慢,调低至 10~50
✅ 防误用 代码审查时 grep "KEYS",或通过 Redis 配置禁用:rename-command KEYS ""

🔚 结语

  • 想快速查几个 key?👉 KEYS(仅本地/测试)
  • 想安全遍历海量 key?👉 SCAN + Go 循环(生产唯一选择)

掌握这个模式,能帮你避免 Redis 线上事故,写出更健壮的缓存层代码!


相关文章
|
Ubuntu 应用服务中间件 项目管理
部署gitlab详解
部署gitlab详解
部署gitlab详解
|
小程序 JavaScript
小程序自定义弹窗禁止底部内容滚动(滚动穿透问题)
小程序自定义弹窗禁止底部内容滚动(滚动穿透问题)
2511 0
|
人工智能 开发者
文章和 PPT 配图有救了!SVG 绘图专家智能体大揭秘
本文分享如何使用 DeepSeek-V3-0324 和 Claude 3.5 或 3.7 绘制出高质量的图片,可以作为文章配图也可以为 PPT 配图,效率成倍增长。文章还介绍了原型图绘制、图片重绘修改和彩色报纸风的进阶案例。希望本文提供的技巧对大家有帮助,大家也可以修改提示词定制自己喜欢的风格。
1908 13
|
8月前
|
缓存 监控 Java
Java 性能天花板:JIT 即时编译、分层编译与代码缓存深度调优指南
JIT即时编译是Java性能优化的核心机制,本文深入解析了JIT的工作原理与优化技术。文章首先介绍了Java的双重执行模型,对比了解释执行与JIT编译的差异。重点讲解了分层编译机制,包括5个编译层级及其流转规则。针对代码缓存管理,详细说明了分段式架构和监控方法。通过JMH基准测试展示了方法内联、逃逸分析等核心优化技术的实际效果,其中方法内联性能提升10-20倍,逃逸分析优化可达50倍。最后提供了线上常见JIT问题的排查方案,强调JDK17默认参数已优化大部分场景,调优需基于监控数据。
879 1
|
9月前
|
Kubernetes 应用服务中间件 nginx
最全的kubectl命令用法
本文系统讲解kubectl命令行工具:详解所有子命令(创建、查询、部署、调试等)、API资源列表、自动补全配置,并通过大量实操示例(如创建/查看/编辑/删除资源、扩缩容、回滚、标签管理等)助你快速掌握Kubernetes集群管理核心技能。(239字)
1203 143
|
8月前
|
缓存 项目管理 开发工具
UV实战教程,我啥要从Anaconda切换到uv来管理包?
本文对比Anaconda“手动挡”与uv“全自动挡”环境管理:uv以“项目即环境”为核心,支持`uv init`一键初始化、自动下载Python、智能依赖管理(`uv add/sync/run`)及PyCharm无缝对接,大幅提升Python开发效率与协作体验。(239字)
2004 11
UV实战教程,我啥要从Anaconda切换到uv来管理包?
|
7月前
|
人工智能 监控 前端开发
大模型应用:基于安诊儿AntAngelMed模型+FastAPI构建慢病管理AI助手.86
本项目基于安诊儿AntAngelMed医疗大模型(临床一致率达88.9%),结合FastAPI后端与轻量前端,构建7×24小时慢病AI助手。支持糖尿病、高血压等居家咨询,提供专业、可读、结构化建议,并实时统计Token消耗,兼顾实用性与成本可控性。
922 2
|
8月前
|
人工智能 IDE 程序员
Agent Apps:Agent 时代,大家都在造工具箱,但真正缺的是“工作台”
Agent时代,工具层出不穷,但真正缺失的是Agent的“工作台”——Agent App。它不是工具集合、技能包或大一统Agent,而是为AI构建可操作、有状态、带上下文与视图的原生工作环境,让Agent真正“上岗干活”。
804 8
Agent Apps:Agent 时代,大家都在造工具箱,但真正缺的是“工作台”
|
8月前
|
SQL 中间件 PHP
PHP框架应用实战——以Laravel为例快速开发后台系统
随着PHP应用复杂度的提升,单纯使用原生PHP开发,会出现代码冗余、维护困难、扩展性差等问题,而PHP框架的出现,很好地解决了这些问题。Laravel作为目前最流行的PHP框架之一,以其优雅的语法、完善的功能、强大的生态,成为PHP开发者的首选框架。
421 0