Redis主从复制原理

x33g5p2x  于2021-11-09 转载在 Redis  
字(2.3k)|赞(0)|评价(0)|浏览(267)

单机Redis面临的问题

单机Redis在发生故障时,由于无法做到故障转移,所以接下来的请求将会直接打到数据库。

大量的查询使得数据库连接数达到峰值,且内部锁冲突严重,造成慢查询、连接超时等后果。

所以这个时候,我们想着能不能将Redis数据以多副本的形式保存在多台Redis上,当发生故障时,快速地手动去切换连接的Redis?

当然,Redis本身也提供了这个功能。

主从模式能将Master节点的数据冗余到多台Slave上,配合哨兵模式能够快速感知Master宕机从而进行主从切换实现故障转移。

主从模式拓扑图

主从模式又可被细分为一主一从、一主多从以及主从从的结构。

不管什么结构,各个从节点都会复制主节点的数据,以此来实现数据备份。

一主一从

最精简的主从模式,老板最喜欢的模式。

当主节点出现故障时,从节点转变角色继续服务。

一主多从

一主多从的结构,非常适用于读多写少的场景。

配合读写分离与负载均衡,即主节点只负责写请求,所有的查询请求被均分到各个从节点上,将大大提升Redis的吞吐量。

主从从

一种使用级联的方式,Slave3并不是作为Master的直接从节点,而是间接从节点。

这样Slave3不需要请求Master去复制数据,只需要请求Slave1,有效降低Master节点的工作负载。

如何指定多个节点间的主从关系?

很简单,有以下方式:

  • 在redis.conf配置文件中,使用slaveof <masterip> <masterport>来永久指定主从关系
  • 在客户端中执行slaveof <masterip> <masterport>来临时指定主从关系
  • 在redis-server启动命令中加入slaveof <masterip> <masterport>来临时指定主从关系

如何断开主从关系?

执行slaveof no one即可,断开复制并不会清除已有的数据,只是不再进行复制。

主从复制原理

既然主从模式可以将数据冗余到其他节点上,那究竟是怎么保证主从数据的一致性呢?

当Slave初次连接上Master时,会进行全量复制。

全量复制

1、Slave初次连接上Master时,会发送PSYNC命令,后面会跟上两个参数,分别是{runID}与{offset}。

runID

每个Redis实例在启动时,会生成一个唯一ID,记为runID。

offset

从节点的复制偏移量

这是Slave与Master的初次沟通,Slave自然不知道Master的唯一ID,因此这里runID的值为?初次复制的偏移量可以记为-1。

2、之后Master就知道Slave为初次复制,那么本次会执行全量复制。Master向Slave回复FULLRESYNC <runID> <offset>,其中<runID>就是Master的实例ID,<offset>为复制偏移量。

3、Slave在收到响应后,会将runID与offset保存在本地。

4、Master通过bgsave的方式,fork出一个子进程,由子进程完成RDB快照的生成。基于写时复制,主线程依然可以执行新的命令,但这些命令并不会被子进程实时扫描到。关于Redis的持久化方式,可以参考我的另外一篇文章谈谈Redis的持久化——AOF日志与RDB快照

5、Master向Slave发送RDB数据。

6、Slave清空本地数据,加载RDB数据。

7、Master在生成RDB文件后,将之后新接收到的命令,存入复制积压缓冲区中。

复制积压缓冲区

Master内部维护了一个固定大小的FIFO队列,默认为1MB。

队列中的命令里的每一个字节都会有一个偏移量与之对应,当写满1MB后,头部的字节将会出队。

8、Master不断地将复制积压缓冲区内的命令发送给Slave

9、Slave在本地回放这些命令,当Slave的复制偏移量和缓冲区内的最大偏移量相同时,此时就代表Master和Slave是一致的。

增量复制

假如Slave由于网络闪断和Master连接失败,过了一会儿网络恢复正常,Slave重新与Master建立连接。

如果此时仍然要进行全量同步的话,效率低下。

因为网络闪断期间,Slave只是丢失了少量数据,不至于进行全量同步,进行增量同步即可。

1、Slave断线重连后,将Master的实例ID和断线前的复制偏移量发送给Master。

2、Master在收到复制请求后,会检验runID与offset。

对于runID,如果不等于当前Master的实例id,则代表发生过主节点宕机,某个从节点切换为主节点。此时Master会回复FULLRESYNC,代表接下来会执行全量同步。

如果等于当前Master的实例id,则继续检查offset。如果offset还在缓冲区内,则Master回复CONTINUE,代表接下来进行增量同步。

如果Slave断线太久,则offset代表的字节早已经出队,此时会进行全量同步。

3、Master依据指定的偏移量,从偏移量代表的字节开始,将命令发送给Slave。

4、Slave在本地回放这些命令。

总结

本文讲述了主从模式下的3种结构,以及每种结构的适用场景。

接着是主从之间的复制原理,分为全量复制和增量复制。

Master区分是全量复制还是增量复制,靠的是runID与offset参数。

第一次复制,则进行全量复制,Master生成RDB文件,并将之后生成的命令存入复制积压缓冲区。

Slave断线重连后,Master依据offset在复制积压缓冲区中选择传输的起始字节。找不到的话,则进行全量复制。

相关文章

微信公众号

最新文章

更多