JJava 知识库
JAVA INTERVIEW

高频面试题

Redis高级约 3 分钟

Redis 数据量持续增长,需要从单机扩到集群,你会怎么规划分片、扩容和故障转移?

参考回答约 3 分钟 · 口语表达
先说结论

我会先控制影响,再按证据定位:Redis Cluster 把键映射到 16384 个槽,再把槽分配给主节点。客户端根据槽路由请求,拓扑变化时通过 MOVED 更新长期映射;槽迁移过程中可能通过 ASK 临时访问目标节点。每个主节点可配置从节点参与故障转移。

01

我会先确认影响范围,同时控制故障继续放大。理解哈希槽、请求重定向、主从复制、故障选举和扩缩容。Redis Cluster 把键映射到 16384 个槽,再把槽分配给主节点。客户端根据槽路由请求,拓扑变化时通过 MOVED 更新长期映射;槽迁移过程中可能通过 ASK 临时访问目标节点。每个主节点可配置从节点参与故障转移。 集群使用异步复制,主节点故障时仍可能丢失尚未复制的数据,因此它提供高可用而不是强一致。

02

止损之后,我会按请求链路建立证据,而不是凭经验猜。沿着「对 Key 计算 CRC16 → 映射到 16384 槽 → 客户端路由到节点 → MOVED/ASK 重定向 → 迁移槽并恢复副本」观察输入、状态与输出,这些阶段都可以从日志、指标或源码里验证。 对 Key 计算 CRC16 Cluster 以 hash slot 而非节点数直接映射,槽作为扩容迁移的最小路由单位。 映射到 16384 槽 普通 Key 通过 CRC16%16384 定位; src/cluster.c keyHashSlot:CRC16 与 hash tag。 CLUSTER SLOTS/SHARDS:槽位、节点与迁移状态。 我会先确认请求实际走到了哪条路径,再用运行数据验证,不会只看类名或配置猜测。

03

定位时我最关注这些参数、指标和容量关系。统计每槽 Key/QPS,迁移含 Big Key 的槽并注入 MOVED/ASK,验证客户端拓扑刷新和延迟。

04

找到根因后先做最小修复,再用同样的流量验证。为支持批量 Lua,团队把所有租户 Key 都写成 {global}:xxx,结果全部落同一槽,集群形同单节点。hash tag 应只绑定确需原子操作的小范围业务实体,而不是全局命名空间。 全局 hash tag 制造单槽热点:各槽 Key/QPS 分布:移除全局 hash tag。 固定输入和基线 先在没有故障注入的环境执行上述配置,固定数据规模、并发度、运行时版本和预热时间。以「最大/平均槽QPS」为主基线,记录值应满足「<2」;同时保存 各槽 Key/QPS 分布、clusterstate,使后续变化能够回到同一时间轴比较。

05

恢复阶段要逐步放量,最后把监控和边界补齐。方案:更适合的场景:主要收益:代价与边界。 Cluster:数据量和吞吐需水平扩展:原生分片与故障转移:跨槽多键限制、客户端更复杂。 客户端一致性哈希:可控分片中间层:规则灵活:迁移和高可用需自行实现。 单实例主从:容量足够且操作依赖多键:语义简单:垂直容量上限明显。 选型至少带上 Key 数量、Value 大小、命令复杂度、热点分布和过期速率,并用上面的量化基线验证;未知数据应明确为待测假设。

排查与恢复时间线从目标到落地
01对 Key 计算 CRC16
02映射到 16384 槽
03客户端路由到节点
04MOVED/ASK 重定向
05迁移槽并恢复副本