Redis的主从库

104 阅读4分钟

前言

Redis有AOF(Append-Only File)和RDB(Redis Database)的两种数据持久化方法,它们可以在Redis发生宕机时通过回放日志和重新读入RDB文件的方式恢复数据,从而保证尽量少丢失数据,提升可靠性。但是,即使使用了这两种方法,仍然存在服务不可用的问题,尤其是当只有一个Redis实例运行时,如果该实例宕机,在恢复期间无法服务新的数据存取请求。

主从

为了解决这个问题,Redis提供了主从库模式,通过增加副本冗余量,将一份数据同时保存在多个实例上。这样,即使其中一个实例发生故障并需要一段时间来恢复,其他实例仍可以对外提供服务,不会影响业务使用。主从库模式实现了Redis的高可靠性,即数据尽量少丢失且服务尽量少中断。

在主从库模式中,主从库之间采用了读写分离的方式。读操作可以发送给主库或从库,而写操作只在主库上执行,并将写操作同步给从库。这样做的好处是避免了在不同实例上执行多次写操作导致数据不一致的问题,同时简化了协调多个实例之间的操作。

主从库的同步是通过基于长连接的命令传播实现的。在建立主从库关系后,主库和从库之间会维护一个网络连接,主库会将收到的命令操作同步给从库,从库会执行这些操作,从而保持数据的一致性。

主从库的数据同步分为三个阶段。首先是主从库间建立连接和协商同步,主从库通过psync命令进行连接,主库回复FULLRESYNC命令带上主库的runID和复制进度offset,从库记录这些参数。第二阶段是主库将数据同步给从库,主库通过bgsave命令生成RDB文件,并将文件发送给从库,从库接收到文件后先清空当前数据库,然后加载RDB文件。在此期间,主库仍可以正常处理请求,并使用专门的复制缓冲区记录RDB文件生成后收到的写操作。最后是第三阶段,主库将第二阶段新收到的写命令再发送给从库,从库重新执行这些操作,实现数据同步。

在主从库模式中,为了减轻主库的压力,可以采用主-从-从的级联模式。通过手动选择一个从库作为级联库,其他从库与级联库建立主从关系,这样级联库在 Redis 2.8 版本之后,主从库之间的网络断连后采用了增量复制的方式继续同步。增量复制与全量复制的区别在于,增量复制只传输在断连期间主库执行的写操作命令,而不需要重新传输全部数据。

当网络断连后重新连接时,从库会向主库发送一个PSYNC命令,带有一个偏移量(offset)参数。这个偏移量表示从库在断连前最后一次成功同步的位置。主库收到PSYNC命令后,会根据偏移量确定从哪个位置开始传输增量数据。

主库会将从断连期间的写操作命令存储在复制缓冲区(replication buffer)中,并通过网络连接将这些命令传输给从库。从库接收到命令后,会重新执行这些命令,使得从库的数据与主库保持一致。

需要注意的是,在网络断连期间,从库可能会自行进行写操作。这些自行执行的写操作可能会与主库的操作发生冲突。为了解决这个问题,从库在断连后会首先进行一次部分重同步(partial resynchronization)。这个过程包括两个步骤:

  1. 从库将自己最后一次同步的偏移量发送给主库。
  2. 主库根据从库发送的偏移量,检查两个库之间的命令冲突。如果发现冲突,主库会将冲突的写操作发送给从库执行,确保从库的数据与主库保持一致。

通过增量复制和部分重同步,主从库在网络断连后可以快速恢复数据同步,并保持一致性。这样可以减少全量复制的开销,并提高系统的可用性和性能。

总结

总结起来,Redis的主从库模式通过全量复制和增量复制实现数据的同步。全量复制用于建立主从库之间的初始同步,将主库的所有数据复制给从库。增量复制用于断连后的数据同步,只传输断连期间主库执行的写操作命令。增量复制结合部分重同步能够高效地解决网络断连导致的数据不一致问题,保证系统的可靠性和性能。