跳转至

哨兵与集群

主从同步

主从同步默认采用异步复制,主节点写入完成后,立刻返回成功

一致性考量:可以通过执行 wait n ex 来等待至少 n 个从节点确认后,再返回成功(multi 和 lua 中不允许阻塞,立刻返回当前的确认数)

image-20250807221925963

replicaof 172.16.19.3 6379

单节点的 Redis 并发能力有上限,通过主从集群实现读写分离

image-20250807124741608

全量同步

在从节点新加入时触发。

  • replid:用于标志同一个数据集,归属于同一个 master 的 slave 会继承属于这个 master 的 replid

    如果在同步启动时,主节点发现从节点具有相同的 replid,说明不是建立初始连接,不会进行 RDB 的传递,通过 repl_baklog 同步数据

  • offset:分别存在于 master 和 slave 中,用于记录 repl_baklog 的同步差异

全量同步时,在 RDB 从生成到发送完成之间的增量数据,通过 repl_baklog 缓冲区进行记录

image-20250807125940729

增量同步

从节点发来 psync replid offset 后可以判断需要进行增量同步,主节点从命令日志中获取 offset 之后的数据,发送给从节点进行同步

哨兵模式(Sentinel)

Redis 哨兵基于 sentinel.conf 配置文件,作为独立的进程运行,一般部署的哨兵进程数 >= 3

哨兵机制用于实现主从集群的自动故障恢复(监控集群状态,更换 master)

image-20250807194226126

监控机制

哨兵基于心跳检测服务状态,每隔 1 秒向集群的每个实例发送 ping 消息(consul 的服务健康检查也是 consul-server 主动定期向 client agent 发送 tcp 探测)

  • 主观下线:某个哨兵发现某个实例未在规定时间内响应 pong,则认为该实例主观下线
  • 客观下线:超过指定数量的哨兵都认为某个实例主观下线(quorum 一般为哨兵实例数的一半)

选主规则

当 master 客观下线后,哨兵需要选主

  • 先判断主从节点断开时间长短,断开时间(可配置)超过指定值的从节点被排除
  • 判断 slave-priority,越小越高
  • 判断 slave 的 offset,越大则优先级越高
  • 上述一样,则根据 slave-id 选择

脑裂问题

主节点和(从节点和哨兵)处在不同的网络分区,使 sentinel 无法感知主节点的存在,从而在 slave 中选举出了一个 master ,此时就存在两个 master,且客户端还在向原来的主节点写入数据。

当网络恢复后,客户端写入的 master 会被哨兵降为从节点,此时再从新的 master 同步数据时,其原有内容会被清空,导致数据丢失。

解决方案:

  • 配置 min-replicas-to-write 1 :如果 master 没有从节点,则拒绝客户端请求
  • 配置 min-replicas-max-lag 10:当从节点延迟超过 10s ,则主节点拒绝写入
    • 这个值设置的过大,会降低一致性,设置的过小,则会导致主节点频繁拒绝写,降低可用性
  • sentinel 方面,提高 quorum 投票数量的阈值,减少误判

分片集群(Cluster)

与专注于 Redis 主从架构的哨兵机制不同,分片集群是一个无中心架构(No Master Node)

当使用 Lua 脚本时,需要保证一次执行的脚本中的 key 都唯一同一个节点中

  • 水平增加数据的存储量
  • 提高写操作的并发能力

image-20250805233643300

路由规则

分片集群通过 CRC16 计算 Key 的 hash 值(可以通过 {} 来规定计算的 Key 的部分);通过 bitmap 存储 16384 个 hash 槽,每个 master 节点可以映射到其中的多个槽中。

在路由数据时,Redis 客户端连接任意一个 master 节点,最后消息都可以被转发到正确的节点中。

故障恢复

每个主从单元的主节点会持续向集群中的其他主节点发送 ping 消息,当规定时间内没有收到 pong 响应,则这个节点被标记位主观下线。当被半数以上的主节点标记为主观下线时,这个节点会被标记为客观下线。

这里的 ping 和 pong 涉及到信息的交换,包括主观下线情况和槽的分配信息

此后,这个下线的主节点的从节点会开始基于 raft 算法的选举:

  • 每个从节点广播一条 CLUSTER_TYPE_FAILOVER_AUTH_REQUEST 消息,要求所有收到消息,且没有投过票的主节点返回 CLUSTER_TYPE_FAILOVER_AUTH_ACK
  • 获得的选票数大于集群主节点的一半时,从节点上位,并开始广播 ping