浅析 Redis 的主从模式

Redis 的主从复制

概述

Redis 的主从复制是 Redis 官方推出的分布式机制,解决了部分集群问题。

官方后续的一些分布式的实现,包括 Sentinel 以及 Cluster 等,多多少少都用到了复制的功能。

思维脑图

redis-master-slaver

相关实现

查看节点主从信息

通过指令 info replication,可以单独查看服务器此时的主从信息。如下:

redis-info-replication

role 表示当前节点的身份,master 表示是主节点

connected_slave 表示当前的子节点数,以及 slave0 就表示子节点信息。


主从关系的建立

Redis 服务器可以通过 SLAVEOF <ip> <port> 命令或者配置文件中 slavof <ip> <port> 的方式,建立主从关系。

被复制的服务器称为主服务器,当前服务器则称为从服务器。

需要注意的是,Redis 只支持一主多从的方式,一个从服务器只能对应一个主服务器。


建立主从关系之后,从服务器就无法再执行写命令了,而是完全同步主服务器的数据。

即使在执行 AOF 或者 RDB 文件的过程中发现有过期的键也不会主动删除,只能等主服务器的同步。

因为无法执行命令,无法写入,所以主从模式仅仅只扩展了读属性,写入瓶颈依然存在。


该种主从复制模型非常适合读多写少的环境,复制相当于为主服务器中的数据创建多个复本,也算是一种容错策略

单点的写入也一定程度上保证了一致性的要求。

这里的一致性都是指最终一致性,因为命令的扩散也会有延迟,卡着延迟从从服务器中读取就会有数据不一致的问题。

因此如果对一致性的要求很高,或者必须要强一致性,建议不要从从服务器读取。

复制模式可以分为数据同步以及命令传播两个阶段。

数据同步就是从服务器刚开始连接时的操作,全盘同步主服务器上的数据。

命令传播就是主服务器将本地执行过的命令再发送到从服务器(主服务器以客户端的身份发送命令到从服务器)。


Redis 中对应数据同步的命令有两个 SYNC 和 PSYNC。

SYNC - 旧版复制

旧版的数据同步就是依托于 SYNC 命令,从服务器向主服务器发送该命令表示开启同步数据流程。

redis-sync基础流程

主服务器首次接收到 SYNC 命令之后,会执行 BGSAVE 命令生成 RDB 文件,并在此时开启命令缓冲区,记录备份期间所有执行的写命令。

BGSAVE 执行完之后,会将生成的RDB文件发送给从服务器。

此时如果于多个从服务器连接,RDB 文件是可以直接共享的。

从服务器在接收到主服务器发送的 RDB 文件之后,会清空本地的所有数据,全盘载入 RDB 文件中的数据。

之后主服务器还会将缓冲区中的数据发送到从服务器,从服务器执行完缓冲区中的写命令,就达到了和主服务器的完全一致。


旧版的复制很简单,主要就是生成 RDB 文件并传播指令。

问题就在于太过简单,即使网络波动导致的瞬时断连,在重连之后也会进行全量同步。


PSYNC - 新版本的数据同步

PSYNC 命令是对 SYNC 命令的进一步优化,主要是 SYNC 只能进行全量同步,效率真的就不高,为此在 Redis2.8 版本之后,新增加了一个 PSYNC 命令。

PSYNC 命令完整的形式是 PSYNC <runid> <offest>在全量同步的基础上增加了一个增量同步的过程判断。


下面是增量同步中增加的概念:

  1. 复制偏移量

    按照字面意思也很好理解,是主从服务器各自维护的以字节为单位的属性,表示复制的进度。

    比如当前主服务器的复制偏移量为10000,在发送了50个字节的内容之后,就变为了10050,可以认为是主从服务器数据不一致性程度的表示。

    在 Sentinel 执行故障转移的时候也会以复制偏移量作为主要的参考依据。

    一定程度上,复制偏移量就表示从节点数据的完整性。


  2. 复制缓冲区

    复制缓冲区是由主服务器维护的一个固定长度的 FIFO 队列,该队列会缓存近期主服务器所执行的写命令。


  3. 主服务器 run ID

    run ID 唯一标识一个 Redis 服务器。

    实际上不论主从在服务器启动时都会生成一个 run ID,由40位随机的16进制字符组成。

    此处的 run ID 是在从服务器连接到主服务器是由主服务器下发的自身的 run ID,重连之后通过判断 run ID 来确定是否为同一个 Master。


PSYNC 的执行流程简述如下:

  1. 判断 run ID 是否相同,不相同会直接开启全量同步的逻辑,相当于直接走 SYNC。
  2. run ID 相同表示是断线重连,判断复制偏移量是否还在复制缓冲区中,如果超出表示超时时间过长,也需要走 SYNC。
  3. 如果复制偏移量未超出复制缓冲区,则直接将复制缓冲区中的命令发送到从服务器,从而避免全量同步。

Q&A

Q: 主从模式的优势

横向扩展了读性能

备份数据,强化数据安全


Q: 主从模式的存在的问题

对于写性能并没有提高,可能出于一致性的考虑,Redis 的主从模式并不允许从从服务器写入。

非强一致性,命令的扩散存在一定的延时,此时主从的数据并不一致。

单点故障问题,因为只能从主节点写入,单点故障问题很难避免,只要主节点宕机,整个集群就不可写入。


Q: PSYNC 的优化

PSYNC 借由复制缓冲区实现了对断线重连的容忍机制,如果断线时间断,可以从复制缓冲区中找到缺失的命令就可以进行部分重同步,而避免每次都是全量同步。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!