Redis学习总结 -- 主从复制

Redis学习总结 – 持久化中,主要介绍了Redis中两种持久化方案AOF和RDB,以及各种方案的优缺点。Redis持久化虽然解决了一般情况下的单机故障导致数据丢失问题,但在特殊情况(如磁盘故障)下,缓存数据依然会丢失。这是因为Redis持久化是将数据存储在本机,本机磁盘故障系统重启时,存储的缓存数据丢失,此时可以通过主从复制将数据存储在其他机器上以提高数据安全。
此外,Redis持久化并不能解决服务可用性的问题。Redis服务可用性是另一个比较大的话题,本文讨论的Redis主从复制是Redis服务可用性的基础。

主从复制

主从复制是指将一台服务器上的数据复制到其他服务器上,前者称为主节点,后者称为从节点。数据复制一般是单向的,只能从主节点到从节点,主节点可以有多个从节点,但从节点只能有一个主节点。

主从复制的作用:

  • 数据冗余:实现了数据的热备份,为Redis提供一种除持久化外的数据冗余方式,属于更高级别的数据安全保护手段。
  • 高可用:主节点异常,从节点可以代替主节点提供服务,从而实现Redis服务的高可用。主从复制是后续Redis sentinel的基础。
  • 读写分离:主节点提供写功能,从节点提供读功能,进行读写分离可以隔离读写之间的影响进一步提高整个系统的性能。

主从复制相关命令

开启主从复制

Redis主从复制功能开启时非常简单的,只需要在从节点上进行操作即可。目前支持三种方式开启主从复制。

  • 配置文件方式:在从节点的配置文件中添加slaveof master_ip master_port
  • 启动命令:在从节点上启动redis-server时,加上**–slaveof master_ip master_port**启动参数
  • 客户端命令:从节点上的Redis-server服务启动后,通过客户端执行slaveof master_ip master_port命令。

注:slaveof是异步命令,从节点执行slaveof命令时,仅保存主节点ip和port,然后就返回OK,具体的复制操作在之后进行。

断开主从复制

当主从复制关系建立后,可以通过slaveof no one命令来断开主从之间的链接,此时从节点上的数据并不会被删除,只是不会再接收主节点的变更数据。

查看主从复制信息

可以通过info replication命令查看主从复制的当前状态信息,如当前角色(master/slave),主节点信息(在从节点上执行info命令),从节点的相关信息(在主节点上执行info命令),复制相关的信息(如缓冲区偏移、缓冲区大小等)。

主从复制步骤

Redis的主从复制主要分为三个阶段:链接建立阶段数据同步阶段命令传播阶段

链接建立阶段

在链接建立阶段主要完成主从之间的链接建立,并完成相应的授权校验。链接建立阶段的主要工作有:
在这里插入图片描述

  • 为什么会有PING命令测试?
    目的是:检查socket连接是否可用,以及主节点当前是否能够处理请求。
  • 权限校验需要注意什么?
    需要和服务器端保持一致,即如果服务器端未开启密码验证,则不需要权限校验;否则,需要保证用户名和密码和服务器端一致。
  • 在链接建立过程中发生失败或超时,该如何处理?
    不断进行重试,直到链接重新建立。在启动过程中,需要关注启动日志,防止配置有误,导致一直无法成功启动。

数据同步阶段

主从节点之间的链接成功建立以后,便可以进行数据同步。在Redis2.8以前,同步过程是从节点发送sync命令执行全量复制;在Redis2.8以后,通过过程中从节点发送psync命令,根据主从节点的当前状态选择全量复制还是部分复制。Redis2.8以后的数据同步流程如下图所示:
数据同步阶段
图中的runid表示服务器运行id,offset表示偏移量,具体作用稍后解释。

  • 全量复制:将主节点中所有数据都发送到从节点中,用于初次复制或无法进行部分复制的情况(主节点复制缓冲区中无法缓存所有变更命令)。
  • 部分复制:将中断期间的变更命令发送到从节点中,用于网络中断等情况后的复制。

全量复制如下图所示:
在这里插入图片描述
由全量复制流程图可知,该操作属于重型操作。当数据量较大时,非常消耗系统资源:

  • 主节点需要生成RDB文件,需要消耗CPU和硬盘IO
  • 主从节点之间通过网络传输RDB文件,消耗主从大量的带宽
  • 从节点清空旧RDB文件,并加载新RDB文件的过程是阻塞的,无法响应客户端的命令(读写分离时,从节点提供只读功能)

全量复制属于重型操作,会导致系统不稳定,应该尽量避免全量复制。与全量复制相比,部分复制仅仅需要将中断期间主节点上的变更命令发送给从节点,更加高效,对系统的影响更小。但是,如果网络中断时间过长,导致主节点无法保存所有中断期间的变更命令,则无法进行部分复制,仍使用全量复制。

在学习部分复制时,需要了解复制缓冲区偏移量offsetrunid服务运行id

  • 复制缓冲区
    在开启主从复制时,主节点会创建一个固定长度的环形队列(FIFO)。复制缓冲区只有一个,并且是由主节点创建,主要用于顺序存储主节点执行过的变更命令。复制缓冲区的长度有限,只保存住节点最近执行的变更命令,最新的命令会覆盖最旧的命令。
    在全量复制过程中,存储生成RDB文件以及发送RDB文件期间的变更命令;在部分复制过程中,存储网络中断期间的变更命令;在后续讲的命令传播阶段,存储主节点当前执行的变更命令。由于只有一个复制缓冲区,多个从节点共享该复制缓冲区,那么控制与不同从节点的复制进度呢?答案就是偏移量offset,主节点会存储发送给每个从节点的数据偏移量,从节点会存储接收到的数据偏移量。
  • 偏移量offset
    主节点和从节点分别维护一个复制偏移量offset,表示主节点发送到从节点的字节数。偏移量可以用来判断主从节点之间的数据库状态,如果offset一致,那么就说明两者数据一致,否则,两者数据不一致,offset之间的差就是从节点缺少的数据。
    当从节点缺少的数据全部都在复制缓冲区中,则可以使用部分复制,否则就只能使用全量复制了。
    实际上,当offset一致时,并不能代表主从节点间的数据状态一致,因为有可能主节点已经变更了,此时offset已经无意义了。为此引入了runid来解决该问题。
  • runid服务运行id
    在Redis服务启动时,都会自动生成一个不重复的随机id作为标识。主从节点初次复制时,主节点将自己的runid发送给从节点,从节点将这个runid保存起来;当断线重连时,从节点会将这个runid发送给主节点,主节点根据runid判断是否可进行部分复制。

可进行部分复制的场景:runid一致,且复制缓冲区存储中断期间所有的变更命令。

数据同步阶段就是从节点数据的初始化过程,在Redis2.8以前,从节点向主节点发送sync命令请求同步数据,在Redis2.8以后,从节点可以发送psync命令请求同步数据。

命令传播阶段

数据同步阶段完成后,主从节点进入命令传播阶段。在该阶段中,主节点将已执行的变更命令发送到从节点中,从节点接收命令并执行,从而保证主从数据的一致性。为了避免发送命令过程中出现问题,主节点也会将该变更命令写入到复制缓冲区中。

命令传播阶段是异步过程,主节点并不会等待从节点回复,因此主从节点间将会有时延,只能保证数据的最终一致性。数据的不一致程度与主从节点的网络状态、数据变更频率、主从的硬件配置和主节点repl-disable-tcp-nodelay配置等有关。
repl-disable-tcp-nodelay配置主要控制是否开启TCP_NODELAY,如果关闭TCP_NODELAY功能,则TCP会对包进行合并,直到达到指定大小或指定时间才会发送出去,这样虽然减少了带宽,但是增加了主从间的数据延迟。当主从间网络状态不好,或者对Redis数据不一致容忍较高时,可关闭该功能,默认是开启该功能。

在命令传播阶段,主从节点之间还保持着心跳机制PINGREPLCONF ACK。心跳机制对于主从复制的超时判断、数据安全等有作用。

  • PING
    主节点定时向从节点发送PING命令,发送频率由 repl-ping-slave-period控制,该命令的作用是让从节点进行超时判断。
    为什么主节点从从节点发送PING?这是因为从节点负责链接的重连,当一段时间内收不到主节点发送的PING命令,则断开当前链接,发起新的链接。
  • REPLCONF ACK
    从节点每秒向主节点发送REPLCONF ACK {offset}命令,该命令主要是从节点向主节点报告当前的数据状态,作用如下:
    (1)实时监测主从节点网络状态:该命令会让主节点进行超时的判断,当主节点在一段时间内都收不到该命令时,可以认为链接中断,可以断开与从节点的链接。在主节点中使用info Replication,可以看到其从节点的状态中的lag值,代表的是主节点上次收到该REPLCONF ACK命令的时间间隔,正常情况下,该值为0或1。
    (2)检测命令丢失:主节点根据命令中的offset和自身存储的offset进行比对,如果发现两者不一致,则可以认定有数据丢失,此时主节点主动发送缺失的数据到从节点中。
    (3)辅助保证从节点的数量和延迟:Redis主节点在从节点数量(min-slaves-to-write配置)过少或延迟(min-slaves-max-lag配置)过高的情况下不会执行写命令。例如min-slaves-to-write和min-slaves-max-lag分别是3和10,含义是如果从节点数量小于3个,或所有从节点的延迟值都大于10s,则主节点拒绝执行写命令。关于主从节点延迟通过从节点状态的lag值来判断的。

主从复制中断

  • 复制缓冲区溢出
    复制缓冲区溢出是指复制缓冲区无法存储特定时间窗内的所有变更命令,此时主节点会断开主从复制链接,导致主从复制中断。存在复制缓冲区溢出的场景如下:
    1、在全量复制过程中,存储生成RDB文件以及发送RDB文件期间的变更命令。当RDB文件过大时,会导致复制缓冲区溢出。存在如下的恶劣情况:全量复制->复制缓冲区溢出,主节点断开链接->从节点重连->全量复制->复制缓冲区溢出,主节点断开链接->…
    2、在部分复制过程中,存储网络中断期间的变更命令。当中断时间过长时,会导致复制缓冲区溢出
    3、在后续讲的命令传播阶段,存储主节点当前执行的变更命令。当主从延迟过大时,会导致复制缓冲区溢出

  • 主从复制超时
    在主从复制过程中,超时是导致复制中断的最重要的原因之一。在整个主从复制过程中,主从节点都需要进行超时判断。repl-timeout参数指定了超时时间的阈值(默认60s),对于主节点和从节点同时有效。
    1、主节点通过距离上次接收REPLCONF ACK的时间差来判断,如果该值超过repl-timeout值,则主节点判定从节点超时,此时断开与从节点的链接,释放相应的资源。
    2、从节点通过距离上次收到主节点的PING命令或数据的时间差来判断,如果该值超过repl-timeout值,则从节点判定主节点超时,则可以断开当前链接,释放相应资源后重新发起新的主从复制链接,避免主从长期数据不一致。存在以下的超时情况:

    • 数据同步阶段:全量复制过程,当数据量过大时,生成RDB文件耗时较多,可能会导致从节点长时间收不到数据而触发超时
    • 命令传播阶段:repl-ping-slave-period和repl-timeout参数配置不合理,repl-timeout应该是repl-ping-slave-period几倍。
    • 慢查询导致的阻塞:主从节点执行慢查询指令(如keys *),导致服务器阻塞,无法响应复制连接中对方节点的请求,可能导致复制超时。

附录

Redis 主从复制

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yuzhiyuxia

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值