• 构建高可用的Redis服务(主从复制/哨兵/集群底层原理)


    高可用的Redis服务

    高可用:常见于分布式系统,指通过系统设计使能够提供服务的时间达到较高值。

    若系统能一直运行,则可用性为100%。

    Redis为了高可用,提供了三种保障机制。

    一、主从复制

    在Redis中,可以通过slaveof命令让一个Redis服务复制另一个Redis服务,我们称呼被复制的服务器为"主服务器",对主服务器进行复制的称为"从服务器"。

    复制分为两部分:同步与命令传播。

    • 同步:将从服务器的状态更新至主服务器的状态,即拥有相同数据。
    • 命令传播:当客户端命令使主服务器状态改变时,主服务器向从服务器发送对应命令,更新从服务器的数据。

    心跳检测:命令传播阶段,从服务器每秒一次向主服务器发送特定的命令,检测当前网络连接状态以及命令是否丢失等。

    1、主从复制的底层原理

    I. 完整同步

    完整同步用来处理初次将主服务器数据同步到从服务器中,步骤如下:

    1. 从服务器向主服务器发送sync命令请求同步数据。
    2. 主服务器收到sync后执行bgsave,生成RDB文件,同时将生成文件期间收到的写命令存入一个缓冲区中。
    3. 主服务器将RDB文件发送至从服务器,从服务器接收后进行数据载入。
    4. 主服务器将缓冲区中的命令发送给从服务器,从服务器接收后进行数据写入。

    至此,完整同步部分就完成了。此后,主服务器通过命令传播实时更新从服务器的状态。


    II. 部分同步

    部分同步用于从服务器断线后重新复制数据的情况。

    • 对于Redis 2.8之前的版本,从服务器会重新进行一次完整同步,但是这样的缺点就是效率太低,而且从服务器本地还存有大部分的持久化的数据,只因为部分数据的丢失而进行完整同步是没有必要的。
    • 对于Redis 2.8之后的版本,Redis重写了同步函数,用psync代替sync,解决了之前版本部分重同步低效的问题。
    psync实现原理
    1. 复制偏移量

      主从服务器各自维护一个复制偏移量:主服务器发送N字节数据时,就将自己的复制偏移量加N;从服务器收到N字节数据时,就将自己的复制偏移量加N。

      如果发生断线,则从服务器只需要复制自身偏移量之后的数据即可。

    2. 复制积压缓冲区

      复制积压缓冲区是主服务器维护的一个FIFO队列,默认大小为1MB,队列中保存着命令和对应的偏移量。

      • 如果从服务器请求的偏移量之后的数据还在队列,则主服务器利用这部分数据执行从服务器的部分重同步
      • 如果从服务器请求的偏移量之后的数据不在队列,则主服务器直接执行从服务器的完整同步
    3. 服务器运行ID

      Redis服务器在启动时自动生成40个十六进制字符组成的随机运行ID。

      从服务器在初次复制主服务器时,会将主服务器的运行ID保存下来。

      • 当从服务器断线重连时,发现此时的主服务器依然是上一次的主服务器,则执行部分同步
      • 当从服务器断线重连时,发现此时的主服务器不再是上一次的主服务器,则执行完整同步

    2、主从复制的优缺点

    优点:

    1. 能够实现读写分离,主服务器用于写,其它从服务器用来读,从而提高性能
    2. 数据更加安全:做了数据冗余,不会因为某一台服务器宕机而丢失全部数据

    缺点:

    1. 同步操作在系统繁忙时会有相当大的延迟,从而导致数据不一致的情况。
    2. 无法降低主服务器的写压力。

    二、哨兵

    哨兵(Sentinel)是一个分布式架构,包含一个或多个哨兵实例,可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器。

    哨兵实例本质上是利用redis-centinel+配置文件启动的特殊类型Redis服务器,不存储数据,只支持部分Redis命令。不同哨兵之间可以进行信息交互。

    image-20220818204207125

    1、工作模式

    1. 每个哨兵以每秒一次的频率向主、从服务器发送PING命令,通过回复来判断对应服务器是否在线。「监控」

      若距离上一次收到有效响应的时间超出配置文件中的down-after-milliseconds ,则哨兵可以主观判定该服务器下线

      注:PING的有效回复包括"+PONG"、“-LOADING”、“-MASTERDOWN”

    2. 当一个哨兵主观判定某个主服务器下线后,它会向同样监视该主服务器的其它哨兵询问,看它们是否也主观认为该服务器下线。

      如果接收到一定数量的"已下线"判断,Sentinel就会将该主服务器判定为**“客观下线”,这样做可以尽可能防止误判**。

      注:具体需要多少个"已下线"判断由每个哨兵的配置文件决定,该数量被保存在哨兵实例的quorum成员变量中。

    3. 从监视该下线主服务器的哨兵中选出一个领头哨兵,由领头哨兵选出优先级最高的从服务器,让它作为新的主服务器。若优先级相同,则选出运行ID最小的,即创建时间最早的。「故障转移」

      注:服务器优先级可以通过配置文件中的replica-priority设置,值越小,优先级越高。

    4. 如果原先的主服务器重新上线,那么它会成为现在这个新主服务器的从服务器

    2、哨兵的优缺点

    优点:

    1. 继承了主从复制的所有优点,可以做到读写分离、保障数据不会大量丢失
    2. 自动进行故障转移,用户友好

    缺点:

    1. 配置麻烦。
    2. 故障转移时可能导致服务较长时间不可用。

    三、集群

    集群(Cluster):通过分片来进行数据共享,提供复制和故障转移功能。

    一个集群通常由多个节点组成,每个节点相互独立,节点内有一个主机和多个从机。

    image-20220821162352871

    注:启动集群节点客户端需要-c选项,如redis-cli -c -p xxxx

    1、集群的配置

    1. 启动节点

      集群的每个节点都是一个Redis服务器,启动该服务器前需要将配置文件的cluster-enabled选项置为yes。

    2. 连接节点

      集群的每个节点都是一个clusterNode结构,节点之间通过CLUSTER MEET ip:port命令进行连接。以节点A连接节点B为例:

      • 节点A创建并维护一个节点B的clusterNode结构,同时向节点B发送一个MEET消息。
      • 节点B收到消息后创建并维护一个节点A的clusterNode结构,同时向节点A发送一个PONG消息。
      • 节点A向节点B发送PING消息,完成==“三次握手”==。
      • 最后,通过相同的方式,将节点B与节点A所在集群的其它节点建立连接。
    3. 指派槽位(分片)

      集群的整个数据库被分为16384个槽(slot),而用户需要在指定客户端下通过CLUSTER ADDSLOTS slot [slot1 slot2 ...]进行槽的分配,例如:使用CLUSTER ADDSLOTS 0 1 2 3 ... 5000将槽0~5000分配给客户端连接的那个节点服务器。每个节点负责了哪些槽最终都会被同步到集群的各个节点中,存储在每个节点的clusterNode *slots[16384]数组中。

      插入到数据库中的键通过CRC校验和计算一个0~16383之间数,从而确定它的槽,计算公式为slot=CRC16(key)&16383

      • 如果键所在的槽由当前节点负责,那么当前节点直接执行该命令。
      • 如果键所在的槽由其他节点负责,那么当前节点通过slots数组迅速定位到负责该槽的节点,并向客户端返回MOVED错误,客户端收到后会自动将命令转交给对方
    4. 复制与故障转移

      集群中的节点可以通过CLUSTER REPLICATE <节点运行时id>将当前节点设置为id对应节点的从节点,实现主从复制。

      集群中的每个节点都扮演了哨兵的角色。当某个节点疑似下线时,它们通过投票的方式判断该节点是否客观下线,如果是,则进行故障转移,选取新的从机作为节点的主机。

    2、集群的优缺点

    优点:

    1. 集群缓解了单主机模式下的写压力。
    2. 数据可以存储在不同的节点,缓解了海量数据存储的压力。

    缺点:

    1. 不支持多键值插入,除非保证它们映射在同一节点的槽中。
    2. 数据通过异步复制,不保证数据的强一致性
  • 相关阅读:
    M2芯片的Mac上安装Linux虚拟机——提前帮你踩坑
    Android 副屏异显 APP杀进程后未取消问题处理
    【计算机毕业设计】音乐管理系统
    电力巡检/电力抢修行业解决方案:AI+视频技术助力解决巡检监管难题
    信奥中的数学:微积分 高等数学 数学分析
    C语言 typedef和 define的区别
    【网工必备】CIDR-路由聚合你了解了没!?
    现代企业管理笔记——控制
    CVBS、VGA、HDMI、MIPI等8种视频接口详解
    LLM - 理解 多模态大语言模型 (MLLM) 的预训练与相关技术 (三)
  • 原文地址:https://blog.csdn.net/Wyf_Fj/article/details/126598062