
本文介绍如何利用 redigo 客户端在 go 程序中安全、高效地获取 redis 数据库中的全部键,并将其转换为字符串切片进行后续处理。
本文介绍如何利用 redigo 客户端在 go 程序中安全、高效地获取 redis 数据库中的全部键,并将其转换为字符串切片进行后续处理。
在 Go 应用中与 Redis 交互时,有时需要批量获取当前数据库(如 db 0)中所有匹配模式的键,最常见的是通配符 “*” —— 即列出全部键。Redigo 提供了底层 Do 方法执行任意 Redis 命令,但其返回值为 Interface{} 类型,需配合类型转换辅助函数(如 redis.Strings)才能安全解析为 []string。
以下是一个完整、可运行的示例:
package main import ( "fmt" "log" "github.com/garyburd/redigo/redis" ) func main() { // 初始化连接池(推荐生产环境使用) pool := &redis.Pool{ MaxIdle: 3, IdleTimeout: 240 * time.Second, Dial: func() (redis.Conn, error) { c, err := redis.Dial("tcp", "localhost:6379") if err != nil { return nil, err } // 显式选择数据库(可选,默认为 db 0) if _, err := c.Do("SELECT", 0); err != nil { c.Close() return nil, err } return c, nil }, TestOnBorrow: func(c redis.Conn, t time.Time) error { if time.Since(t) < time.Minute { return nil } _, err := c.Do("PING") return err }, } defer pool.Close() // 从连接池获取连接 conn := pool.Get() defer conn.Close() // 注意:此处 defer 在函数退出时关闭连接,非在 Do 后立即关闭 // 执行 KEYS * 命令并解析结果 keys, err := redis.Strings(conn.Do("KEYS", "*")) if err != nil { log.Fatalf("Failed to fetch keys: %v", err) } fmt.Printf("Found %d keys:n", len(keys)) for i, key := range keys { fmt.Printf("%d. %sn", i+1, key) } }
⚠️ 重要注意事项:
- KEYS 命令在 Redis 中是阻塞式全量扫描,时间复杂度为 O(N),当键数量极大(如百万级)时会导致 Redis 主线程卡顿,影响线上服务响应。*生产环境严禁直接使用 `KEYS `**。
- 替代方案应优先选用 SCAN 命令(配合游标分批迭代),它具备非阻塞、可中断、支持模式匹配等优势。Redigo 中可这样调用:
cursor := int64(0) var allKeys []string for { reply, err := redis.Values(conn.Do("SCAN", cursor, "MATCH", "*", "COUNT", 100)) if err != nil { log.Fatal(err) } var newCursor int64 var keys []string if _, err := redis.Scan(reply, &newCursor, &keys); err != nil { log.Fatal(err) } allKeys = append(allKeys, keys...) if newCursor == 0 { break } cursor = newCursor } - 使用连接池时,请确保 defer conn.Close() 放置在获取连接后的作用域内,避免提前释放或遗漏关闭。
- 若使用较新版本 Redigo(v1.8+),注意其已归档,社区推荐迁移至 github.com/go-redis/redis/v9;但若项目仍基于 Redigo,上述 redis.Strings 方案依然稳定可靠。
总结:redis.Strings(conn.Do(“KEYS”, “*”)) 是 Redigo 中获取全部键最直接的写法,适用于开发、调试或小规模数据场景;但在生产系统中,务必以 SCAN 替代 KEYS,兼顾功能完整性与服务稳定性。