-
在 Redis 中,高效且安全地遍历所有 key 是一个需要谨慎处理的任务,因为如果操作不当,可能会对 Redis 的性能产生显著影响,尤其是在 key 数量非常庞大的情况下。一、使用 KEYS命令(不推荐在生产环境使用)命令: KEYS * 说明:KEYS命令会返回匹配指定模式(如 *表示所有 key)的所有 key。问题:KEYS是 阻塞式操作,如果你的 Redis 数据量很大(比如百万级以上的 key),这个命令会一次性将所有 key 加载到内存并返回,这会导致 Redis 长时间阻塞,无法处理其他请求,从而影响线上服务的可用性。结论:❌ 严禁在生产环境中使用 KEYS *,尤其是在数据量大的情况下。二、使用 SCAN命令(推荐方式)命令: SCAN cursor [MATCH pattern] [COUNT count] 说明:SCAN是一个 非阻塞的、基于游标的迭代器,用于渐进式地遍历 Redis 中的 key。它每次调用返回一小部分 key 和一个新的游标(cursor),你通过不断迭代调用 SCAN,直到游标返回 0,表示遍历完成。相比 KEYS,SCAN对 Redis 性能影响极小,适合生产环境使用。参数:cursor:游标,初始为 0,结束时也为 0。MATCH pattern(可选):匹配特定模式的 key,如 MATCH user:*。COUNT count(可选):建议每次返回的 key 数量,只是一个提示,不保证精确,一般可设为 100~1000。示例(伪代码 / redis-cli): # 第一次调用,cursor 从 0 开始 127.0.0.1:6379> SCAN 0 MATCH * COUNT 100 1) "17" # 下一次迭代的游标 2) 1) "key1" 2) "key2" ... (最多 COUNT 个 key) # 第二次用返回的游标继续 127.0.0.1:6379> SCAN 17 MATCH * COUNT 100 1) "0" # 游标为 0 表示遍历结束 2) 1) "key101" 2) "key102" 优点:✅ 非阻塞,不会长时间影响 Redis 服务。✅ 可控制每次返回的数量,降低单次操作开销。✅ 支持模糊匹配(通过 MATCH)。缺点:⚠️ 不保证强一致性:在遍历过程中,如果有 key 被增删改,可能会看到重复的 key 或者遗漏某些 key,但对大多数场景是可以接受的。⚠️ 需要客户端自行处理游标和多次调用。三、结合语言客户端使用 SCAN几乎所有 Redis 官方客户端(如 Python、Java、Node.js 等)都封装了 SCAN的迭代功能,使用起来更加方便。1. Python(redis-py): import redis r = redis.StrictRedis(host='localhost', port=6379, db=0) # 使用 scan_iter 方法(推荐,内部封装了 SCAN) for key in r.scan_iter(match="*", count=100): print(key.decode('utf-8')) scan_iter是一个生成器,会自动处理游标和多次 SCAN 调用,简化开发。2. Java(Jedis)示例: import redis.clients.jedis.Jedis; import redis.clients.jedis.ScanParams; import redis.clients.jedis.ScanResult; public class RedisScanExample { public static void main(String[] args) { Jedis jedis = new Jedis("localhost"); String cursor = "0"; ScanParams scanParams = new ScanParams().count(100).match("*"); do { ScanResult<String> scanResult = jedis.scan(cursor, scanParams); for (String key : scanResult.getResult()) { System.out.println(key); } cursor = scanResult.getCursor(); } while (!cursor.equals("0")); } } 四、其他注意事项与建议1. 避免在高峰期执行大规模遍历即使使用 SCAN,如果 key 数量极大(比如上千万),仍然可能造成一定负载。建议在业务低峰期进行,或者采用分片/分布式方式处理。2. 考虑使用 Redis 的 SCAN+ TYPE+ 具体命令如果你不仅想遍历 key,还想获取每个 key 的 value 或类型,可以结合 TYPE命令以及 GET/ HGETALL/ SMEMBERS等,但要注意:这会进一步增加 Redis 和客户端的负载。尽量不要在遍历过程中对 key 执行写入或删除操作,避免数据不一致。3. 大 key 问题如果你的 key 中包含大 value(如大 Hash、大 List 等),在遍历时获取其内容可能导致网络和内存问题,建议提前识别并优化大 key。4. 使用 Redis 的 dbsize查看 key 总数(仅总数,不列出 key) 127.0.0.1:6379> DBSIZE (integer) 1234567 这可以让你了解大致有多少 key,为遍历做准备,但注意它只是返回一个近似值。五、总结一下下方法是否阻塞是否推荐适用场景KEYS *是❌ 不推荐仅用于测试或极小数据量环境SCAN否✅ 推荐生产环境,安全遍历所有 key 生产环境一定要使用 SCAN,并尽量使用客户端提供的封装方法(如 scan_iter)。
-
Redisson 的 watchdog 什么情况下可能会失效?
-
Redisson 中为什么要废弃 RedLock,该用啥?
-
Redis Cluster 中使用事务和 Iua 有什么限制?
上滑加载中
推荐直播
-
华为云码道Skill实战与极速交付,智能开发全链路实战2026/07/22 周三 19:00-21:00
王一男-华为云码道产品规划专家;李炎-华为云码道产品专家;姜浩-华为云HCDG核心组成员
直播深度解读华为云码道6月产品新特性,从Skill市场安装专家技能,带你零距离体验从需求,开发,审查,重构全链路闭环的开发过程。从零构建并交付一个完整项目,让您体验从代码提交到服务上线的“极速”之旅。
回顾中 -
聚开发者之力,创具身新未来2026/07/23 周四 15:00-17:00
张豪杰/程文/王军/刘新春/黄钦开 /张晓天
本次华为云具身智能开发平台CloudRobo培训面向具身智能开发者,带您全流程体验机器人本体R2C小时级接入、环境重建与轨迹生成仿真数据生产、PB级数据管理、数据评测、模型训推、强化学习和Benchmark一键评测等功能,并体验业界主流具身模型应用。
回顾中
热门标签