Redis集群负载不均不能只看槽位是否平均,真正原因常是数据/访问倾斜、热Key、HashTag滥用或客户端路由策略不当,需结合keys数、内存碎片率、大Key、热点Key及客户端配置综合诊断与优化。

Redis集群节点负载不均,不能只看槽位数量是否平均——redis-cli --cluster rebalance显示“no rebalancing needed”,但CPU、内存、QPS依然严重倾斜,这是常态。真正要动的不是槽,而是数据分布逻辑和请求路由行为。
槽位分配均匀 ≠ 负载均匀,先确认是不是真问题
很多团队一看到某个节点used_memory高就急着迁移槽位,结果发现迁移后负载照样不均。因为槽位只是数据存放位置的“地图”,不决定访问频次和单Key体积。
- 用
redis-cli --cluster info 集群任意节点IP:端口看各节点keys数和slots数:如果slots差<2%,但keys差>5倍,说明是数据/访问倾斜,不是槽位问题 - 用
redis-cli -h 节点IP -p 端口 info memory对比used_memory和mem_fragmentation_ratio:碎片率>1.5可能掩盖真实内存压力 - 用
redis-cli -h 节点IP -p 端口 --bigkeys -i 0.01扫大Key:一个10MB String或含50万成员的Hash就能让单节点IO和CPU飙升
热Key和HashTag滥用是最大隐性偏移源
业务代码里写user:{1001}:profile这种带{}的键,等于主动把所有1001相关请求钉死在一个槽、一个节点上。哪怕槽位平均分了,这个节点也得扛下全部读写。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 查热点:
redis-cli -h 节点IP -p 端口 --hotkeys(Redis 6.2+),或用MONITOR+top -n 1 -k 2临时抓高频Key - 改键设计:去掉
{},或把{1001}替换成{1001:rand(1,8)}打散到8个槽 - 对计数类热Key(如
pv:home),改用INCRBY user_id % 8分片再聚合,别全压在单Key上 - 避免
HGETALL扫全量Hash:用HSCAN分页,或提前把高频字段拆成独立String Key
Lettuce客户端默认策略会固化不均访问路径
Spring Boot默认的ReadFrom.REPLICA_PREFERRED不是按负载选从节点,而是按配置顺序轮询——如果application.yml里从节点写成192.168.1.10,192.168.1.11,192.168.1.12,那90%读请求永远先打192.168.1.10,直到它挂掉才切下一个。
- 启用自适应拓扑刷新:
spring.redis.lettuce.cluster.refresh.adaptive=true,避免缓存过期槽表导致误路由 - 手动指定读节点权重(Lettuce 6.2+):
ReadFrom.SLAVE_PREFERRED配合LatencyEvaluator实现基于延迟的动态选择 - 禁用固定顺序:删掉
spring.redis.urls里硬编码的节点列表,改用spring.redis.cluster.nodes让客户端自动发现 - 连接池别设太大:
max-active: 16比max-active: 200更利于快速释放空闲连接,减少单节点长连接堆积
MOVED重定向不解决负载,只解决路由错误
MOVED响应只会告诉你“这个槽不在这里,去192.168.1.12”,但它不会说“192.168.1.12现在QPS 95%,你换个节点试试”。客户端拿到新地址后,下次同样Key的请求仍会直奔该节点,形成稳定但不均衡的流量闭环。
- 不要依赖
MOVED自动平衡:它本质是纠错机制,不是负载调度器 - 监控
cluster_stats里的redirects指标:如果每秒MOVED次数突增,说明槽表已乱,需立刻redis-cli --cluster check - 对强一致性场景(如分布式锁),用
TRYLOCK+ 失败后随机退避重试,而非死磕同一节点 - 升级到Redis 7.4+,开启
cluster-allow-replica-migration yes,允许从节点在主节点过载时自动接管部分读请求
最常被忽略的一点:负载不均往往始于键设计,而非集群配置。一个{user_id}标签、一个未分页的HGETALL、一个没加随机后缀的计数Key,比10次槽位重平衡更能拖垮节点。先查--bigkeys和--hotkeys,再动reshard命令。

















