登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  数据库 >  Redis

Redis Cluster 槽位统计辅助容量规划的方法

来源:17golang原创

时间:2026-10-16 23:00:21 137浏览 收藏

Redis Cluster 做容量规划时,不能只看每台机器的 used_memory。更稳妥的做法是先确认 16384 个 hash slot 是否完整覆盖,再把槽位区间映射到主节点,最后补充每个槽位的键数量和热点分布。这样得到的是一张“拓扑—槽位—数据量”统计表,而不是只看节点平均值。

官方地址:https://redis.io/

槽位数量适合判断分片拓扑是否均衡,槽位键数适合发现数据倾斜,迁移窗口还要结合单节点内存、业务写入和迁移批次一起评估。统计结果可以辅助容量决策,但不能单凭一项指标自动决定扩容。
  • CLUSTER INFO回答“集群是否完整可服务”。
  • CLUSTER SLOTS回答“哪些槽位由哪个主节点和副本节点负责”。
  • CLUSTER COUNTKEYSINSLOT回答“某个槽位在当前节点本地有多少键”。

先确认 16384 个槽位是否完整覆盖

Redis Cluster 的第一层统计是全局健康边界。官方的 CLUSTER INFO 会返回 cluster_slots_assigned、cluster_slots_ok、cluster_slots_pfail、cluster_slots_fail 和 cluster_size 等字段。规划容量前,至少把这些字段保存下来:如果槽位没有全部分配,先处理拓扑问题,不要把“不完整集群”当成容量基线。

# 从任意集群命令端口读取全局覆盖状态;示例只展示命令,不代表本文已连接实例
redis-cli -c -h 127.0.0.1 -p 7000 CLUSTER INFO | grep -E '^(cluster_state|cluster_slots_|cluster_size):'

# 读取槽位区间和主、副本地址,用于后续建立节点映射
redis-cli -c -h 127.0.0.1 -p 7000 CLUSTER SLOTS

CLUSTER SLOTS返回的是槽位范围及其服务节点,适合建立“起始槽—结束槽—主节点—副本节点”的映射。槽位范围均匀,不代表键数量均匀;反过来,键数量接近也不代表副本、内存和流量已经满足生产要求。

Redis Cluster 的 CLUSTER INFO、CLUSTER SLOTS、16384个哈希槽与主副本节点之间的静态关系说明图
图1:槽位覆盖结构说明图。查看全局状态、槽位区间与主副本节点的关系;这是静态说明图,不是运行截图。

按主节点汇总槽位数量和键数量

完成覆盖检查后,再统计每个主节点拥有的槽位数。平均值可以用 16384 ÷ 主节点数 得到,但这只是拓扑上的平均槽位数,不是容量上限。一个槽位里可能只有少量小键,也可能聚集大量大对象,所以还要对槽位键数做采样或完整采集。

CLUSTER COUNTKEYSINSLOT slot 的复杂度是 O(1),但它只查询接收命令节点的本地数据集。如果把命令发给不负责该槽位的节点,得到的数量会是 0。因此脚本必须先用 CLUSTER SLOTS 找到槽位所属主节点,再把计数请求发到该节点,不能固定连接一个 seed 节点循环所有槽位。

# 这是统计脚本骨架:读取槽位归属后,把每个槽位发给对应主节点。
# 真实项目中还应补充认证、TLS、超时、重试和结果落盘;这里不执行连接。
from collections import defaultdict

def summarize_slot_counts(slot_ranges, count_keys):
    # slot_ranges: [(master_id, start_slot, end_slot)]
    per_master = defaultdict(lambda: {"slots": 0, "keys": 0, "max_slot_keys": 0})
    for master_id, start_slot, end_slot in slot_ranges:
        row = per_master[master_id]
        for slot in range(start_slot, end_slot + 1):
            # count_keys 必须路由到该 slot 的主节点,不能在任意节点上调用
            slot_keys = count_keys(master_id, slot)
            row["slots"] += 1
            row["keys"] += slot_keys
            row["max_slot_keys"] = max(row["max_slot_keys"], slot_keys)
    return dict(per_master)

表格建议至少保留四列:主节点、槽位数、槽位键总数、单槽最大键数。前两列更偏拓扑,后两列更偏数据分布。采集全量槽位会产生额外命令开销,生产环境可以先按固定间隔采样,再对疑似热点槽位做补采;采样周期和采样比例要与业务峰值分开记录。

识别热点并估算迁移窗口

容量规划的关键不是追求每个槽位的键数绝对相等,而是找出会限制扩容、迁移或故障转移的少数热点。可以把“单槽最大键数 ÷ 节点平均槽位键数”作为内部比较指标,但它不是 Redis 官方阈值,也不能代替内存占用、对象大小和命令流量。

如果发现某个主节点槽位数接近平均值,却拥有明显更多键或更大内存,说明仅调整槽位数量可能不够。迁移前要确认热点槽位对应的业务键是否持续写入,并把迁移批次、客户端重定向、网络带宽和可接受的业务抖动纳入窗口。Redis 官方将 resharding 描述为在节点之间移动 hash slot;redis-cli --cluster reshard 可以辅助执行,但不会替你理解业务热点。

# 先查看指定槽位的部分键名,slot 参数应来自前面的统计表
# 这是规划阶段的示例;生产环境要限制返回数量并避免把敏感键名写入日志
redis-cli -c -h 127.0.0.1 -p 7000 CLUSTER GETKEYSINSLOT 8123 20

# 规划后由管理员在维护窗口执行迁移;--cluster-yes 只跳过交互确认
# 目标节点、迁移槽位数和回滚安排必须先经过人工评估
redis-cli --cluster reshard 127.0.0.1:7000 \
  --cluster-from SOURCE_NODE_ID \
  --cluster-to TARGET_NODE_ID \
  --cluster-slots 128 \
  --cluster-yes
Redis Cluster 的槽位键数、热点槽位、源主节点、目标主节点与迁移窗口之间的静态关系说明图
图2:热点与迁移窗口结构说明图。查看槽位键数如何连接到源主节点、目标主节点和容量评估;图中不表示真实迁移结果。

用小工具输出可复查的统计表

实际落地时,可以把统计分成三份输出:第一份保存 CLUSTER INFO 的全局状态,第二份保存 CLUSTER SLOTS 的拓扑快照,第三份保存按主节点聚合后的槽位键数。每份记录都要带采集时间、连接入口、节点 ID 和是否为采样结果,便于和扩容前后的数据比较。

指标回答的问题不能直接推出
cluster_slots_assigned / ok槽位是否完整可服务节点内存是否足够
主节点槽位数拓扑分片是否大致均衡业务键是否均匀
单槽键数与节点键总数是否存在数据倾斜单键大小和访问流量
迁移槽位数本次计划移动多少槽位迁移耗时和业务影响

这张表可以作为容量评审的输入:先排除覆盖异常,再观察节点和槽位的离散程度,最后结合内存、连接数、命令延迟和业务峰值决定是否扩容或重分片。若只是看到某一天的单槽键数偏高,不要立即执行迁移;先重复采集,确认热点是稳定业务特征还是临时批处理。

常见问题

槽位数平均就代表容量平均吗?

不代表。槽位只表达分片归属,键数量、对象大小、访问流量和过期策略仍可能严重不均衡。

为什么 COUNTKEYSINSLOT 返回 0?

该命令只查询接收节点的本地数据集;如果请求发到了不负责该槽位的节点,返回 0 不能证明槽位没有键。

采集全部槽位会不会影响线上 Redis?

命令本身是轻量统计,但全量循环仍会产生请求量。应控制采集频率、超时和并发,并把采样与峰值时段分开安排。

发现热点槽位后能直接 reshard 吗?

不能只看一个指标就迁移。还要确认业务写入、对象大小、带宽、客户端重定向和回滚窗口,并由管理员在维护窗口执行。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>