redis-cli --bigkeys在集群中仅扫描首个master节点的db0,因不识别redis cluster架构、不支持自动重定向或槽位跳转,加-c参数反而使其失效;须手动逐个直连各master节点执行,并配合memory usage等命令验证真实内存占用。

redis-cli --bigkeys 在集群中为什么只扫到一个节点
它根本不知道你在用 Redis Cluster。执行时默认连第一个 master 节点的 DB 0,不自动跳转、不识别槽位、不重定向。加 -c 参数反而会让 --bigkeys 失效——因为 -c 启用客户端重定向逻辑,而 --bigkeys 内部扫描依赖 KEYSPACE 遍历,重定向后无法保证采样一致性。
常见错误现象:
- 在 proxy(如 Codis/Twemproxy)上跑
redis-cli -c --bigkeys,直接报错或返回空 - 只扫完 node-0 就停手,结果线上 node-3 内存飙到 95%,却没线索
- 输出里显示
Biggest hash found 'order:batch:202604',但查CLUSTER KEYSLOT order:batch:202604发现它实际落在 node-2 上
实操建议:
- 先用
redis-cli -c -h {proxy} -p {port} cluster nodes拿到所有 master 的ip:port和角色 - 对每个 master 单独直连:例如
redis-cli -h 10.1.2.3 -p 7001 --bigkeys -i 0.01 - 别信“最大”二字——
--bigkeys只报每种类型“采样中最大的一个”,不是 Top N,更不反映真实内存
发现疑似 Big Key 后怎么验证是不是真大
--bigkeys 输出的字节数/元素数只是估算值,尤其对 Hash/List/ZSet 类型,完全不体现 value 大小或编码膨胀。比如一个有 4800 个字段的 Hash,字段值全是 base64 图片,--bigkeys 会标为“安全”,但 MEMORY USAGE 可能返回 22MB。
必须人工验证,步骤如下:
- 从输出中复制 key 名,在对应节点上执行:
MEMORY USAGE <key_name></key_name>(Redis 4.0+) - 对非 String 类型,补查结构规模:
HLEN <key_name></key_name>、ZCARD <key_name></key_name>、SCARD <key_name></key_name> - 用
OBJECT ENCODING <key_name></key_name>看底层编码:若 Hash 从ziplist切换到hashtable,内存可能翻倍 - 注意:
MEMORY USAGE返回的是近似值,含 key 名、过期时间、内部指针等开销,比纯 value 大 10%~30% 属正常
Hash 分桶拆分 Big Key 的实操要点
不能简单按时间或 ID 取模硬拆。要兼顾查询路径、更新频率和删除粒度。比如用户订单聚合 key user:1001:orders,直接按天拆成 user:1001:orders:20260520,会导致跨天查询必须合并 N 个 key,反而更慢。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
推荐做法是:用业务主键 + Hash 分桶组合,保留单次查询可定位性:
- 把原始 key 的业务主键(如订单 ID)做
hash_crc32(order_id) % 16,得到桶号 - 新 key 命名为
user:1001:orders:shard:0~:shard:15 - 读写时都走同一套计算逻辑,客户端完成路由,服务端无感知
- 避免使用
KEYS或SCAN扫描全量分桶——改用HGETALL或ZRANGE直接拉取,否则又引入新瓶颈
特别注意:拆分后要同步清理原 Big Key,但不能用 DEL。应分批 HSCAN + HDEL,每次不超过 1000 个 field,防止阻塞。
为什么拆分后还要持续监控
拆分只是缓解,不是根治。很多 Big Key 是“生长型”的:比如日志类 key 每天追加,半年后每个分桶又变成 5MB;或者用户关注列表随粉丝增长持续膨胀,分桶数固定就又失衡。
真正要做的,是把检测闭环跑起来:
- 每周定时脚本,遍历所有 master 节点执行
--bigkeys+MEMORY USAGE校验 - 把
used_memory_peak_human和各节点mem_fragmentation_ratio加入告警项 - 对高频访问的分桶 key(如
user:1001:orders:shard:0),额外埋点统计latency和size变化率
最易被忽略的一点:集群中某个节点内存突然升高,未必是本地产生了 Big Key,很可能是其他节点的某个 key 因哈希漂移或迁移失败,临时堆积在该节点的迁移缓冲区里——得结合 INFO replication 和 CLUSTER NODES 输出交叉看。










