大 key 处置是什么
大 key 指单个键的 value 过大(如 Hash 有百万字段、List 有百万元素、String 达数十 MB)。后果是读写耗时高、删除时阻塞主线程、集群下造成数据倾斜。处置路径是先止血再重构:能拆就拆、删除用异步方式、必要时把大 value 压缩或搬出 Redis。
基本信息
| 判定参考 | String 超过 10KB 需关注,集合类元素数超过一万需评估 |
|---|---|
| 发现手段 | redis-cli --bigkeys 抽样扫描,或 redis-rdb-tools 离线分析 |
| 删除命令 | UNLINK 异步释放,DEL 在超大键上会阻塞主线程 |
| 分批手段 | HSCAN 配 HDEL、SSCAN 配 SREM、LTRIM 截断 List |
| 拆分手段 | 按业务维度或 hash tag 分片成多个小键 |
典型使用场景
- 购物车类键过大:按用户或哈希标签拆成多个键,降低单键压力
- 全量集合类缓存:把一次性 SADD 全量改成按业务分片存储
- 日志与时间线:用 LTRIM 固定长度,或定期裁剪为定长窗口
- 大 JSON 字符串:改为 Hash 存字段,或在应用层压缩后存储
- 历史遗留大键清理:用异步删除命令而非 DEL,避免长时间阻塞
渐进处置示例
渐进处置示例
redis-cli --bigkeys # 低峰期抽样扫描,定位大键
redis-cli MEMORY USAGE big:hash # 精确查看单个键占用字节
redis-cli OBJECT ENCODING big:hash # 看底层编码,判断是否退化
# 分批删除大 Hash:
redis-cli HSCAN big:hash 0 COUNT 1000 # 客户端循环读取并批量 HDEL
# 大 List 直接截断:
redis-cli LTRIM big:list 0 999 # 只留前 1000 个元素
# 最省事的异步删除:
redis-cli UNLINK big:hash处置手段对照
| 手段 | 适用 | 代价 |
|---|---|---|
| 按维度拆分 | 可自然分组的业务对象 | 需要改读写代码并迁移历史数据 |
| 渐进删除 | 仍需下线的大键 | 耗时长,删除期间键依然占内存 |
| 异步删除 | 可以整键删除的场景 | 命令立即返回,内存由后台线程释放 |
| 压缩或外置 | 超大 JSON 与图片类数据 | 读写要编解码,或用对象存储替代 |
预防比事后治理便宜:在写入路径上限制单键大小(例如 Hash 超过一万字段就分片),把约束写进业务代码。
拆分后要同步修改读取逻辑并迁移历史数据,否则老键仍被写入,问题会重新出现。