【大白话说Java面试题 第178题】【07_Redis篇】第14题:怎么实现 Redis 的高可用?

发布时间:2026/7/16 23:48:17

【大白话说Java面试题 第178题】【07_Redis篇】第14题:怎么实现 Redis 的高可用? PDF大白话说Java面试题 — 07_Redis篇第14题怎么实现 Redis 的高可用回答核心考点Redis 高可用是分布式系统设计的核心命题大厂面试不会只问主从、哨兵、集群三种模式而是深入考察主从复制的全量同步与增量同步机制SYNCvsPSYNC、哨兵的故障转移流程与脑裂问题min-slaves-to-write、集群的 Slot 分配与迁移原理CRC16 16384 Slot、Gossip 协议的通信机制以及生产环境中如何根据业务规模做架构选型。面试官真正想判断的是你是否理解高可用不是选一个模式而是在一致性、可用性、分区容错性CAP之间的工程化权衡。1. 主从复制Replication1.1 核心架构┌─────────┐ ┌─────────┐ ┌─────────┐ │ Master │ ←────── │ Slave1 │ ←────── │ Slave2 │ │ (写) │ 同步 │ (读) │ 级联 │ (读) │ └─────────┘ └─────────┘ └─────────┘主从复制的作用读写分离主节点写从节点读提升读吞吐量数据冗余从节点是主节点的实时备份故障恢复基础哨兵/集群的故障转移依赖主从复制。1.2 复制机制全量同步 vs 增量同步同步类型触发条件过程特点全量同步从节点首次连接主节点 / 主节点无法执行 PSYNC主节点BGSAVE生成 RDB → 发送给从节点 → 从节点加载 RDB → 主节点发送缓冲区的写命令数据量大时耗时久主节点压力大增量同步从节点断线重连且主节点的复制积压缓冲区仍有断线期间的命令主节点发送积压缓冲区的命令给从节点快速只同步增量数据PSYNC 命令Redis 2.8从节点 → 主节点PSYNC runid offset 主节点判断 1. runid 匹配且 offset 在复制积压缓冲区内 → 返回 CONTINUE发送增量数据 2. runid 不匹配或 offset 超出范围 → 返回 FULLRESYNC new_runid offset执行全量同步复制积压缓冲区Replication Backlog主节点维护的一个固定大小默认 1MBrepl-backlog-size的循环缓冲区记录最近传播的写命令从节点断线重连时如果 offset 仍在缓冲区内执行增量同步。1.3 主从复制的延迟问题主从复制是异步的主节点写命令后立即返回客户端后台同步到从节点。因此存在复制延迟场景延迟影响正常网络毫秒级可接受跨机房10~100ms读从节点可能读到旧数据高并发写秒级主从数据不一致窗口扩大解决方案强制读主对一致性要求高的查询走主节点牺牲读性能延迟监控监控master_repl_offset和slave_repl_offset的差值超过阈值告警同步复制WAIT命令Redis 3.0等待指定数量的从节点同步完成才返回但性能下降。1.4 主从复制的优缺点维度说明优点实现简单读写分离提升读性能数据冗余备份缺点主节点单点故障需配合哨兵异步复制存在延迟全量同步时主节点压力大2. 哨兵模式Sentinel2.1 核心架构┌─────────┐ ┌─────────┐ ┌─────────┐ │ Sentinel1│←──────→│ Sentinel2│←──────→│ Sentinel3│ │ (监控) │ Gossip │ (监控) │ Gossip │ (监控) │ └────┬────┘ └────┬────┘ └────┬────┘ │ │ │ └───────────────────┼───────────────────┘ │ ┌───────┴───────┐ │ Master │ │ (写 读) │ └───────┬───────┘ │ 复制 ┌───────┴───────┐ │ Slave1 │ │ (读) │ └───────────────┘哨兵的核心职责监控定期检查主从节点的健康状态PING/PONG通知节点故障时通知管理员或其他应用自动故障转移主节点宕机时选举从节点为新主节点配置提供者客户端通过哨兵获取当前主节点地址。2.2 故障转移流程1. Sentinel 检测到 Master 主观下线SDOWN ↓ 2. 多个 Sentinel 协商确认 Master 客观下线ODOWN ↓ 3. 选举 Leader SentinelRaft 算法 ↓ 4. Leader 从 Slave 中选择新 Master - 过滤排除断线、复制延迟过大的 Slave - 优先级选择 slave-priority 最高的 - 偏移量选择复制偏移量最大的数据最新 - Run ID选择 Run ID 最小的 ↓ 5. 向新 Master 发送 SLAVEOF NO ONE ↓ 6. 向其他 Slave 发送 SLAVEOF 指向新 Master ↓ 7. 更新配置通知客户端2.3 脑裂问题与解决方案脑裂场景网络分区时原 Master 与 Sentinel 失联但仍在接收客户端写请求。Sentinel 选举新 Master 后系统中存在两个 Master导致数据不一致。网络分区 ┌─────────┐ ××× ┌─────────┐ │ ClientA │──────────────→│ Old Master│仍在写 └─────────┘ └─────────┘ ↑ 网络分区与 Sentinel 失联 ↓ ┌─────────┐ ┌─────────┐ │Sentinel │──────────────→│ New Master│新选举 │ (选举) │ └─────────┘ └─────────┘解决方案# redis.conf min-slaves-to-write 1 # 主节点至少要有 1 个从节点连接才允许写 min-slaves-max-lag 10 # 从节点复制延迟不超过 10 秒当原 Master 与所有从节点失联网络分区min-slaves-to-write条件不满足主节点拒绝写请求防止脑裂期间的数据不一致。2.4 哨兵模式的优缺点维度说明优点自动故障转移无需人工介入客户端通过哨兵自动发现主节点支持多哨兵高可用缺点只监控主从节点不处理数据分片故障转移期间~10秒服务不可用脑裂问题需额外配置3. 集群模式Cluster3.1 核心架构┌─────────┐ ┌─────────┐ ┌─────────┐ │ Master1 │←──→│ Master2 │←──→│ Master3 │ │ Slot 0-5460│ │ Slot 5461-10922│ │ Slot 10923-16383│ └───┬─────┘ └───┬─────┘ └───┬─────┘ │ │ │ ┌───┴─────┐ ┌───┴─────┐ ┌───┴─────┐ │ Slave1 │ │ Slave2 │ │ Slave3 │ └─────────┘ └─────────┘ └─────────┘核心设计数据分片16384 个 Slot每个 Master 负责一部分 Slot哈希槽分配CRC16(key) % 16384计算 Key 所属的 Slot主从复制每个 Master 有至少一个 Slave故障时自动切换Gossip 协议节点间通过 Gossip 交换状态信息心跳、配置。3.2 Slot 分配与迁移Slot 分配# 查看 Slot 分配CLUSTER SLOTS# 返回# 1) 1) (integer) 0# 2) (integer) 5460# 3) 1) 127.0.0.1# 2) (integer) 7000# 2) 1) (integer) 5461# 2) (integer) 10922# ...Slot 迁移扩容/缩容# 1. 在目标节点准备导入 SlotCLUSTER SETSLOT1000IMPORTINGsource_node_id# 2. 在源节点准备导出 SlotCLUSTER SETSLOT1000MIGRATINGtarget_node_id# 3. 逐个迁移 KeyCLUSTER GETKEYSINSLOT1000100# 获取 Slot 1000 中的 100 个 KeyMIGRATE target_host target_port key05000# 迁移 Key# 4. 完成迁移CLUSTER SETSLOT1000NODEtarget_node_idHash Tag如果 Key 包含{tag}只对tag计算 CRC16确保相关 Key 落在同一 Slot。SET user:{1001}:nameAlice# 计算 CRC16(1001)SET user:{1001}:age25# 同一 Slot支持事务和管道3.3 Gossip 协议作用集群节点间通过 Gossip 协议交换状态信息无需中心化协调。消息类型消息类型内容频率PING节点发送自身状态 随机选择 1/10 节点的状态每秒PONG对 PING 的响应包含自身状态收到 PING 时MEET新节点加入集群时广播一次性FAIL节点判断某节点故障时广播故障时故障检测节点 A 发送 PING 给节点 B超时未收到 PONG标记 B 为PFAIL疑似故障A 通过 Gossip 将 B 的 PFAIL 状态传播给其他节点如果多数 Master 认为 B 故障B 被标记为FAIL触发故障转移。3.4 集群模式的优缺点维度说明优点水平扩展支持 1000 节点自动故障转移数据分片分散压力无中心架构Gossip缺点运维复杂Slot 迁移、节点扩容跨 Slot 事务不支持需 Hash Tag客户端需支持 Cluster 协议MOVED/ASK 重定向4. 三种高可用方案深度对比对比维度主从复制哨兵模式集群模式数据分片❌ 不支持❌ 不支持✅ 16384 Slot自动故障转移❌ 手动切换✅ 自动✅ 自动读写分离✅ 手动配置✅ 手动配置✅ 天然支持扩展性垂直扩展单节点内存垂直扩展水平扩展加节点最大节点数1 主 N 从1 主 N 从1000 节点客户端复杂度低中需支持 Sentinel高需支持 Cluster数据一致性异步复制最终一致异步复制最终一致异步复制最终一致适用场景数据量小读写分离数据量小高可用要求大数据量高并发5. 生产环境架构选型业务规模推荐架构理由数据 10GB读多写少主从 哨兵1 主 2 从 3 哨兵简单可靠满足高可用数据 10~100GB高并发集群6 节点3 主 3 从水平扩展分散读写压力数据 100GB海量并发集群多主多从 代理Codis/Twemproxy超大规模代理层简化客户端跨机房部署集群 主从跨机房就近读取容灾备份6. 生产环境避坑指南6.1 主从复制延迟监控# 查看复制偏移量差值redis-cli INFO replication# master_repl_offset: 1234567# slave_repl_offset: 1234500# 差值 67延迟较小建议监控master_repl_offset - slave_repl_offset超过 10000 告警。6.2 哨兵节点的部署哨兵节点应独立部署不与 Redis 节点同机避免单点故障至少 3 个哨兵节点奇数确保投票机制有效哨兵节点之间网络互通避免网络分区导致误判。6.3 集群的脑裂与分区容忍配置cluster-require-full-coverage no部分 Slot 不可用时其他 Slot 继续服务避免跨机房部署集群网络分区时容易脑裂如需跨机房用主从复制 哨兵。6.4 客户端重试与容错哨兵模式下客户端需支持 Sentinel 协议自动发现新 Master集群模式下客户端需处理MOVEDSlot 迁移和ASK正在迁移重定向配置连接池的最大重试次数和超时时间。6.5 持久化与高可用的关系高可用解决服务不中断持久化解决数据不丢失主从复制是异步的主节点宕机时从节点可能丢失最后几秒数据必须开启 AOFappendfsync everysec RDB作为数据安全的最后兜底。7. 面试官追问与高分回答模板追问 1“怎么实现 Redis 的高可用”低分回答“用主从复制、哨兵模式、集群模式。”没有深入原理和选型高分回答Redis 高可用有三种方案按业务规模递进主从复制一主多从主节点写、从节点读通过异步复制实现数据冗余和读写分离。但主节点单点故障需手动切换适合数据量小、对自动故障转移无强要求的场景。哨兵模式在主从基础上引入 Sentinel 节点监控主从健康状态主节点宕机时自动选举新主节点基于 Raft 算法。支持自动故障转移和客户端自动发现但只解决高可用不解决扩展性。集群模式数据分片到 16384 个 Slot多主多从通过 Gossip 协议实现无中心架构。支持水平扩展1000 节点和自动故障转移适合大数据量、高并发场景。生产环境选型数据 10GB 用哨兵 10GB 用集群。追问 2“主从复制的全量同步和增量同步有什么区别”高分回答主从复制分两种同步方式全量同步从节点首次连接主节点或主节点无法执行 PSYNC 时触发。主节点fork()子进程执行BGSAVE生成 RDB 文件发送给从节点加载。数据量大时耗时久主节点压力大。增量同步从节点断线重连且主节点的复制积压缓冲区默认 1MB仍包含断线期间的命令时触发。主节点只发送积压缓冲区的增量命令快速同步。关键命令是PSYNC runid offset主节点判断 runid 是否匹配、offset 是否在缓冲区内满足则增量同步否则全量同步。追问 3“哨兵模式的故障转移流程是什么”高分回答哨兵故障转移分七步主观下线SDOWN单个 Sentinel 检测到 Master 超时未响应客观下线ODOWN多个 Sentinel 协商确认 Master 故障基于 Raft 投票选举 Leader SentinelSentinel 之间通过 Raft 算法选举一个 Leader 负责故障转移选择新 Master过滤掉断线/延迟大的 Slave按slave-priority→ 复制偏移量 → Run ID 选择提升新 Master向选中的 Slave 发送SLAVEOF NO ONE切换其他 Slave向其他 Slave 发送SLAVEOF指向新 Master通知客户端更新配置客户端通过哨兵获取新 Master 地址。整个过程约 10 秒期间写服务不可用。追问 4“什么是脑裂怎么解决”高分回答脑裂是指网络分区时原 Master 与 Sentinel 失联但仍在接收写请求Sentinel 选举新 Master 后系统中同时存在两个 Master导致数据不一致。解决方案min-slaves-to-write N主节点至少要有 N 个从节点连接才允许写。网络分区时原 Master 与从节点失联无法写入防止数据分歧。min-slaves-max-lag M从节点复制延迟不超过 M 秒延迟过大的从节点不计入min-slaves-to-write。客户端重试脑裂恢复后客户端需重新通过哨兵发现正确的 Master。但min-slaves-to-write是牺牲可用性换一致性如果所有从节点都故障主节点将拒绝写请求。追问 5“Redis 集群的 Slot 是怎么分配的扩容时怎么迁移”高分回答Redis 集群将数据分为 16384 个 Slot0~16383每个 Master 节点负责一部分 Slot。Key 通过CRC16(key) % 16384计算所属 Slot。扩容迁移流程新节点加入集群CLUSTER MEET为目标节点设置导入状态CLUSTER SETSLOT slot IMPORTING source为源节点设置导出状态CLUSTER SETSLOT slot MIGRATING target逐个迁移 Slot 中的 KeyMIGRATE命令迁移完成后将 Slot 分配给目标节点CLUSTER SETSLOT slot NODE target。Hash Tag如果 Key 包含{tag}只对tag计算 CRC16确保相关 Key 在同一 Slot支持跨 Key 事务和管道。追问 6“Gossip 协议在 Redis 集群中起什么作用”高分回答Gossip 协议是 Redis 集群的无中心化通信机制节点间通过周期性交换状态信息实现集群自治PING/PONG每个节点每秒向随机几个节点发送 PING携带自身状态和 1/10 其他节点的状态收到 PING 的节点回复 PONG。状态传播通过多轮 PING/PONG节点故障信息PFAIL → FAIL快速传播到整个集群。配置同步新节点加入、Slot 迁移等配置变更通过 Gossip 传播。故障检测节点 A 未收到节点 B 的 PONG标记 B 为 PFAIL如果多数 Master 都认为 B 故障B 被标记为 FAIL触发故障转移。Gossip 的优点是去中心化、容错性强缺点是状态收敛有延迟不适合对一致性要求极高的场景。8. 方案选型速查表业务场景推荐架构节点配置核心注意点小型应用10GB主从 哨兵1主2从3哨兵监控复制延迟配置脑裂防护中型应用10~100GB集群3主3从合理分配 Slot预留扩容空间大型应用100GB集群 代理多主多从 Codis代理层简化客户端分片策略优化跨机房容灾主从跨机房 哨兵每机房1主1从就近读取异步复制容忍延迟极高可用要求集群 持久化多主多从 AOF自动故障转移 数据不丢失面试官想要的满分总结Redis 高可用不是选一个模式而是根据业务规模在一致性、可用性、扩展性之间的工程化权衡。主从复制是基础解决读写分离和数据冗余但无法自动故障转移。哨兵模式在主从基础上增加自动故障转移~10 秒适合中小规模。集群模式通过 16384 Slot 分片 Gossip 协议实现无中心水平扩展适合大数据量、高并发场景。生产级注意点主从复制监控延迟master_repl_offset - slave_repl_offset哨兵配置脑裂防护min-slaves-to-write集群使用 Hash Tag 保证相关 Key 同 Slot所有方案必须叠加 AOF RDB 持久化作为数据安全的最后兜底。最后记住高可用解决服务不中断持久化解决数据不丢失两者缺一不可。觉得对您有帮助麻烦点点关注啦您的关注是我创作的最大动力~

相关新闻