redis-cli --bigkeys在集群中仅扫描当前连接的master节点DB0,不识别槽位分布、不自动跳转重定向,故无法定位全集群大Key;须手动逐个直连各master节点执行,并用MEMORY USAGE验证真实内存占用。

直接用 redis-cli --bigkeys 在集群任一节点上执行,无法准确定位真正的大 Key——它只扫描当前连接的节点,而集群模式下 Key 是分片(shard)分布的,你看到的只是局部视图。
为什么 redis-cli --bigkeys 在集群里容易漏掉大 Key
Redis 集群默认使用 CRC16 算法对 Key 做哈希后取模分片,同一个 Key 一定落在固定 slot,但 --bigkeys 不会自动遍历所有节点。如果你只连 nodeA 扫描,那 nodeB/C 上的 user:profile:9999(占 8MB 的 Hash)就完全不会出现在结果里。
- 它底层依赖
SCAN,而集群中SCAN只作用于当前节点的本地数据 - 输出里的 “Biggest hash found” 统计的是本节点内最大,不是全集群最大
- 不支持自动聚合各节点结果,也没有 slot 范围参数可指定
正确做法:逐个节点执行 + 汇总分析
必须手动连接每个 master 节点,分别运行 --bigkeys,再人工或脚本合并结果。这是目前最可靠、零依赖的线上方案。
- 先用
redis-cli -c -h {host} -p {port} cluster nodes拿到所有 master 节点 IP:PORT 列表 - 对每个 master 执行:
redis-cli -h {ip} -p {port} -a {auth} --bigkeys -i 0.1(-i 0.1降低扫描干扰) - 把每次输出重定向到独立文件,比如
node1_bigkeys.log,再用grep "Biggest"提取关键行 - 重点看
bytes和fields字段,字符串类超过1048576(1MB)、集合类超过5000元素的,优先标记为高危
更准但需 Redis 4.0+:用 MEMORY USAGE 逐 key 校验
--bigkeys 只给估算值,真要确认某个 Key 占多少内存,必须用 MEMORY USAGE。但它不能批量扫,得先有候选 Key 列表。
- 先用
--bigkeys各节点扫出 Top 20 候选 Key,再对这些 Key 分别执行:redis-cli -h {ip} -p {port} MEMORY USAGE key_name - 注意:
MEMORY USAGE对集合类型返回的是近似值(抽样估算),但比--bigkeys的统计维度更贴近真实内存开销 - 如果某 Key 的
MEMORY USAGE返回值远高于其STRLEN或HLEN推算值(比如 Hash 的字段数不多但内存超大),说明存在大量小对象的元数据开销或编码膨胀,也属于典型 BigKey
容易忽略的陷阱:别在主从同步延迟高的节点上扫
集群中某些节点可能因网络抖动或磁盘慢导致从库 lag 较高,此时用 --bigkeys 扫出来的 Key 可能是旧快照状态,已删除的大 Key 还显示在结果里,或者新写入的大 Key 尚未同步过来。
- 执行前先检查:
redis-cli -h {ip} -p {port} info replication | grep "master_repl_offset\|slave_repl_offset",确保 offset 差值 - 避免在 slave 节点上执行扫描——
--bigkeys要求读写权限,且 slave 默认slave-read-only yes,可能报错(error) READONLY You can't write against a read only slave. - 如果集群启用了
cluster-require-full-coverage no,部分 slot 不可用时--bigkeys会静默跳过,导致漏扫,务必提前确认所有 slot 状态为ok
真正难的不是发现单个大 Key,而是判断它是否“正在生长”——比如一个不断 HSET 的用户行为 Hash,今天 3000 字段,明天就破万。这类 Key 必须结合监控(如每分钟 HLEN 变化率)和慢日志(SLOWLOG GET 10 中出现 HGETALL 耗时 >10ms)交叉验证,否则等它爆掉才看到,已经晚了。











