大 Key / 热 Key 线上治理

发布时间:2026/6/22 20:41:23
大 Key / 热 Key 线上治理 大 Key / 热 Key 线上治理定位、拆分、降级全套优化手段Redis 崩了八成跟这两个 Key 有关。大 Key 让你的 Redis 堵得像早高峰的三环热 Key 让单节点 QPS 直接打满——它们不是同一个问题但都能让整个集群陪葬。这篇文章把从定位到治理的全链路方案讲透每一步都能直接落地。一、先搞清楚大 Key 和热 Key 根本不是一回事维度大 Key热 Key本质单次操作数据量过大单个 Key 访问频率过高症状阻塞、网络拥塞、主从延迟单节点 CPU/QPS 飙升、缓存击穿危险时刻读写、删除、迁移时高峰期流量集中时核心思路拆——把大的拆小分——把集中的分散治理大 Key 是设计问题治理热 Key 是架构问题。搞混了方案全废。二、大 Key精准定位三步锁定第一步全局扫描快速圈定嫌疑对象bashredis-cli -h 127.0.0.1 -p 6379 --bigkeys输出示例Biggest string found so far product:detail:1001 with 120000 bytes Biggest hash found so far user:info:10000 with 10000 fields这条命令按类型输出每个类型里最大的 Key适合快速摸底。但注意它只告诉你最大的不告诉你所有大的。真正的大 Key 可能藏在第 10 名。生产建议在从节点执行避免影响主节点性能。第二步精确测量确认威胁等级对疑似大 Key 做二次确认bashTYPE product:detail:1001 # 确认数据类型 STRLEN product:detail:1001 # 字符串体积字节 HLEN user:info:10000 # Hash 字段数 LLEN order:list:1001 # List 元素数 MEMORY USAGE product:detail:1001 # 真实内存占用含管理开销统一判定标准华为云/腾讯云实践共识类型大 Key 阈值严重大 Key字符串 1MB 100MBHash/List/Set/ZSet 1 万元素 10 万元素单分区大小— 100MB第三步SCAN DEBUG 组合批量排查--bigkeys只能看 Top 1要找出所有大 Key必须编程扫描pythonimport redis r redis.Redis(host127.0.0.1, port6379, decode_responsesTrue) cursor 0 big_keys [] while True: cursor, keys r.scan(cursorcursor, count100) for key in keys: size r.debug_object(key).get(serializedlength, 0) if size 10240: # 10KB 阈值按需调整 big_keys.append((key, size)) if cursor 0: break print(f发现 {len(big_keys)} 个大 Key) for k, s in big_keys: print(f{k}: {s} bytes)进阶离线分析 RDB 文件生产环境大规模集群推荐离线分析不影响线上bashrdb-tools -c memory dump.rdb memory.csv # 在 CSV 中筛选 serializedlength 10240 的行关联业务证据确认优先级定位完技术指标后必须关联业务bashSLOWLOG GET 128看慢查询里是否有大 Key 的身影。如果HGETALL user:info:10000频繁出现在慢查询中它就是你的头号敌人。建立排查台账Key 名称类型大小访问频率关联接口处理优先级user:info:10000Hash10000 fields500/min用户详情P0三、大 Key 治理拆是核心删要安全手段一拆分——最有效没有之一原则避免一次操作全量数据。原始大 Key拆分方案拆分后 Keyuser:100010万字段的 Hash按业务字段拆user:1000:base、user:1000:profile、user:1000:statorder:list:0百万级 List按时间分页order:list:0:202501、order:list:0:202502超大 JSON 字符串Hash 化product:detail:1001:name、product:detail:1001:priceJava 客户端分片示例javapublic class KeySharding { private static final int SHARD_COUNT 10; public String getShardedKey(String originalKey, String userId) { int shardIndex Math.abs(userId.hashCode()) % SHARD_COUNT; return originalKey : shardIndex; } } // 写入时product:123 - product:123:0 ~ product:123:9 // 读取时随机或 hash 选取一个分片手段二安全删除——UNLINK 替代 DEL这是最容易踩的坑直接 DEL 大 Key 会阻塞主线程。bash# ❌ 危险主线程阻塞期间所有请求排队 DEL big:hash:key # ✅ 安全Redis 4.0异步释放不阻塞主线程 UNLINK big:hash:keyRedis 6.0 可开启惰性删除bashlazyfree-lazy-user-del yes lazyfree-lazy-user-flush yes开启后即使执行DEL底层也等效于UNLINK。对集合类型大 Key必须分批删bash# Hash先 HSCAN 取字段再 HDEL 逐个删 HSCAN big:hash 0 COUNT 100 HDEL big:hash field1 field2 field3 ... # List先 LRANGE 分页取再 LTRIM 缩减 LRANGE big:list 0 99 LTRIM big:list 100 -1手段三数据迁移——不该放 Redis 的搬走超大 JSON、二进制文件、历史归档数据——Redis 不是为这些设计的。数据类型迁移目标超大 JSON/对象MongoDB、Elasticsearch图片/文件对象存储S3/OSS历史冷数据数据库 TTL或直接归档铁律所有可过期数据必须设置 TTL。忘设 TTL 是大 Key 膨胀的第一元凶。四、热 Key 治理把火分散把压降级第一步找到那把火排查方式原理优缺点INFO stats看keyspace_hits分布简单但不精确redis-cli monitor redis-faina实时抓操作记录准确但高并发下影响性能客户端埋点AtomicLongMapSDK 层统计访问频率准确但侵入性强代理层收集Twemproxy/Codis代理统一统计对业务透明但增加架构复杂度云厂商控制台阿里云/腾讯云平台级热 Key 分析一键出结果最省事华为云实践阈值访问频率 100,000 次/分钟 热 Key设置多级预警。第二步四大治理手段按场景选手段一Key 分片——读多写少的首选把一个热 Key 拆成 N 个副本流量打散hot:product:123 → hot:product:123:0 ~ hot:product:123:9写只写主 Keyhot:product:123:0读随机或 hash 取一个分片java// 读取时随机选一个分片 int shard ThreadLocalRandom.current().nextInt(10); String key hot:product:123: shard; return redisTemplate.opsForValue().get(key);京东 hotkeys 方案更进一步代理层自动识别热 Key创建临时副本实现流量自动负载均衡。手段二本地缓存——挡在 Redis 前面的最后一道墙热点数据根本不该到 Redis。用 Caffeine/Guava Cache 挡在应用层javaLoadingCacheString, Object localCache Caffeine.newBuilder() .maximumSize(1000) .expireAfterWrite(5, TimeUnit.MINUTES) .build(key - redisTemplate.opsForValue().get(key));收益某线上案例接入本地缓存后 Redis QPS 骤降 99%。但要注意本地缓存过大会导致 GC 压力必须有同步机制保证与 Redis 一致性推荐 Redis 发布订阅 版本号校验手段三读写分离——读压力的解药适用于读多写少场景写请求 → 主节点 读请求 → 从节点多个云上一键开启即可。但从节点增多会增加故障率运维复杂度上升需权衡。手段四限流 降级——最后的保险当热 Key 已经把 Redis 打满必须断臂求生策略实现方式示例接口限流Sentinel / Guava RateLimiter秒杀接口限 1000 QPSRedis 侧限流Lua 脚本原子判断超过阈值直接返回空服务降级返回兜底数据商品详情降级为默认推荐列表热点黑白名单业务层定制临时屏蔽非核心热 Key五、全链路闭环从发现到根治治理不是一次删除是建立可持续的闭环发现 → 止血 → 改造 → 验证 → 回滚 → 监控阶段动作检查项发现定期扫描 阈值告警Top 大 Key 清单是否完成止血本地缓存 UNLINK 删除接口延迟、慢查询是否回落改造Key 拆分 分片高风险接口是否完成分页改造验证双写 数据一致性校验新旧数据是否一致回滚保留旧读逻辑开关回滚触发条件是否演练通过监控阈值告警 周巡检告警是否生效、巡检是否执行六、一张表记住所有方案问题本质定位方法核心手段兜底方案大 Key单次操作数据量过大--bigkeys SCANDEBUG拆分 UNLINK 删除数据迁移出 Redis热 Key单个 Key 访问频率过高INFO stats 客户端埋点 云控制台分片 本地缓存 读写分离限流 降级Redis 的性能上限往往取决于 Key 的设计能力。大 Key 靠拆热 Key 靠分而所有方案的前提是——你得先找到它们。