2-3-4-4-Redis集群及主从

一、Redis 高可用方案核心架构总览

Redis 的高可用方案分为两类:主从复制 + 哨兵(Sentinel)(集中式故障检测+手动/自动切换)和 Redis Cluster(分布式分片+自动故障转移)。两者核心差异在于:

维度 主从+哨兵 Redis Cluster
架构类型 集中式(依赖外部哨兵做故障检测) 分布式(节点间自管理,Gossip 协议)
数据分片 无(主节点存全量数据) 有(16384 槽位,节点按槽位分片)
扩展性 垂直扩展(提升单节点内存/CPU) 水平扩展(增加节点分摊数据/流量)
高可用实现 哨兵监控+自动故障转移 节点间互备+自动槽位迁移

二、主从复制 + 哨兵机制详解

1. 核心组件与职责

  • 主节点(Master):负责写请求,同步数据到从节点。
  • 从节点(Slave/Replica):复制主节点数据,处理读请求(分担主节点压力)。
  • 哨兵(Sentinel):集群的“监控中心”,核心职责:
    1. 监控:持续检查主节点/从节点是否存活。
    2. 自动故障转移:主节点宕机后,选举新主节点并更新从节点配置。
    3. 配置中心:向客户端返回当前主节点地址。

2. 关键原理

(1)主从复制流程

Redis 主从复制是异步全量+增量复制:

  • 全量复制(首次连接或主节点重启):

    主节点生成 RDB 快照→发送给从节点→从节点加载 RDB→主节点将全量复制期间的写命令同步给从节点。

    注意:全量复制会阻塞主节点(生成 RDB 时),可通过 repl-diskless-sync开启无盘复制(直接发送 RDB 到网络,减少磁盘 IO)。

  • 增量复制(全量后):

    主节点将写命令写入 复制积压缓冲区(Replication Backlog)→从节点定期向主节点请求未同步的命令(基于 psync命令)。

(2)哨兵故障转移流程

  1. 监控阶段:哨兵每秒向主节点发送 PING,若超过 down-after-milliseconds(默认 30 秒)无响应,标记主节点为“主观下线(SDOWN)”。
  2. 共识阶段:哨兵间通过 Gossip 协议交换状态,若超过 quorum(默认 1)个哨兵认为主节点 SDOWN,则标记为“客观下线(ODOWN)”。
  3. 选举领头哨兵:通过 Raft 算法选举一个领头哨兵(Leader Sentinel),负责后续故障转移。
  4. 选择新主节点:领头哨兵从从节点中筛选符合条件的候选(优先级高→复制偏移量大→运行 ID 小)。
  5. 晋升与通知:候选从节点执行 SLAVEOF NO ONE晋升为主节点→领头哨兵通知其他从节点 SLAVEOF 新主节点→更新哨兵配置。

3. 应用场景

  • 读多写少:从节点分担读请求(如电商用户信息缓存,读请求占比 80%)。
  • 小数据量高可用:单节点内存≤32G(垂直扩展成本低)。
  • 弱一致性容忍:允许短暂的主从数据延迟(如商品列表缓存)。

4. 常见问题与解决

(1)主从同步延迟(写后读从节点读不到最新数据)

  • 原因:主节点写命令异步同步到从节点,网络/负载大时延迟加剧。
  • 解决
    • 强一致性场景:写后强制读主节点(如支付订单状态)。
    • 降低延迟:优化主节点性能(如 pipeline 批量写)、增大从节点资源、设置 repl-backlog-size(增大复制积压缓冲区)。

(2)哨兵脑裂(网络分区导致双主)

  • 原因:网络中断后,部分哨兵认为主节点宕机并选举新主,原主节点恢复后成为“影子主”,导致数据冲突。
  • 解决
    • 配置 min-replicas-to-write(主节点必须至少有 N 个从节点同步)和 min-replicas-max-lag(从节点延迟≤M 秒):若不满足,主节点拒绝写请求(避免数据丢失)。
    • 示例:min-replicas-to-write 1+ min-replicas-max-lag 10→ 主节点必须有 1 个从节点在 10 秒内同步,否则拒绝写。

(3)故障转移失败

  • 原因:从节点未正确复制数据、哨兵配置错误(如 quorum过小)。
  • 解决
    • 检查从节点同步状态(INFO replication查看 slave_repl_offset是否接近主节点)。
    • 调整 quorum为从节点数量的半数以上(如 3 从节点→quorum 2)。

三、Redis Cluster 详解

1. 核心设计:分布式分片与自管理

Redis Cluster 是去中心化的分布式方案,核心是槽位(Slot)分片

  • 整个集群分为 16384 个槽位(0~16383),每个 key 通过 CRC16(key) % 16384计算所属槽位。
  • 每个主节点负责一部分槽位(如 3 主节点→每个节点约 5461 个槽位)。
  • 从节点复制对应主节点的槽位数据,主节点宕机后从节点晋升为主节点,接管槽位。

2. 关键原理

(1)节点间通信:Gossip 协议

节点间通过 Gossip 协议交换以下信息:

  • 自身状态(存活/故障)。

  • 负责的槽位列表。

  • 其他节点的网络地址。

    特点:低 overhead,允许节点动态加入/退出,但收敛速度较慢。

(2)自动故障转移

  • 主节点宕机后,其从节点通过 Gossip 协议感知→发起选举(类似哨兵,用 Raft 算法)→晋升为主节点→更新集群元数据(告知其他节点新的主节点地址)。
  • 故障转移期间,客户端请求会收到 ASK重定向(告知迁移到新节点),客户端自动处理后重新请求。

(3)客户端路由:MOVED/ASK 重定向

  • MOVED 重定向:客户端请求的 key 所属槽位不在当前节点→返回 MOVED <slot> <new_node_ip:port>,客户端需重新连接新节点。
  • ASK 重定向:槽位正在迁移中→返回 ASK <slot> <new_node_ip:port>,客户端先请求新节点,迁移完成后自动切回原节点。

3. 应用场景

  • 大数据量高并发:单集群支持 TB 级数据、百万级 QPS(如秒杀系统库存缓存、电商商品详情缓存)。
  • 水平扩展需求:数据量增长时,通过增加节点分摊槽位(如从 3 主扩展到 6 主)。
  • 高可用要求极高:节点故障时自动转移,无需人工干预(如金融交易缓存)。

4. 常见问题与解决

(1)数据倾斜(部分节点压力过大)

  • 原因
    • 槽位分配不均(如手动分片时某节点槽位多)。
    • 热点 key(如某商品 ID 对应的 key 集中在同一个槽位)。
  • 解决
    • 重新分片:用 redis-cli --cluster reshard命令调整槽位分配(如将热点槽位的 key 拆分到其他节点)。
    • 拆分热点 key:将 product:123:stock拆分为 product:123:stock:shard1product:123:stock:shard2,分别放到不同槽位。

(2)槽位迁移中断

  • 原因:迁移过程中节点宕机、网络中断。
  • 解决
    • 迁移前备份数据→中断后重新执行迁移。
    • 使用 redis-cli --cluster import导入数据到新节点。

(3)客户端兼容问题

  • 原因:旧客户端不支持 Cluster 协议(如 Jedis 2.8 以下版本)。
  • 解决
    • 升级客户端库(如 JedisCluster、Lettuce)。
    • 使用代理层(如 Twemproxy、Codis)屏蔽 Cluster 细节(但会增加额外开销)。

(4)网络分区导致的集群分裂

  • 原因:网络中断后,集群分为两个独立的部分,均认为对方节点故障。
  • 解决
    • 设置 cluster-node-timeout(默认 15 秒):超过该时间节点才认为其他节点故障。
    • 恢复网络后,集群会自动合并(通过 Gossip 协议同步元数据)。

四、方案对比与选型建议

场景 推荐方案 原因
小数据量(≤10G)、读多写少 主从+哨兵 配置简单,从节点分担读压力
大数据量(≥10G)、高并发 Redis Cluster 水平扩展,自动故障转移
强一致性要求(如支付) 主从+哨兵(配参数) 可控制写请求的一致性(min-replicas-*
无运维能力(需自动分片) Redis Cluster 自管理,无需手动调整槽位

五、最佳实践总结

  1. 主从+哨兵
    • 开启主从持久化(RDB+AOF),避免数据丢失。
    • 设置 min-replicas-to-writemin-replicas-max-lag,保证写一致性。
    • 从节点只读,禁止写操作。
  2. Redis Cluster
    • 合理分配槽位(每个节点槽位数量差≤1%)。
    • 监控热点 key(用 redis-cli --cluster hotkeys或第三方工具)。
    • 使用支持 Cluster 的客户端(如 Lettuce),避免重定向开销。
  3. 通用
    • 定期备份数据(RDB 快照+AOF 文件)。
    • 监控节点状态(内存、CPU、QPS、同步延迟)。

六、模拟面试追问(帮你适应节奏)

  1. 若让你设计一个秒杀系统的库存缓存,你会选主从+哨兵还是 Redis Cluster?为什么?
  2. 主从复制的全量同步为什么会阻塞主节点?如何优化?
  3. Redis Cluster 的 MOVED重定向和哨兵的故障转移有什么本质区别?
  4. 若 Cluster 中某个槽位迁移失败,如何快速定位问题?

提示:回答时需结合场景(如秒杀的高并发)、原理(如 Cluster 的槽位分片)、问题(如数据倾斜)展开,体现“落地思维”。需要我针对某个追问详细解答吗?

posted @ 2025-11-11 14:40  哈罗·沃德  阅读(5)  评论(0)    收藏  举报