keys命令在主节点上会彻底阻塞redis服务,因其单线程模型下需o(n)遍历全量键空间,导致所有请求(含同步、心跳)中断,超时可能触发哨兵脑裂;它仅支持key名字符串匹配,不识别value类型,无法按数据类型筛选,且禁用须通过redis.conf中rename-command keys ""硬性配置。

KEYS 命令在主节点上会彻底阻塞 Redis 服务
Redis 是单线程模型,KEYS 命令时间复杂度为 O(N),它必须遍历整个键空间逐个比对 pattern。一旦执行,主线程无法处理任何其他请求——包括 GET、SET、心跳检测、从节点同步请求等。主节点卡住超过 down-after-milliseconds(默认 30s),哨兵就会触发故障转移;若此时从节点也尚未完成全量同步,极易引发脑裂。
匹配数据类型不是 KEYS 的能力范围
KEYS 只能按 key 名做字符串模式匹配,完全不感知 value 类型。KEYS user:* 返回的可能是 string、hash、zset 混杂的 key 列表,但你无法从中区分哪些是 hash 类型。想按类型筛选,必须额外对每个 key 执行 TYPE 命令——这又引入 N 次额外调用,放大阻塞风险。
- 错误做法:
redis-cli keys "user:*" | xargs -I{} redis-cli type {} - 更糟的是:该管道在客户端侧拼接,若 key 数量达百万级,xargs 可能因参数超长失败或触发 shell 限制
SCAN 也不能直接替代“按类型查 key”
SCAN 虽非阻塞,但它同样只支持 key 名匹配,不支持类型过滤。常见误区是以为加个 COUNT 1000 就安全了,其实不然:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
-
SCAN 0 MATCH "user:*" COUNT 1000每次返回最多 1000 个 key,但其中可能 0 个是hash类型 - 若业务真需定位某类 key(如所有
hash结构的用户配置),应提前用集合维护:SADD user_hash_keys user:123 user:456,再用SMEMBERS获取——但要注意避免bigkey问题 -
SCAN的COUNT并非精确值,实际返回数量受哈希表稀疏程度影响,设为 1000 不代表每次真返回 1000 个
禁用 KEYS 必须落地到配置层
仅靠规范或代码审查不可靠。必须在 redis.conf 中显式禁用:
rename-command KEYS ""
注意以下细节:
- 该配置需在所有主从节点统一生效,集群环境尤其不能遗漏某个分片节点
- 重启 Redis 才生效;热重载(
CONFIG REWRITE)不支持rename-command变更 - 禁用后,任何客户端调用
KEYS都会收到(error) ERR unknown command `KEYS`,而非慢查询日志记录 - 不要用
rename-command KEYS "my_keys"伪装,运维和监控系统仍可能误用
真正棘手的从来不是“找不到 key”,而是“找到之后才发现根本没法安全地批量操作”——比如想删掉所有过期 session,用 SCAN + DEL 循环本身就有并发竞争风险,更别说误删。设计阶段就该用带 TTL 的命名空间隔离,而不是依赖运行时扫描补救。










