← 返回题目列表

分布式缓存集群容量如何规划?

中等 第 20 / 26 题 更新于 2026/09/30
缓存容量内存估算QPS容量规划
学习 AI 实战项目

简化版

缓存容量规划要同时算内存、吞吐、网络和故障冗余,不能只把 value 大小相加。内存需包含 key/value、对象与哈希表开销、过期与淘汰余量、复制和 fork 峰值;性能需按热点与最重命令估算,并验证单分片故障、扩容迁移和冷启动时仍满足 SLO。

详细版

先从业务侧收集有效 Key 数、平均/P95/P99 key-value 大小、数据类型、TTL 分布、读写 QPS、命中率、热点比例和增长率。基础内存近似为 Σ(键数 × 单条实际 MEMORY USAGE),再加客户端缓冲、复制 backlog、内存碎片、AOF/RDB 与写时复制峰值。不要用序列化前对象大小代替 Redis 实际占用。

节点数由多个上限共同决定:总内存/单节点安全内存、总 QPS/单节点安全吞吐、总带宽/单节点带宽,以及单个热点分片上限,取最大值。还要预留 N+1 或分片副本故障后的接管容量,一般不把正常水位跑到 90% 以上;具体目标由持久化、碎片率和扩容速度决定。

最后用生产相似数据压测普通 GET/SET、批量命令、热 Key、Big Key、故障切换和槽迁移。建立按天预测的内存耗尽时间与扩容提前量;容量规划不是一次表格,而是监控—预测—压测—扩容的闭环。

完整版教学

一、容量规划要回答四个问题

缓存容量不仅是“能放多少 GB”,还要回答能否处理目标 QPS、网络是否扛得住、故障后是否仍有余量、扩容能否在耗尽前完成。任何一项先到上限,集群就已到有效容量边界。

例如内存只用 50%,但热点分片 CPU 95% 或网卡出口打满,继续加 Key 仍会恶化延迟;反过来 QPS 很低,但大对象让内存逼近淘汰水位,也必须扩容。

记忆钩子:缓存容量取“内存、计算、网络、故障余量”四个约束中的最小可用上限。

二、内存不能只算业务 value

Redis 中一条记录还包括 key 对象、value 对象、字典 entry、指针、allocator 对齐及数据结构编码开销。小 Key 场景里元数据占比可能很高;集合从紧凑编码升级到哈希表/跳表后,单元素开销也会跳变。

最可靠的方法是用接近生产的数据写入测试实例,再以 MEMORY USAGE 抽样不同分位,并结合 used_memory 与业务 payload 计算倍率。估算公式可以写成:

基础数据内存 = key_count × avg_actual_memory_usage
运行目标内存 = 基础数据内存
             + 复制/客户端缓冲
             + 碎片与 allocator 余量
             + 持久化 fork/COW 峰值
             + 故障与增长余量

三、带数字做一次内存估算

假设 8000 万个 Key,抽样 MEMORY USAGE 平均为 420B,P99 为 1.8KB。平均基础占用约 80000000 × 420B ≈ 33.6GB。若复制/缓冲预留 4GB、碎片与运行余量按基础的 30%、未来两个月增长 20%,估算至少约 33.6×1.3×1.2+4 ≈ 56.4GB。

这还不包含重写/快照时写时复制的极端峰值。若写流量大、fork 期间修改了 10GB 页面,RSS 可能临时增加接近该量。容器 limit 若只按 maxmemory 设置,会被 OOM Killer 终止。

平均值也会隐藏 Big Key,因此同时看 P95/P99 和 Top Key。单键 4GB 即使总内存充足,也会带来迁移与阻塞风险。

四、吞吐和网络怎样估算

单节点“10 万 QPS”没有通用意义,取决于命令、value 大小、pipeline、连接数和 CPU。应按真实命令比例压测。读取 1KB 的 10 万 QPS,单纯 payload 就约 100MB/s;加协议、TCP 和副本流量后可能逼近 1Gbps 网卡极限。

工作负载主要瓶颈需要观察
小 value GETCPU/网络包率CPU、ops/s、P99
大 value GET出口带宽/缓冲bytes/s、client buffer
SET + 副本CPU、网络、持久化replication lag、AOF
ZRANGE 大范围CPU/响应大小slowlog、返回元素数
Lua/复杂命令主线程执行时间command latency

吞吐规划以满足延迟 SLO 的最大流量为准,不采用已经出现大量超时的峰值数字。

五、分片数与副本数怎么计算

先分别计算内存所需主分片数和吞吐所需主分片数,取较大者,再乘副本因子。假设安全单主容量 20GB、总目标 120GB,内存至少 6 个主分片;若单主安全吞吐 4 万 QPS、目标 30 万 QPS,吞吐至少 8 个,最终主分片不能少于 8。

每主一从时物理节点资源约翻倍,但副本不是额外业务写容量;它承担复制与故障接管。分片过少扩展粒度粗,过多则增加连接、心跳、运维和 Cluster 元数据成本。

规划还要看槽/Key 分布,不能假设哈希一定消除业务热点。大客户或固定热点 Key 可能需要专属拆分。

六、故障和扩容余量

若 8 个主分片正常各 2 万 QPS,其中一个故障后其从节点接管流量本身问题不大,但宿主机上其他实例也可能争用 CPU/网络。若采用跨节点合并或请求重试,故障流量还会放大。因此正常水位要按最坏单故障计算,而不是平均分布。

扩容也不是瞬时的。迁移 200GB 数据,实际可安全限速 50MB/s,纯传输时间约 200×1024/50 ≈ 4096s,约 68 分钟;考虑业务竞争、重试和验证会更久。告警必须早于耗尽时间至少一个完整扩容周期。

days_to_full = (safe_memory_limit - current_used) / daily_growth
若扩容交付+迁移需 7 天,应在 days_to_full 明显大于 7 时触发

七、压测和持续预测

压测环境要有相似 Key 数量、value 分布、TTL 和热点,运行足够久以暴露碎片、淘汰和复制滞后。除稳态外,还要执行主从切换、断开副本、槽迁移和冷缓存回源,记录最坏 P99 与数据库压力。

线上监控包括 used/max memory、RSS、fragmentation ratio、evictions、expired keys、ops、网络、客户端缓冲、复制 lag、最热分片与最大 Key。对内存和 QPS 做趋势预测,避免到 90% 才人工扩容。

容量变更后复核成本:过度冗余会浪费,过度装箱会扩大单机故障和迁移时间。目标是在 SLO 与故障假设下保持可解释余量。

八、常见误区与追问

  • 误区:序列化后的 value 大小就是 Redis 内存占用。 还要计算 key、对象、字典、对齐和数据结构编码开销。
  • 误区:副本可以直接算作写容量。 副本要处理复制并用于接管,不是独立可写分片。
  • 误区:内存没满就不需要扩容。 CPU、带宽、热点分片或迁移时间可能先达到上限。
  • 误区:平均 Key 大小足以规划。 P99 和 Big Key 会影响内存峰值、迁移与延迟,必须单独统计。
  • 追问:容器内存 limit 为什么要高于 maxmemory? 进程还有碎片、缓冲、代码页和 fork/COW 峰值,否则可能被 OOM Kill。
  • 追问:安全水位设多少? 没有统一比例,应按持久化峰值、故障接管、增长和扩容时间压测确定。
  • 追问:分片越多越好吗? 不是,分片增多带来连接、运维、跨分片操作和重平衡成本。

九、加强记忆

容量规划按“算实际内存、压真实命令、取最大分片数、留故障与迁移余量、持续预测”推进。不要只看 value 总和或营销 QPS;用生产样本测 MEMORY USAGE,把 key 元数据、碎片、缓冲和 COW 算进去,再用真实读写和热点验证 CPU、网络与 P99,最终按 N+1 和扩容提前量保留安全空间。