十七、Redis进阶-Redis主从复制原理

作者: 温新

分类: 【Redis】

阅读: 1998

时间: 2020-09-05 14:50:13

主从复制原理

1)当启动一个从数据库后,从数据库会向主数据库发送SYNC命令

2)与此同时,主数据库接收到SYNC命令后开始在后台保存快照(RDB持久化的过程),并将保存快照期间接收的命令缓存起来。快照完成后,Redis会将快照文件和所有缓存的命令发送给从数据库

3)从数据库收到后,会载入快照文件并执行到缓存的命令。

以上过程是复制的初始化。复制初始化结束后,主数据库每当收到写命令时就会将命令同步给从数据库,从而保证主从数据库一致。

读写分离一致性

通过复制可以实现读写分离,可以提高服务器的负载能力。读频率大于写频率的应用场景中,当单机Redis无法应付大量的读请求时,可以通过复制功能建立多个从数据库节点,主数据库只进行写操作,而从数据库负责读操作。

从数据库持久化

持久化是比较耗时的操作,为了提高性能,可以通过复制功能建立一个或多个从数据库,并在从数据库中开启持久化,同时主数据库中禁用持久化。当从数据库化崩溃重启后主数据库会自动将数据同步过来,因此不用担心数据丢失。

如果主数据库崩溃时,情况就变得复杂很多。手工通过从数据库恢复主数据库数据时,需要严格按照下面两步操作:

1)在从数据库中使用replicaof no one命令将从数据库提升成主数据库继续服务;

2)启动之前崩溃的主数据库,然后使用replicaof命令将其设置成新的主数据库的从数据库,即可将数据同步回来。

无硬盘复制

主从复制是基于RDB方式的持久化实现的,主数据库端在后台保存RDB快照,从数据库端则接收并载入快照文件。这样实现的优点是简化逻辑,复用已有的代码,但是缺点也很明显,如下:

1)主数据库禁用RDB快照时,如果执行了复制初始化操作,Redis依旧会生成RDB快照,因此下次启动后主数据库会以该快照恢复数据。因为复制发生的时间不确定,这使得恢复的数据可能是任何时间点

2)复制初始化时需要在硬盘中创建RDB快照文件,所以如果硬盘性能很慢时这一过程会对性能产生影响。举个栗子:把Redis作为缓存系统时,不需要持久化,服务器的硬盘读写速度可能较差。当该缓存系统使用一主多从的集群架构时,每次和从数据库同步时,Redis都会执行一次快照,同时对硬盘进行读写,导致性能降低。

增量复制

当主从数据库连接断开后,从数据库会发送SYNC命令重新进行一次完整复制操作。这样即使断开期间数据库变化很小,也需要将数据库中的所有数据重新快照并传送一次。

增量复制基于以下三点实现:

1)从数据库会存储主数据库运行ID(run id)。每个Redis运行实例都会拥有一个唯一的运行ID,每当实例重启就会自动生成一个新的运行ID

2)在复制同步阶段,主数据库每将一个命令传送给从数据库时,都会同时把该命令存放到一个积压队列(backlog)中,并记录下当前积压队列中存放的命令的偏移量范围

3)从数据库接收到主数据库传来的命令时,会记录下该命令的偏移量

这三点是实现增量复制的基础。当主从连接准备就绪后,从数据库会发送一条PSYNC命令来告诉主数据库可以开始把所有的数据同步过来。格式为PSYNC 主数据库的运行ID 断开前最新的命令偏移量

1)首先,主数据库会判断从数据库传送来的运行ID是否和自己运行的ID相同。此步骤是为了确保从数据库之前确实是和自己同步的,以免从数据库拿到错误的数据

2)其次,判断从数据库最后同步成功的命令偏移是否在积压队列中,如果在可则可以执行增量复制,并将积压队列中相应的命令发送给从数据库

积压队列本质上是一个固定长度的循环队列。默认情况下积压队列的大小为1MB,可以通过配置文件repl-backlog-size选项来调整。

积压队列越大,允许的主从数据库断线的时间就越长。

我是小白,期待和优秀的你一起同行!

小白

2020年09月05日

请登录后再评论