Redis主从同步

一、主从模式的介绍

我们需要的是保障Redis的高可用,减少甚至避免Redis服务发生宕机的可能。
目前实现Redis高可用的模式主要有三种: 主从模式、哨兵模式、集群模式。今天我们先来聊一下主从模式。
Redis 提供的主从模式,是通过复制的方式,将主服务器上的Redis的数据同步复制一份到从 Redis 服务器,这种做法很常见,MySQL通过binlog进行的主从复制也是这么做的。
主节点的Redis我们称之为master,从节点的Redis我们称之为slave,主从复制为单向复制,只能由主到从,不能由从到主。可以有多个从节点,比如1主3从甚至n从,从节点的多少根据实际的业务需求来判断。

二、主从同步如何保证数据的安全性和一致性?

为了保证主服务器Redis的数据和从服务器Redis的数据的一致性,也为了分担访问压力,均衡负载,应用层面一般采取读写分离的模式。
读操作:主、从库都可以执行,一般是在从库上读数据,对实时性和准确性有100%高真要求的部分业务,在谨慎评估之后也可以读主库,前提是不能给Master带来高压力和风险。
写操作:只在主库上写数据,写完之后将写操作指令同步到从库

1.读写分离模式

读写分离模式的使用跟MySQL做读写分离的初衷是一样的。因为我们已经划分了主从库,而且从库的数据是由主库单向复制的。如果主从库都可以执行写指令,那么在高频并发场景下对不同的副本数据做修改,操作会具有无序性,极易导致各副本产生数据不一致,这是分布式模式的弊病。 如果非要保证数据的强一致性,Redis 需要加锁处理,或者使用队列顺序执行,这样势必降低Redis的性能,降低服务的吞吐能力,这就不是高性能Redis所能接受的。 

2.主从和读写分离模式的意义: 

读写分离的意义

  1. 提高性能:读请求可以分配到从节点上,减轻主节点的读压力,从而提高整体系统的读性能。
  2. 增加系统吞吐量:能够更好地应对高并发的读请求,提升系统的服务能力。

主从同步的意义

  1. 数据备份:从节点保存了主节点的数据副本,增加了数据的安全性。
  2. 高可用性:当主节点出现故障时,可以快速切换到从节点,保证服务的连续性。
  3. 扩展性:便于横向扩展 Redis 集群,增加更多的从节点来分担负载。
  4. 数据一致性:确保主从节点之间的数据保持一致,避免数据不一致的情况发生。

三、搭建主从同步模式

Redis的主从架构中,主节点的数据更新会自动被复制到从节点,确保数据的一致性。主从复制的开启,在从节点配置和发起即可,不需要我们在主节点做任何事情。

 1.主库配置

# 设置Redis监听的IP地址和端口号,默认监听所有IP地址和6379端口
bind 0.0.0.0

# 启用保护模式,允许远程访问
protected-mode no

# 指定Redis监听的端口号
port 6380

# 增加Redis的最大内存限制,以容纳更多数据
#maxmemory 16GB   增加内存限制,根据您的服务器实际内存调整
maxmemory 20480mb

2.从库配置

在从服务器的配置文件中加入

replicaof <masterip> <masterport>

假设现在有主实例 (10.21.125.1:6380)、从实例 A(10.21.125.2:6379)和 从实例 B (10.21.125.3:6379),在两个从实例上分别执行以下命令,就成为了Slave,主实例成为 Master。

# 修改为从库监听的端口号
port 6379

# 添加需要同步的主库信息
replicaof 10.21.125.1 6380

四、主从复制原理 

Redis 的主从复制原理可以更详细地描述如下:

  1. 建立连接:从节点主动向主节点发起连接请求。
  2. 同步请求:从节点向主节点发送 SYNC 命令,请求进行数据同步。
  3. 主节点备份:主节点接收到 SYNC 命令后,执行 BGSAVE 命令创建一个当前数据的 RDB 快照文件。
  4. 传输快照:主节点将生成的 RDB 快照文件发送给从节点。
  5. 加载快照:从节点接收到快照文件后,将其加载到内存中,完成数据的初始化。
  6. 命令传播:在完成快照同步后,主节点会将后续执行的写命令以及相关的配置修改等信息,以命令流的形式发送给从节点。
  7. 从节点执行命令:从节点接收到主节点发送的命令后,逐一执行这些命令,以保持与主节点数据的一致性。

需要注意的是,在实际应用中,Redis 还提供了部分重同步的机制,当网络中断等情况导致主从节点数据不一致时,可以通过部分重同步来快速恢复同步状态,而无需再次进行全量的快照同步。

此外,Redis 还支持增量复制,即主节点只将增量的命令发送给从节点,进一步提高了同步的效率。

 五、主从库的同步机制

Redis 的主从复制机制均采用异步复制,我们也称为乐观复制,这种复制方式意味着不能完全保证主库和从库数据的实时一致性。
Redis的主从复制机制可以根据不同的业务场景可以采用不同的应对方式。下面是一些主要场景及其对应的实现方案:

        1. 首次配置完成主从库之后的全量复制:在从库第一次连接到主库时,将采用psync复制方式进行全量复制。 这意味着从库会从头开始复制主库中的全部数据。
        2. 主从正常运行期间,准实时同步:在正常运行状态下,从库通过读取主库的缓冲区来进行增量复制。 这个过程涉及复制主库上发生的新的数据变更。
        3. 从库第二次启动(异常或主从网络断开后恢复): Append增量数据 + 准实时同步将通过读取主库的缓冲区进行部分复制。 这种方式能够快速同步中断期间发生的数据变更,而不会对主库造成重大影响。

psync 

PSYNC 命令是Redis中用于从节点与主节点之间数据同步的关键命令。它的工作原理包括以下几个步骤:

1. 启动或重连判断:
当从节点(Slave)启动或与主节点(Master)的连接断开后重连时,从节点需要确定是否曾经同步过。
如果从节点没有保存任何主节点的运行ID(runid),它将视为第一次连接到主节点。

2. 首次同步处理:
如果是第一次同步的情况下,从节点会发送 PSYNC -1 命令给主节点,代表请求全量数据同步。 全量同步是指主节点将其所有数据完整地Copy一份给从节点。

3. 主从重连后的处理:
对于之前已经同步过的从节点,它会发送 PSYNC runid offset 命令,其中runid是主节点的唯一标识符,offset是从节点上次同步数据的偏移量。这样本质就是增量同步。

4. 主节点响应:
主节点接收到PSYNC命令后,会检查runid是否匹配,以及offset是否在复制积压缓冲区的范围内。
如果匹配且offset有效,主节点将回复CONTINUE,并发送自从节点上次断开连接以来的所有写命令。

5. 触发全量同步的条件:
如果runid不匹配,或offset超出了积压缓冲区的范围,主节点将通知从节点执行全量同步,回复FULLRESYNC runid offset

6. 积压缓冲区的作用:
主节点会在处理写命令的同时,将这些命令存入复制积压队列(缓冲池),同时记录队列中存放命令的全局offset。
这样做法是保证了效率。当从节点断线重连,且条件允许时(runid和offset都具备),它可以通过offset从积压队列中进行增量复制,而不是全量复制,这样复制的成本就低很多。

7. 保障数据一致性:
PSYNC机制允许从节点在网络不稳定或其他意外断开连接的情况下,能够以增量方式重新同步数据。这也是它的一大优势,那就是保持主从节点数据的一致性。

8. 什么时候启动重连工作
判断是否进行全量同步,需要考虑两个关键因素:首先,确认这是否是第一次进行数据同步;其次,检查缓存区是否已经达到或超过其容量上限。只有在是第一次同步,或者缓存区已溢出的情况下,才会执行全量同步。

一主多从同步说明

如果你有多个从库,则在每次连接的时候需要注意一些细节,如下:

  • 多个从库情况下,每个从库都会记录自己的 slave_repl_offset,各自复制的进度也不相同。
  • 重连主库进行恢复时,从库会通过 psync 命令将 slave_repl_offset 告知主库,主库判断从库的状态,来决定进行增量复制,还是全量复制。
  • replication buffer 和 repl_backlog 的说明
    • replication buffer 是主从库在进行全量复制时,主库上用于和从库连接的客户端的 buffer
    • repl_backlog_buffer 是为了支持从库增量复制,主库上用于持续保存写操作的一块专用 buffer,所有从库共享的
  • 主库和从库会各自记录自己的复制进度,所以,不同的从库在进行恢复时,需要将自己的复制进度(slave_repl_offset)发给主库,主库才可以按照偏移量取数据跟它同步。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值