Redis入门(四)主从复制

目录

第十一章 Redis主从复制

11.1 简介

11.2 运用实例---一主两从

11.2.1 创建目录,复制配置文件

11.2.2 新建三个配置文件

11.2.3 启动三个Redis服务

11.2.4 配置从机

11.2.5 主写从读操作

11.2.6 一主二仆

11.2.7 薪火相传

11.2.8 反客为主

11.3 主从复制原理

11.3.1 连接建立阶段

11.3.2 数据同步阶段

11.3.3 命令传播阶段

11.3.4 总结

11.4 全量复制和部分复制

11.4.1 全量复制

11.4.2 部分复制

11.5 psync命令的执行

11.6 心跳机制

11.6.1 主->从:PING

11.6.2 从->主:REPLCONF ACK

11.7 哨兵模式

11.7.1 简介

11.7.2 架构

11.7.3 使用步骤

11.7.4 基本原理


第十一章 Redis主从复制

11.1 简介

   主从复制,即master/slaver机制,是指将一台Redis服务器的数据,复制到其他的Redis服务器,主机数据更新后根据配置和策略,自动同步到备机中。前者称为主节点master,后者称为从节点slave,master以写为主,slave以读为主。数据的复制是单向的,只能由主节点到从节点。

   默认情况下,每台Redis服务器都是主节点,且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点一主多从

   作用:

        ①读写分离,性能扩展

        ②容灾快速恢复(当一台从机宕机了,另一台从机可以继续工作)

11.2 运用实例---一主两从

11.2.1 创建目录,复制配置文件

   在根目录下创建一个myredis文件夹,将/etc/redis.conf配置文件复制到myredis文件夹中,并且将配置文件中的appendonly改为no,即关闭AOF。

11.2.2 新建三个配置文件

   因为本文是只在一台虚拟机上运行,为了演示,开启多台redis,需要不同的配置文件,使用不同的端口号。

        ①新建redis6379.conf:

        ②新建redis6380.conf:

        ③新建redis6381.conf:

11.2.3 启动三个Redis服务

   目前还没有配置主从关系,使用命令info replication可以查看主从复制的相关信息。

   使用redis-cli -p 端口号来开启进入三个Redis服务器的客户端,然后查看信息:

11.2.4 配置从机

   命令:

        slaveof <ip> <port>

   在6380、6381两个redis服务器上执行该命令,作为从机:

11.2.5 主写从读操作

   在master上写:

   在slave上读:

11.2.6 一主二仆

   当一个从服务器挂掉了,重启之后不会自动变为从服务器,而是初始为主服务器。如果此时再把该服务器设置成之前服务器的从服务器,会把主服务器中的数据从头复制一份

   当主服务器挂掉了,此时从服务器不会做任何事情,仍旧是该主服务器的从服务器,当主服务器重启后,还是这些从服务器的主服务器。

11.2.7 薪火相传

   上一个slave可以是下一个slave的master,slave同样可以接受其他slave的连接和同步请求,那么该slave作为了链条中下一个的master,可以有效减轻master的写压力,去中心化降低奉献。

   仍旧是命令slaveof <ip> <port>。

   中途变更转向会清楚之前额数据,重新建立拷贝最新的。

   风险是一旦某个slave宕机,后面的slave都没法备份。

   主机挂了,从机还是从机,无法写数据了。

11.2.8 反客为主

   当一个master宕机后,后面的slave可以立刻升为master,其后面的slave不用做任何修改。

   命令:

        slaveof no one

11.3 主从复制原理

   参考:深入学习Redis(3):主从复制 - 编程迷思 - 博客园

   主从复制过程大体可以分为3个阶段:连接建立阶段(准备阶段)、数据同步阶段、命令传播阶段。

11.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命令后,可能出现3种情况:

        1.返回pong:说明socket连接正常,且主节点当前可以处理请求,复制过程继续。

        2.超时:一定时间后从节点仍未收到主节点的回复,说明socket连接不可用,则从节点断开

          socket连接,并重连。

        3.返回pong以外的结果:如果主节点返回其他结果,如正在处理超时运行的脚本,说明主节

          点当前无法处理命令,则从节点断开socket连接,并重连。

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

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

11.3.2 数据同步阶段

   主从节点之间的连接建立以后,便可以开始进行数据同步,该阶段可以理解为从节点数据的初始化。具体执行的方式是:从节点向主节点发送psync命令(Redis2.8以前是sync命令),开始同步。

   需要注意的是,在数据同步阶段之前,从节点是主节点的客户端,主节点不是从节点的客户端;而到了这一阶段及以后,主从节点互为客户端。原因在于:在此之前,主节点只需要响应从节点的请求即可,不需要主动发请求,而在数据同步阶段和后面的命令传播阶段,主节点需要主动向从节点发送请求(如推送缓冲区中的写命令),才能完成复制。

11.3.3 命令传播阶段

   数据同步阶段完成后,主从节点进入命令传播阶段。在这个阶段主节点将自己执行的写命令发送给从节点(互为客户端),从节点接收命令并执行,从而保证主从节点数据的一致性。

   在命令传播阶段,除了发送写命令,主从节点还维持着心跳机制:PING和REPLCONF ACK

   命令传播是异步的过程,即主节点发送写命令后并不会等待从节点的回复,因此实际上主从节点之间很难保持实时的一致性,延迟在所难免。

11.3.4 总结

   1.slave启动成功连接到master后会发送一个psync命令;

   2.Master接到命令启动后台的存盘进程,同时收集所有接收到的用于修改数据集命令,在后台进程执行完毕之后,master将传送整个数据文件到slave,以完成一次完全同步。

        同步机制分为全量复制和增量复制。

        全量复制:slave服务在接收到数据库文件数据后,将其存盘并加载到内存中。

        增量复制:Master继续将新的所有收集到的修改命令依次传给slave,完成同步。

   3.只要是重新连接master,一次完全同步(全量复制)将被自动执行

11.4 全量复制和部分复制

   在Redis2.8以前,从节点向主节点发送sync命令请求同步数据,此时的同步方式是全量复制;在Redis2.8及以后,从节点可以发送psync命令请求同步数据,此时根据主从节点当前状态的不同,同步方式可能是全量复制或部分复制。

11.4.1 全量复制

   用于初次复制或其他无法进行部分复制的情况,将主节点中的所有数据都发送给从节点,是一个非常重型的操作。

   过程:

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

          请求,但主节点判断无法进行部分复制;

        ②主节点收到全量复制的命令后,执行bgsave,在后台生成RDB文件,并使用一个缓冲区(称

          为复制缓冲区主节点会为每一个从节点分别分配复制缓冲区)记录从现在开始执行的所有写

          命令;

        ③主节点的bgsave执行完成后,将RDB文件发送给从节点;从节点首先清除自己的旧数据

          然后载入接收的RDB文件,将数据库状态更新至主节点执行bgsave时的数据库状态;

        ④主节点将前述复制缓冲区中的所有写命令发送给从节点,从节点执行这些写命令,将数据

          库状态更新至主节点的最新状态;

        ⑤如果从节点开启了AOF,则会触发bgrewriteaof的执行,从而保证AOF文件更新至主节点的

          最新状态。

   整个过程中,需要传输的就是两部分:RDB文件 + 复制缓冲区的记录

11.4.2 部分复制

   用于网络中断等情况后的复制,只将中断期间主节点执行的写命令发送给从节点,与全量复制相比更加高效。需要注意的是,如果网络中断时间过长,导致主节点没有能够完整地保存中断期间执行的写命令,则无法进行部分复制,仍使用全量复制。

   部分复制的实现,依赖于三个重要的概念:

        ①复制偏移量:主节点和从节点分别维护一个复制偏移量(offset),代表的是主节点向从节

          点传递的字节数;主节点每次向从节点传播N个字节数据时,主节点的offset增加N;从节点

          每次收到主节点传来的N个字节数据时,从节点的offset增加N。ffset用于判断主从节点的数

          据库状态是否一致:如果二者offset相同,则一致;如果offset不同,则不一致,此时可以根

          据两个offset找出从节点缺少的那部分数据。

        ②复制积压缓冲区:复制积压缓冲区是由主节点维护的、固定长度的、先进先出(FIFO)队

          列,默认大小1MB;当主节点开始有从节点时创建,其作用是备份主节点最近发送给从节点

          的数据。注意,无论主节点有一个还是多个从节点,都只需要一个复制积压缓冲区(一个主节

          点只有一个)。在命令传播阶段,主节点除了将写命令发送给从节点,还会发送一份给复制积

          压缓冲区,作为写命令的备份,除了存储写命令,复制积压缓冲区中还存储了其中的每个字

          节对应的复制偏移量(offset)。由于复制积压缓冲区定长且是先进先出,所以它保存的是主节

          点最近执行的写命令;时间较早的写命令会被挤出缓冲区。由于该缓冲区长度固定且有限,

          因此可以备份的写命令也有限,当主从节点offset的差距过大超过缓冲区长度时,将无法执

          行部分复制,只能执行全量复制。从节点将offset发送给主节点后,主节点根据offset和缓冲

          区大小决定能否执行部分复制:如果offset偏移量之后的数据,仍然都在复制积压缓冲区

          里,则执行部分复制;如果offset偏移量之后的数据已不在复制积压缓冲区中(数据已被挤

          出),则执行全量复制。

        ③服务器运行ID:每个Redis节点(无论主从),在启动时都会自动生成一个随机ID(每次启动都

          不一样),由40个随机的十六进制字符组成;runid用来唯一识别一个Redis节点。通过info

          Server命令,可以查看节点的runid。主从节点初次复制时,主节点将自己的runid发送给从

          节点,从节点将这个runid保存起来。当断线重连时,从节点会将这个runid发送给主节点,

          主节点根据runid判断能否进行部分复制:如果从节点保存的runid与主节点现在的runid相

          同,说明主从节点之前同步过,主节点会继续尝试使用部分复制(到底能不能部分复制还要看

          offset和复制积压缓冲区的情况);如果从节点保存的runid与主节点现在的runid不同,说明从

          节点在断线前同步的Redis节点并不是当前的主节点,只能进行全量复制。

11.5 psync命令的执行

   执行过程如下图:

首先,从节点根据当前状态,决定如何调用psync命令:

  • 如果从节点之前未执行过slaveof或最近执行了slaveof no one,则从节点发送命令为psync ? -1,向主节点请求全量复制;
  • 如果从节点之前执行了slaveof,则发送命令为psync <runid> <offset>,其中runid为上次复制的主节点的runid,offset为上次复制截止时从节点保存的复制偏移量。

主节点根据收到的psync命令,及当前服务器状态,决定执行全量复制还是部分复制:

  • 如果主节点版本低于Redis2.8,则返回-ERR回复,此时从节点重新发送sync命令执行全量复制;
  • 如果主节点版本够新,且runid与从节点发送的runid相同,且从节点发送的offset之后的数据在复制积压缓冲区中都存在,则回复+CONTINUE,表示将进行部分复制,从节点等待主节点发送其缺少的数据即可;
  • 如果主节点版本够新,但是runid与从节点发送的runid不同,或从节点发送的offset之后的数据已不在复制积压缓冲区中(在队列中被挤出了),则回复+FULLRESYNC <runid> <offset>,表示要进行全量复制,其中runid表示主节点当前的runid,offset表示主节点当前的offset,从节点保存这两个值,以备使用。

11.6 心跳机制

   心跳机制对于主从复制的超时判断、数据安全等有作用。

11.6.1 主->从:PING

   每隔指定的时间,主节点会向从节点发送PING命令(官方文档是说从节点向主节点发送PING命令的),这个PING命令的作用,主要是为了让从节点进行超时判断。PING发送的频率由repl-ping-slave-period参数控制,单位是秒,默认值是10s。

11.6.2 从->主:REPLCONF ACK

   在命令传播阶段,从节点会向主节点发送REPLCONF ACK命令,频率是每秒1次。

   命令格式为:REPLCONF ACK {offset},其中offset指从节点保存的复制偏移量。

   REPLCONF ACK命令的作用包括:

        ①实时监测主从节点网络状态:该命令会被主节点用于复制超时的判断。此外,在主节点中

          使用info Replication,可以看到其从节点的状态中的lag值,代表的是主节点上次收到该

          REPLCONF ACK命令的时间间隔,在正常情况下,该值应该是0或1。

        ②检测命令丢失:从节点发送了自身的offset,主节点会与自己的offset对比,如果从节点数据

          缺失(如网络丢包),主节点会推送缺失的数据(这里也会利用复制积压缓冲区)。

          注意:offset和复制积压缓冲区,不仅可以用于部分复制,也可以用于处理命令丢失等情形;

          区别在于前者是在断线重连后进行的,而后者是在主从节点没有断线的情况下进行的。

        ③辅助保证从节点的数量和延迟: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值。

11.7 哨兵模式

   参考:深入学习Redis(4):哨兵 - 编程迷思 - 博客园

11.7.1 简介

   Redis Sentinel,即Redis哨兵,在Redis 2.8版本开始引入。哨兵的核心功能是主节点的自动故障转移。可以理解为反客为主的自动版,能够后台监控主机是否故障,如果故障了根据投票数自动将从节点转换为主节点。一个哨兵可以监控多个节点

   功能:

        ①监控(Monitoring):哨兵会不断地检查主节点和从节点是否运作正常。

        ②自动故障转移(Automatic failover):当主节点不能正常工作时,哨兵会开始自动故障转移操

          作,它会将失效主节点的其中一个从节点升级为新的主节点,并让其他从节点改为复制新的

          主节点。

        ③配置提供者(Configuration provider):客户端在初始化时,通过连接哨兵来获得当前Redis

          服务的主节点地址。

        ④通知(Notification):哨兵可以将故障转移的结果发送给客户端。

11.7.2 架构

   由两部分组成:

        哨兵节点:哨兵系统由一个或多个哨兵节点组成,哨兵节点是特殊的redis节点,不存储数据

        数据节点:主节点和从节点都是数据节点

   哨兵节点本质上就是redis节点

11.7.3 使用步骤

   依旧是上面的一主二仆模式,主节点是6379,从节点是6380、6381。

  • 新建自定义sentinel.conf文件(文件名字不能出错),配置哨兵,填写内容:

sentinel monitor mymaster 127.0.0.1 6379 1

mymaster:为监控对象起的服务器名称,别名

1:至少需要有多少个哨兵同意迁移的数量

  • 启动哨兵:redis-sentinel sentinel.conf。哨兵进程的端口号为26379

  • 当主机挂掉了,会在从机中产生新的主机。怎么选择?

        此时哨兵节点启动和故障转移阶段,各个节点的配置文件会被重写。对于主从节点,主要是

      slaveof配置的变化:新的主节点没有了slaveof配置,其从节点则slaveof新的主节点。对于哨

      兵节点,除了主从节点信息的变化,纪元(epoch)也会变化。

        优先级的配置参数:replica-priority。默认100,值越小,优先级越高。

        偏移量是上文提到的offset,runid也是上文提及的每个节点的一个id。

11.7.4 基本原理

   关于哨兵的原理,关键是了解以下几个概念:

        ①定时任务:每个哨兵节点维护了3个定时任务。定时任务的功能分别如下:通过向主从节点

          发送info命令获取最新的主从结构;通过发布订阅功能获取其他哨兵节点的信息;通过向其

          他节点发送ping命令进行心跳检测,判断是否下线。

        ②主观下线:在心跳检测的定时任务中,如果其他节点超过一定时间没有回复,哨兵节点就

          会将其进行主观下线。顾名思义,主观下线的意思是一个哨兵节点“主观地”判断下线;与主

          观下线相对应的是客观下线。

        ③客观下线:哨兵节点在对主节点进行主观下线后,会通过sentinel is-master-down-by-addr

          命令询问其他哨兵节点该主节点的状态;如果判断主节点下线的哨兵数量达到一定数值,则

          对该主节点进行客观下线。

            需要特别注意的是,客观下线是主节点才有的概念;如果从节点和哨兵节点发生故障,被

          哨兵主观下线后,不会再有后续的客观下线和故障转移操作。

        ④选举领导者哨兵节点:当主节点被判断客观下线以后,各个哨兵节点会进行协商,选举出

          一个领导者哨兵节点,并由该领导者节点对其进行故障转移操作。

            监视该主节点的所有哨兵都有可能被选为领导者,选举使用的算法是Raft算法Raft算法的

          基本思路是先到先得:即在一轮选举中,哨兵A向B发送成为领导者的申请,如果B没有同意

          过其他哨兵,则会同意A成为领导者。选举的具体过程这里不做详细描述,一般来说,哨兵

          选择的过程很快,谁先完成客观下线,一般就能成为领导者。

        ⑤故障转移:选举出的领导者哨兵,开始进行故障转移操作,该操作大体可以分为3个步骤:

  • 在从节点中选择新的主节点:选择的原则是,首先过滤掉不健康的从节点;然后选择优先级最高的从节点(由slave-priority指定);如果优先级无法区分,则选择复制偏移量最大的从节点;如果仍无法区分,则选择runid最小的从节点。
  • 更新主从状态:通过slaveof no one命令,让选出来的从节点成为主节点;并通过slaveof命令让其他节点成为其从节点。
  • 将已经下线的主节点(即6379)设置为新的主节点的从节点,当6379重新上线后,它会成为新的主节点的从节点。

PS:根据尚硅谷视频整理,如有侵权,联系删除。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值