Redis主从/哨兵模式

主从模式

读写分离,master处理读写命令,slave仅处理读命令。

image

为什么仅有一个masater能处理读? 这是避免引入加锁、实例间协商是否完成修改等操作。

主从同步方式

通过replicaof {master_ip} 6379去请求RDB文件,同步细节如下。

image

  1. 从库给主库发送 psync 命令,表示要进行数据同步。

    psync 命令包含了主库的 runID 和复制进度 offset 两个参数。runID是Redis 实例启动时自动生成的随机 ID唯一标记,第一次复制时主库 runID未知设为“?”。offset为 -1,表示第一次复制。

  2. 主库通过 FULLRESYNC响应命令,返回主库 runID和主库复制进度offset。从库记录此数据。

  3. 主库启动bgsave命令生成RDB文件并发送给从库,从库清空当前内存数据并加载RDB数据。

  4. 主库发送同步期间replication buffer缓存的写命令给从库,从库回放写命令,完成数据同步。

解决主服务器同步压力

Redis宕机恢复提到过bgsave会增加cpu和内存负载,并会短暂阻塞主进程。可以考虑通过将部分从服务器作为二级从服务器的主服务器,分担全量复制的从服务器压力。

网络断连处理

Redis从服务器会定期发送REPLCONF ACK offset从主服务器拉取数据。但当网络波动时,可能会导致offset落后较多。

主服务器在接受写命令时,会缓存到一个环形缓冲区repl_backlog_buffer中,并更新master offset。接受到从服务器同步slave offset后,会判断repl_backlog_buffer是否还覆盖此位移。若包含则将落后的写命令缓存到replication buffer等待从服务器读取同步;否则,通过bgsave生成RDB走全量同步流程。

1. repl_backlog_buffer
   环形缓冲区,主服务器上的一块缓存,用于记录写命令,同步从服务器的备份缓存。可以根据redis写命令tps/网络IO/从服务器同步时间调整大小。

2. replication buffer
   从服务器等于client,此buffer意义同client buffer,故每个从服务器都有单独的replication buffer。
   数据需要写入replication buffer,再通过socket buffer发送出去,所以主服务器的写命令也会同时写入replication buffer。
   只有当从服务器断连后,便会用到repl_backlog_buffer去捞取丢失的命令。

哨兵模式

哨兵机制是实现主从库自动切换的关键机制。

它有效解决了主从复制模式下故障转移三个问题:

  1. 主库异常确认
  2. 升主从库选择
  3. 新主库信息集群广播

哨兵概念

一个特殊的redis实例,主要负责三个任务:监控、选主、通知。

image

监控

哨兵在运行时,会周期性地给所有主从库发送PING命令,有三种响应:

  1. PONG:这是一个正常的回复,表示主节点正在正常运行,无需向其他哨兵确认主节点状态。
  2. LOADING:这个回复表示主节点正在载入数据,会周期性向主节点发送诊断信息。如果主节点为PONG则无需其他操作。
  3. MASTERDOWN:这个回复表示主节点已经下线。这里又分为SDOWN(Subjectively Down,主管下线)和ODOWN(Objectively Down,客观下线)。如果发现下线,当前哨兵会与其他哨兵通信,对主节点状态作最终判定,以及进行故障转移操作。

从库未及时响应,会标记为主观下线;主库未及时响应,会发起主库切换流程。

主观/客观下线

  1. 主观下线

哨兵未在默认时间收到实例响应,便可标记主观下线。

  1. 客观下线

当有N 个哨兵实例时,最好是( quorum 配置项设定)有 N/2 + 1 个实例判断主库为“主观下线”时,才能认为是客观下线.

image

任何一个实例只要自身判断主库“主观下线”后,就会给其他实例发送 is-master-down-by-addr 命令。接着,其他实例会根据自己和主库的连接情况,做出 Y 或 N 的响应,Y 相当于赞成票,N 相当于反对票。

一个哨兵获得了仲裁所需的赞成票数后,就可以标记主库为“客观下线”。这个所需的赞成票数是通过哨兵配置文件中的 quorum 配置项设定的。例如,现在有 5 个哨兵,quorum 配置的是 3,那么,一个哨兵需要 3 张赞成票,就可以标记主库为“客观下线”了。这 3 张赞成票包括哨兵自己的一张赞成票和另外两个哨兵的赞成票。

选主

哨兵Lead选举

任何一个想成为 Leader 的哨兵,要满足两个条件:

  1. 拿到半数以上的赞成票
  2. 拿到的票数同时还需要大于等于哨兵配置文件中的 quorum 值

升主从库选择

  1. 优先级最高的从库得分高
    slave-priority 配置项可以给从库设置优先级。比如,你有两个从库,它们的内存大小不一样,你可以手动给内存大的实例设置一个高优先级。在选主时,哨兵会给优先级高的从库打高分。

  2. 和旧主库同步程度最接近的从库得分高
    通过比较slave_repl_offset和master_repl_offset进行判断。

  3. ID 号小的从库得分高
    每个实例的默认ID。

通知

在执行通知任务时,哨兵会把新主库的连接信息发给其他从库,让它们执行 replicaof 命令,和新主库建立连接,并进行数据复制。同时,哨兵会把新主库的连接信息通知给客户端(redis-cli或者SDK等),让它们把请求操作发到新主库上。

  • 基于 pub/sub 机制的哨兵集群
  • 基于 INFO 命令的从库列表,这可以帮助哨兵和从库建立连接
  • 基于哨兵自身的 pub/sub 功能,这实现了客户端和哨兵之间的事件通知。
posted @ 2023-11-04 12:23  kiper  阅读(21)  评论(0编辑  收藏  举报