zoukankan      html  css  js  c++  java
  • Redis学习笔记四:主从复制和哨兵

    这里是Redis学习笔记的第四篇,主要讲Redis主从复制和哨兵。

    为什么需要主从复制

    单机redise风险与问题

    • 问题1 机器故障
    • 问题2 容量瓶颈

    为了避免单点redis服务器故障,准备多台服务器,互相连通。将数据复制多个副本保存在不同的服务器上,链接在一起,并保证数据是否同步的,即使有其中一台服务器宕机,其他服务器依然可以继续提供服务,实现Redis的高可用,同时实现数据冗余备份。

    但是多台服务器怎么保证这么多服务器的数据同步呢?让每个数据库的数据都读写数据并且保持一致是一件很难的事情,于是有一种方案:我们让一台主服务器写,多台从服务器读 (这也考虑到数据库大大部分操作都是查询操作),然后主服务器写操作更新数据同步给从服务器。所以我们有了主从复制。

    什么是主从复制

    考虑上面我们的解决方案。主从复制即将master中的数据即时,有效的复制到slave中。从而达到各个服务器数据同步的目的。
    特征:一个master可以拥有多个slave,一个slave只对应一个master

    master的职责:
      写数据
      执行写操作时,将出现变化的数据自动同步到slave
      读数据(可忽略)

    slave的职责:
      读数据
      写数据(禁止)

    主从复制的作用
      读写分离:master写,slave读,提高服务器的读写负载能力
      负载均衡:基于主从结构,配合读写分离,由slave分担master负载,并根据需求的变化,改变slave的数量,通过多个从节点分担数据读取负载,大大提高Redis服务器并发量与数据吞吐量
      故障恢复:当master出现问题时,由slave提供服务,实现快速的故障恢复
      数据冗余:实现数据热备份,时持久化之外的一种数据冗余方式
      高可用基石:基于主从复制,构建哨兵模式与集群,实现Redis的高可用方案

    主从复制工作流程

    主从复制过程大体可以分为3个阶段

      1,建立连接阶段(即准备阶段)  2,数据同步阶段  3,命令传播阶段

    我们来稍微详细第讲一下这三个过程。

    1,建立连接阶段

    保存主节点信息

    从节点服务器内部维护了两个字段,即masterhost和masterport字段,用于存储主节点的ip和port信息。

    slaveof是异步命令,从节点完成主节点ip和port的保存后,向发送slaveof命令的客户端直接返回OK,实际的复制操作在这之后才开始进行。

    建立socket连接

    从节点每秒1次调用复制定时函数replicationCron(),如果发现了有主节点可以连接,便会根据主节点的ip和port,创建socket连接。如果连接成功:

    从节点:为该socket建立一个专门处理复制工作的文件事件处理器,负责后续的复制工作,如接收RDB文件、接收命令传播等。

    主节点:接收到从节点的socket连接后(即accept之后),为该socket创建相应的客户端状态,并将从节点看做是连接到主节点的一个客户端,后面的步骤会以从节点向主节点发送命令请求的形式来进行。

    发送ping命令

    从节点成为主节点的客户端之后,发送ping命令进行首次请求,目的是:检查socket连接是否可用,以及主节点当前是否能够处理请求。

    从节点发送ping命令后,主结点一般返回pong:说明socket连接正常,且主节点当前可以处理请求,复制过程继续。

    身份验证

    如果从节点中设置了masterauth选项,则从节点需要向主节点进行身份验证;没有设置该选项,则不需要验证。

    从节点进行身份验证是通过向主节点发送auth命令进行的,auth命令的参数即为配置文件中的masterauth的值。如果主节点设置密码的状态,与从节点masterauth的状态一致(一致是指都存在,且密码相同,或者都不存在),则身份验证通过,复制过程继续;如果不一致,则从节点断开socket连接,并重连。

    发送从节点端口信息

    身份验证之后,从节点会向主节点发送其监听的端口号,主节点将该信息保存到该从节点对应的客户端的slave_listening_port字段中;该端口信息除了在主节点中执行info Replication时显示以外,没有其他作用。

    这一阶段的指令/配置为:

    主从连接(slave连接master)
     方式一:客户端发送命令
        slaveof <masterip> <masterport>
     方式二:启动服务器参数
        redis-server -slaveof <masterip> <masterport>
     方式三:服务器配置
        slaveof <masterip> <masterport>
    
    
    还有一些其他的配置信息:
     slave系统信息
        master_link_down_since_seconds
        masterhost
        masterport
     master系统信息
        slave_listening_port(多个)

     客户端发送命令:

      slaveof no one

    说明:slave断开连接后,不会删除已有数据,只是不再接受master发送的数据

      

    2,数据同步阶段

    这一步的主要目的就是把,从结点的数据库更新成主节点的数据。简单划分这一阶段有5步:

    1,请求同步   2,创建RDB同步数据 3,恢复RDB同步数据  4,请求部分同步数据  5,恢复部分同步数据

     这一阶段的重点是:全量复制和部分复制。

    1. 全量复制:用于初次复制或其他无法进行部分复制的情况,将主节点中的所有数据都发送给从节点,是一个非常重型的操作。
    2. 部分复制:用于网络中断等情况后的复制,只将中断期间主节点执行的写命令发送给从节点,与全量复制相比更加高效。需要注意的是,如果网络中断时间过长,导致主节点没有能够完整地保存中断期间执行的写命令,则无法进行部分复制,仍使用全量复制。

    全量复制:

    (1)从节点判断无法进行部分复制,向主节点发送全量复制的请求;或从节点发送部分复制的请求,但主节点判断无法进行全量复制;

    (2)主节点收到全量复制的命令后,执行bgsave,在后台生成RDB文件,并使用一个缓冲区(称为复制缓冲区)记录从现在开始执行的所有写命令

    (3)主节点的bgsave执行完成后,将RDB文件发送给从节点;从节点首先清除自己的旧数据,然后载入接收的RDB文件,将数据库状态更新至主节点执行bgsave时的数据库状态

    (4)主节点将前述复制缓冲区中的所有写命令发送给从节点,从节点执行这些写命令,将数据库状态更新至主节点的最新状态

    (5)如果从节点开启了AOF,则会触发bgrewriteaof的执行,从而保证AOF文件更新至主节点的最新状态

    部分复制:

    部分复制依赖于三个重要的概念:服务器运行ID,复制积压缓冲区,复制偏移量

    服务器运行ID(runid)
     概念:服务器运行ID是每一台服务器每次运行的身份识别码,一台服务器多次运行可以生成多个运行id
     组成:运行id由40位字符组成,是一个随机的十六进制字符  例如:fdc9ff13b9bbaab28db42b3d50f852bb5e3fcdce
     作用:运行id被用于在服务器间进行传输,识别身份。如果想两次操作均对同一台服务器进行,必须每次操作携带对应的运行id,用于对方识别
     实现方式:运行id在每台服务器启动时自动生成的,master在首次连接slave时,会将自己的运行ID发送给slave,slave保存此ID,通过info Server命令,可以查看节点的runid

    复制缓冲区
     概念:复制缓冲区,又名复制积压缓冲区,是一个先进先出(FIFO)的队列,用于存储服务器执行过的命令,每次传播命令,master都会将传播的命令记录下来,并存储在复制缓冲区
     复制缓冲区默认数据存储空间大小是1M,由于存储空间大小是固定的,当入队元素的数量大于队列长度时,最先入队的元素会被弹出,而新元素会被放入队列
     由来:每台服务器启动时,如果开启有AOF或被连接成为master节点,即创建复制缓冲区
     作用:用于保存master收到的所有指令(仅影响数据变更的指令,例如set,select)
     数据来源:当master接收到主客户端的指令时,除了将指令执行,会将该指令存储到缓冲区中

    主从服务器复制偏移量(offset)
     概念:一个数字,描述复制缓冲区中的指令字节位置
     master复制偏移量:记录发送给所有slave的指令字节对应的位置(多个)
     slave复制偏移量:记录slave接收master发送过来的指令字节对应的位置(一个)
     作用:同步信息,比对master与slave的差异,当slave断线后,恢复数据使用

    3,命令传播阶段

    数据同步阶段完成后,主从节点进入命令传播阶段;在这个阶段主节点将自己执行的写命令发送给从节点,从节点接收命令并执行,从而保证主从节点数据的一致性。在命令传播阶段,除了发送写命令,主从节点还维持着心跳机制:PING和REPLCONF ACK。

    主->从:PING

    每隔指定的时间,主节点会向从节点发送PING命令,这个PING命令的作用,主要是为了让从节点进行超时判断。

    PING发送的频率由 repl-ping-slave-period 参数控制,单位是秒,默认值是10s。

    从->主:REPLCONF ACK

    在命令传播阶段,从节点会向主节点发送REPLCONF ACK命令,频率是每秒1次;命令格式为:REPLCONF ACK {offset},其中offset指从节点保存的复制偏移量。

    REPLCONF ACK命令的作用包括:

    (1)实时监测主从节点网络状态:该命令会被主节点用于复制超时的判断。此外,在主节点中使用info Replication,可以看到其从节点的状态中的lag值,代表的是主节点上次收到该REPLCONF ACK命令的时间间隔,在正常情况下,该值应该是0或1。

    (2)检测命令丢失:从节点发送了自身的offset,主节点会与自己的offset对比,如果从节点数据缺失(如网络丢包),主节点会推送缺失的数据(这里也会利用复制积压缓冲区)。注意,offset和复制积压缓冲区,不仅可以用于部分复制,也可以用于处理命令丢失等情形;区别在于前者是在断线重连后进行的,而后者是在主从节点没有断线的情况下进行的。

    (3)辅助保证从节点的数量和延迟:Redis主节点中使用min-slaves-to-write和min-slaves-max-lag参数,来保证主节点在不安全的情况下不会执行写命令;所谓不安全,是指从节点数量太少,或延迟过高。例如min-slaves-to-write和min-slaves-max-lag分别是3和10,含义是如果从节点数量小于3个,或所有从节点的延迟值都大于10s,则主节点拒绝执行写命令。而这里从节点延迟值的获取,就是通过主节点接收到REPLCONF ACK命令的时间来判断的,即前面所说的info Replication中的lag值。

    哨兵模式

    为什么需要哨兵

    在我们上诉的主从复制解决方案中,很容易想到可能会出现:主服务器宕机了怎么办?那么我们有以下工作要做:

    1,关闭master和所有slave  2,找一个slave作为master  3,修改其他slave的配置,连接新的主  4,启动新的master与slave  5,全量复制*N+部分复制*N

    但是这些工作要思考几个问题:

     关闭期间的数据服务谁来承接?
     找一个主?怎么找法?
     修改配置后,原始的主恢复了怎么办?

     所以我们有了哨兵模式来解决。

    什么是哨兵模式

    哨兵(sentinel) 是一个分布式系统,用于对主从结构中的每台服务器进行监控,当出现故障时通过投票机制选择新的master并将所有slave连接到新的master。

    哨我们通常讲兵的作用有三个:
    1,监控
      不断的检查master和slave是否正常运行。
      master存活检测、master与slave运行情况检测
    2,通知(提醒)
      当被监控的服务器出现问题时,向其他(哨兵间,客户端)发送通知。
    3,自动故障转移
      断开master与slave连接,选取一个slave作为master,将其他slave连接到新的master,并告知客户端新的服务器地址


    注意:哨兵也是一台redis服务器,只是不提供数据服务。通常哨兵配置数量为单数


    启用哨兵模式

    这个指令能启动哨兵

    redis-sentinel sentinel- 端口号 .conf
    

    我们需要的配置项

    哨兵主从切换的工作流程

     哨兵在进行主从切换过程中经历三个阶段
      1,监控:Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。

      2,通知:当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。

      3,故障转移:当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器; 当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。

    这一部分黑马程序员的视频和PPT讲解十分生动:

     

      

     

    参考资料:

    Bilibili黑马程序员的Redis视频:https://www.bilibili.com/video/BV1CJ411m7Gc

    Redis主从复制:https://www.cnblogs.com/wade-luffy/p/9639986.html  (好文章)

    Redis哨兵模式:https://www.cnblogs.com/kevingrace/p/9004460.html

  • 相关阅读:
    str_pad 和 filter_var
    phpstorm主题下载地址
    php二维数组的排序
    wx.request出现400 bad request的问题
    php里的闭包函数
    关于宝塔下的项目中的php不能访问的问题
    字体大小适配宽度
    递归复制&查看文件夹下的指定后缀的文件
    find_in_set
    给动态ajax添加的元素添加click事件
  • 原文地址:https://www.cnblogs.com/clno1/p/13021281.html
Copyright © 2011-2022 走看看