BigKey 的发现与处理
BigKey 会显著影响 Redis 服务的性能和稳定性,甚至可能导致服务降级或宕机。本文档介绍了 BigKey 的概念、检测方法以及在生产环境中的最佳处理实践。
目录
什么是 BigKey
Redis 中的 BigKey 并非指键本身很大,而是指该键对应的值的大小。BigKey 通常根据两个维度评估:内存占用和元素数量。常见阈值包括:
- String:大小超过 5MB
- List:元素数量超过 20,000
- Set:元素数量超过 10,000
- Sorted Set:元素数量超过 10,000
- Hash:字段数量超过 10,000
注意:以上阈值仅作为参考,具体可根据您的环境和需求进行调整。
BigKey 的影响
BigKey 会从多个方面影响 Redis 服务的性能和稳定性:
- 线程阻塞:Redis 采用单线程模型处理数据,BigKey 操作耗时较长,会阻塞其他命令的执行,导致整体服务性能下降。
- 客户端超时:由于单线程架构,BigKey 操作可能导致 Redis 无法及时响应客户端请求,进而引发连接超时。
- 网络带宽饱和:传输 BigKey 会消耗大量网络带宽。例如,1MB 大小的 Key 每秒访问 1000 次,将产生 1GB/s 的网络流量,可能超出普通网络设备承载能力。
在集群部署中,还存在额外问题:
- 内存不均衡:BigKey 可能导致单个节点内存占用过高,造成集群资源利用不均衡。
- 迁移瓶颈:扩缩容时迁移 BigKey 会长时间阻塞 Redis,影响正常业务,甚至威胁集群稳定性。
BigKey 的检测
使用检测工具进行检测
Alauda Application Services 提供了 Inspections 功能,帮助您检测 Redis 实例中的 BigKey。
-
编辑检测工具的部署配置以启用 BigKey 检测。
在实例所在集群中,编辑 RdsInstaller 资源以开启 BigKey 检测。
输出示例如下:
-
修改
ENABLE_REDIS_KEYS_INDICATOR环境变量的值并保存。将
spec.inspection.env中ENABLE_REDIS_KEYS_INDICATOR的值改为1,修改后的示例如下:保存后,inspection Operator 工具会重启。您可以通过以下命令查看重启进度:
输出示例如下:
注意:上述修改非永久生效,平台升级时配置会被覆盖。
-
执行检测
在 Redis -> Details Info 页面,点击 Inspection 按钮启动实例检测。
检测开始后,按钮显示为 Inspecting...,检测完成后按钮恢复可点击状态。
由于启用了 BigKey 检测功能,检测工具会对缓存中的所有数据执行
SCAN操作,检测过程可能耗时较长。 -
查看检测结果
检测完成后,可在 Redis -> Detail Info 的检测报告中点击 Query 按钮查看检测结果。

如果实例中存在 BigKey,检测结果会列出
BigKey Top5,示例如下:
使用限制
- 检测工具会对 Redis 数据进行全量扫描,可能对 Redis 服务产生一定压力,建议在业务低峰期使用。
- 当前检测工具仅支持检测
string、list和zset类型。
使用命令行检测
Redis 社区提供了使用 redis-cli 检测 BigKey 的功能。检测时会遍历/采样 Redis 实例中的所有 Keys,返回 Keys 的整体统计信息及各数据类型中最大的 Key。当前支持分析的 bigkeys 类型包括 string、list、set、zset、hash 和 stream。执行命令如下:
使用限制
redis-cli检测同样会对 Redis 数据进行全量扫描,可能对 Redis 服务产生一定压力,建议在业务低峰期使用。
BigKey 的优化
需根据具体业务场景和数据特性选择合适的优化方案,通常关注以下几个方面:
存储数据结构优化
对于包含大量数据成员的集合类型(如 list、set、zset、hash 等),将其拆分为多个 Keys,确保每个 Key 的成员数量处于合理范围。在 Redis 集群架构中,拆分大 Key 能显著提升数据分片间的内存均衡性。
数据压缩
若缓存大量 JSON 或 HTML 数据,可考虑对数据进行压缩。此外,也可使用 ProtoBuffer、MessagePack 等序列化协议以减少数据体积。
定期清理过期数据
对于有明确过期时间的数据,可通过设置过期时间自动清理。对于过期时间不确定的数据,可定期清理。特别是 list、set、zset、hash 等数据结构,可能积累大量过期数据,建议结合 SCAN 和 DEL 命令清理无效成员。
无论选择哪种优化方案,清理现有 BigKey 时需特别谨慎使用 DEL 命令,因为 DEL 会阻塞 Redis 服务。推荐使用 UNLINK 命令,UNLINK 会异步删除 Key,不会阻塞 Redis 服务。