redis 获取所有key(长文讲解)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战(已更新的所有项目都能学习) / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新开坑项目:《Spring AI 项目实战》 正在持续爆肝中,基于 Spring AI + Spring Boot 3.x + JDK 21..., 点击查看 ;
- 《从零手撸:仿小红书(微服务架构)》 已完结,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观
前言
在使用 Redis 进行开发时,我们常常需要快速获取数据库中的所有 Key,例如在调试、数据清理或统计分析场景中。然而,Redis 的 Key 获取并非简单的操作,不同的命令和方法会直接影响性能和系统稳定性。本文将从基础概念出发,结合实际案例,深入讲解如何高效安全地获取 Redis 中的所有 Key,并帮助开发者理解背后的设计逻辑。
一、Redis Key 获取的核心命令:KEYS 和 SCAN
1.1 KEYS 命令:直接获取所有 Key
命令语法:KEYS pattern
KEYS
是 Redis 最基础的 Key 获取命令,它会返回所有匹配给定模式的 Key。例如:
redis> KEYS *
1) "user:1001"
2) "session:abc123"
3) "cache:products"
优点:
- 简单直接:一行命令即可获取所有 Key,适合测试或小型数据集。
- 模式匹配:支持通配符(如
*
、?
),可筛选特定格式的 Key。
缺点:
- 阻塞问题:当数据库中 Key 数量庞大时,
KEYS
会阻塞 Redis 主线程,导致服务不可用。例如,一个包含 100 万 Key 的数据库,执行KEYS *
可能需要数秒甚至更久,期间 Redis 无法处理其他请求。 - 资源消耗大:返回大量数据时,内存和网络传输压力显著增加。
类比比喻:
想象你在图书馆中寻找所有书名包含“Redis”的书籍,KEYS
就像直接搬空整个书架,虽然能快速找到目标,但会打乱其他读者的借阅流程。
1.2 SCAN 命令:分批遍历 Key
为解决 KEYS
的阻塞问题,Redis 2.8 引入了 迭代器模式 的 SCAN
命令。它通过游标(Cursor)分批次返回 Key,避免一次性占用资源。
命令语法:SCAN cursor [MATCH pattern] [COUNT count]
cursor
:起始游标值(初始为0
),后续由 Redis 返回。MATCH
:可选参数,用于过滤 Key 模式。COUNT
:建议每次返回的 Key 数量(实际可能更多)。
示例代码:
redis> SCAN 0 MATCH user:* COUNT 10
1) "123"
2) ["user:1001", "user:1002", "user:1003"]
redis> SCAN 123 MATCH user:* COUNT 10
1) "456"
2) ["user:1004", "user:1005"]
...
优点:
- 低阻塞性:每次只处理少量 Key,主线程响应不受影响。
- 兼容模式匹配:支持类似
KEYS
的模式过滤。
关键点:
- 游标需要循环使用,直到返回
0
表示遍历完成。 COUNT
是建议值而非固定值,实际返回数量可能因 Redis 内部策略而变化。
1.3 KEYS 和 SCAN 的性能对比
场景 | KEYS | SCAN |
---|---|---|
小规模数据 | 快速高效 | 稍显冗余(需循环) |
大规模数据 | 高风险(阻塞服务) | 安全可靠 |
实时性要求 | 可能导致服务中断 | 平稳运行 |
资源消耗 | 内存和带宽压力大 | 渐进式消耗资源 |
类比比喻:
KEYS
像是“一次性搬空仓库”,而 SCAN
则是“分批次搬运”,既保证效率又不打乱仓库日常运作。
二、实战场景与代码示例
2.1 场景一:调试时快速查看 Key
需求:在本地开发环境中,快速查看所有以 cache:
开头的 Key。
redis> KEYS cache:*
1) "cache:users"
2) "cache:products"
注意事项:
- 本地测试环境 Key 数量少,
KEYS
是安全的。 - 生产环境避免直接使用
KEYS
,改用SCAN
。
2.2 场景二:清理过期 Key
需求:定期删除前缀为 temp:
且未设置过期时间的 Key。
实现思路:
- 使用
SCAN
遍历所有 Key,过滤出符合条件的 Key。 - 对每个 Key 执行
DEL
命令。
Python 实现示例:
import redis
client = redis.Redis(host='localhost', port=6379)
cursor = '0'
while cursor != 0:
cursor, keys = client.scan(cursor=cursor, match='temp:*', count=100)
if keys:
client.delete(*keys)
关键点:
- 通过
scan()
方法自动处理游标循环。 count
参数需根据业务调整,平衡遍历速度与资源消耗。
2.3 场景三:统计 Key 数量
需求:统计 Redis 中所有 Key 的总数。
方法:
redis> DBSIZE
(integer) 15000
DBSIZE
可直接返回当前数据库的 Key 数量,但无法统计特定模式的 Key。若需统计特定前缀的 Key 数量,则需结合 SCAN
:
count = 0
cursor = '0'
while cursor != 0:
cursor, keys = client.scan(cursor=cursor, match='user:*')
count += len(keys)
print(f"Total user keys: {count}")
三、进阶技巧与注意事项
3.1 使用 COUNT 参数优化遍历速度
SCAN
的 COUNT
参数控制每次返回的 Key 数量,默认值为 10
。增大 COUNT
可加快遍历速度,但会增加单次请求的资源占用。例如:
redis> SCAN 0 MATCH * COUNT 1000
建议:
- 小型数据集可设置
COUNT 1000
。 - 大型数据集建议逐步调整,观察系统负载后再决定。
3.2 结合 MATCH 和 TYPE 过滤 Key
若需过滤特定类型的 Key(如仅获取字符串类型的 Key),可结合 SCAN
和 TYPE
命令:
cursor = '0'
while cursor != 0:
cursor, keys = client.scan(cursor=cursor, match='user:*')
for key in keys:
if client.type(key) == b'string':
# 处理字符串类型 Key
pass
3.3 注意游标的边界条件
在使用 SCAN
时,需确保循环终止条件正确。例如,在 Python 中:
cursor = '0'
while cursor != '0': # 注意游标是字符串类型
cursor, keys = client.scan(cursor=cursor, ...)
若直接比较 cursor != 0
(整数),可能导致无限循环。
四、替代方案与高级用法
4.1 使用 Lua 脚本优化批量操作
若需同时获取并处理 Key(如删除),可编写 Lua 脚本减少网络往返:
local cursor = tonumber(ARGV[1])
local pattern = ARGV[2]
local count = tonumber(ARGV[3])
local result = redis.call('SCAN', cursor, 'MATCH', pattern, 'COUNT', count)
local keys = result[2]
redis.call('DEL', unpack(keys))
return result
在客户端调用:
script = """
... # 上述 Lua 脚本
"""
client.eval(script, 0, '0', 'temp:*', '100')
4.2 Redis 集群环境的 Key 遍历
在 Redis 集群中,SCAN
只能遍历单个节点的 Key。若需全局遍历,需结合 CLUSTER NODES
获取所有节点并分别执行 SCAN
。
结论
Redis 的 Key 获取操作看似简单,实则需要开发者根据场景选择合适的方法。对于开发调试或小数据量场景,KEYS
是快速有效的工具;但在生产环境中,SCAN
的分批次迭代模式能显著提升系统稳定性。通过结合模式匹配、类型过滤和 Lua 脚本优化,开发者可以灵活应对各种复杂需求。掌握这些技巧不仅能提升代码效率,还能避免因操作不当导致的性能问题。
关键总结:
- 小数据:
KEYS
简单直接。 - 大数据:
SCAN
安全高效,需循环处理游标。 - 生产环境:禁用 KEYS,优先使用迭代模式。
希望本文能帮助开发者在 Redis 开发中游刃有余地获取和管理 Key!