关于Redis主从复制的一些理解

一、主从关系建立

默认情况下,每个Redis实例都是主节点,可以通过适当的配置与其它节点建立主从关系。
一个主节点可以有多个从节点,一个从节点只能有一个主节点,从节点可以同时作为其它节点的主节点(树状结构)。
主从复制中,数据的流向是单向的,只能从主节点复制到从节点。

1.1、建立主从关系

建立主从复制关系的方法:

  • 在配置文件中,通过slaveof MASTERIP MASTERPORT进行设置;
  • 在使用redis-server命令启动Redis实例时,指定--slaveof MASTERIP MASTERPORT将该Redis实例作为从节点启动;
  • 在Redis运行时,通过slaveof MASTERIP MASTERPORT指令进行设置。

通过执行INFO replication指令,可以查看当前主从复制状态。
如果主节点通过“requirepass”参数设置了密码验证,从节点需要使用“masterauth”参数设置正确的主节点密码才能与主节点建立主从关系。
默认情况下,从节点都是只读的,可以通过“slave-read-only=[yes|no]”进行设定。

1.2、断开主从关系

通过在从节点上执行slaveof no one断开与主节点的复制关系。
断开主从关系后,从节点不会清空原先从主节点复制来的数据。但是再跟其它节点建立主从关系时,从节点会删除原有的数据。

二、复制过程

当在某个Redis实例上,键入“slaveof MASTERIP MASTERPORT”命令并回车后,复制过程便开始了。大致的过程为:主从之间建立连接 --> 同步数据–> 持续同步。

2.1、主从之间建立连接

  • 1)从节点保存主节点的IP和端口;
  • 2)从节点主动与主节点建立Socket连接;
  • 3)Socket连接建立后,从节点向主节点发送ping命令,以检测Socket连接是否可用。如果主节点返回pong回复,说明连接可用;
  • 4)如果主节点使用requirepass设定了密码,从节点会与主节点进行密码验证;

2.2、同步数据

如果主从节点之间正确建立连接:

  • 1)从节点用本身缓存的“masterid”和复制偏移量“offset”向主节点发起部分复制请求;
  • 2)主节点收到请求,将从节点发来的“masterid”与自身“masterid”对比不一致,认为是第一次复制,告诉从节点应该采用全量复制;同时主节点调用BGSAVE开始进行RDB持久化;
  • 3)从节点接收到主节点要进行全量复制,更新保存的“masterid”;
  • 4)主节点RDB持久化完成,将RDB文件发送给从节点。如果此时有写指令,将会把指令放在复制客户端缓冲区中;
  • 5)从节点接收RDB文件,清空内存中原有的数据,然后将RDB文件中的数据加载到内存;
  • 6)主节点将复制客户端缓冲区中的数据发送给从节点,主节点认为同步过程完成;
  • 7)从节点加载完所有数据后,如果自身开启了AOF持久化,成功执行AOF重写后同步过程完成。

2.3、持续复制

首次数据同步完成后,主节点会持续把写指令发送给从节点,保证主从数据一致。
主从节点都有心跳检测机制。从节点每隔1秒向主节点上报自身的复制偏移量。一方面可以检测主从节点网络状态,一方面可以检查是否有数据丢失,及时从主节点拉取数据保证数据一致性。
主节点不仅有自身的复制偏移量,还保存从节点的复制偏移量,通过对比主从节点的复制偏移量,可以判断数据是否一致。

三、主从复制的问题

3.1、异步复制

主节点上运行的写指令,会在处理完成后,将写指令发送给从节点,从节点再执行主节点发送来的命令。由于主从节点的网络状况、命令的执行速度等,会造成从节点的数据相对于主节点存在延迟,这对于Redis来说无法避免。
延迟的字节数可以通过INFO replication命令对比主从节点的复制偏移量得出:

127.0.0.1:6379> INFO replication
slave0:ip=127.0.0.1,port=6380,state=online,offset=11825,lag=1
master_repl_offset:11825

3.2、关于TCP_NODELAY

Redis的“repl-disable-tcp-nodelay”参数用于控制是否开启TCP_NODELAY,默认是关闭。

  • 关闭时,主节点产生的数据都会及时发送给从节点,会增加网络带宽的消耗,适用于网络良好的环境;
  • 开启时,主节点会合并较小的TCP数据包节省带宽,发送时间取决于操作系统内核。这样就增加了主从之间的延迟,适用于网络紧张的环境。

3.3、复制积压缓冲区和部分复制

复制积压缓冲区是在主从连接建立后,保存在主节点内存中的固定长度的先进先出的队列,用于主从复制过程中的数据补救。默认大小是1MB,由参数“repl-backlog-size”控制。相关信息可以通过INFO replication命令查看:

127.0.0.1:6379> INFO replication
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:11825

由此可以得出复制积压缓冲区内的可用偏移量范围:[repl_backlog_first_byte_offset,repl_backlog_first_byte_offset+repl_backlog_histlen]

部分复制:

  • 如果出现网络异常导致主从状态断开,主节点会将写指令保存在复制积压缓冲区中;
  • 从节点重新连接后,会向主节点请求部分复制,补发丢失的命令数据;
  • 主节点验证masterid一致后,认为该从节点是之前的从节点,可以进行部分复制;
  • 通过对比主从节点的复制偏移量,从主节点的复制积压缓冲区内查找这些数据,如果存在这部分数据,则直接发送给从节点, 这样就可以保持主从节点复制的一致性。

3.4、复制客户端缓冲区

在主从复制第一次建立时,通常会进行全量复制。从节点接收RDB文件到接收完成期间,主节点会将写指令保存在复制客户端缓冲区中,当从节点加载完RDB文件中的数据,主节点再把缓冲区中的数据发送给从节点。
复制客户端缓冲区的默认配置是“client-output-buffer-limit slave 256MB 64MB 60”,即60秒内缓冲区消耗大于64MB或直接超过256MB,主节点将直接关闭与从节点的连接,导致全量同步失败。
在写指令数据量大或者网络状况较差时,可以适当调整该参数,保证全量同步正常进行。

3.5、复制超时时间

Redis默认的复制超时时间是60秒,由参数“repl-timeout”控制。
从2.2节全量复制过程的描述,可以得知全量复制的时间开销主要包括:

  • 主节点BGSAVE时间;
  • RDB文件网络传输时间;
  • 从节点清空原有数据的时间;
  • 从节点加载RDB文件数据到内存中的时间;
  • 开启AOF持久化时的AOF重写时间。

在主节点数据量达到一定规模时,进行一次全量复制的时间很可能已经超过60秒,特别是RDB文件传输非常耗时。这时从节点将放弃接收RDB文件并清理已经传输的临时文件,导致全量复制失败。

3.6、建立主从前的数据备份

特别需要注意的是,建立主从复制关系时,从节点在加载主节点发送来的RDB文件前,会清空自身原有的数据。所以在建立主从关系时,一定先做好数据备份,避免误操作造成的数据丢失。

3.7、复制风暴

复制风暴是指大量从节点对同一主节点或者对同一台机器的多个主节点短时间内发起全量复制的过程。
由于Redis的单线程结构,一般会在单台机器上部署多个Redis实例。如果这台机器上有多个主节点,当这台机器故障恢复重启时,会有大量从节点从这台机器的主节点进行全量复制,会对这台机器的网络带宽造成很大压力。应该尽量避免将主节点分布在单台机器上。
对于一主多从结构来说,当主节点重启恢复后,从节点同时进行全量复制,也会对主节点的网络带宽造成很大压力。应当减少主节点下从节点的数量。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值