redis replication主从复制基本原理

核心原理

当启动一个slave节点的时候,会根据配置文件的slaveof获取master节点的ip,host信息;
如果slave节点是第一次连接master节点,则在master同步数据给salve节点时,做的是全量复制;master节点会启用后台线程,基于当前的内存数据生成一份RDB快照文件,然后传输该文件至slave文件的磁盘中。
如果slave节点是重新连接master节点,则会根据offset信息进行增量复制;master会将缓存中的写命令发送给slave节点,slave节点通过写命令同步master节点新增的数据。

断点续传

从redis2.8开始,支持主从复制的断点续传,如果主从复制过程中,网络连接断掉,在重连之后,可以接着上一次复制的地方,继续复制下去,而不是重新从头开始复制一份。
master节点和slave节点都会记录复制偏移量offset和master id,offset存储在master节点内存创建的backlog中。如果master节点和slave网络连接断掉,可以根据offset信息从指定位置继续复制。
如果没有找到对应的offset信息,则只能进行全量复制。

无磁盘化复制

master节点直接在内存中创建rdb文件,并不会再本地落盘数据,直接发送给slave节点。
可以在redis.conf配置

  1. repl-diskless-sync yes # no: rdb文件存储至磁盘再进行同步,yes:rdb直接生成在内存中,然后同步
  2. repl-diskless-sync-delay # 等待一段时间,即等待与更多的slave节点建立连接后,再进行同步

slave节点的过期key处理

slave节点不会过期key,而是会等待mster的过期key,如果过期或者LRU缓存淘汰的一个key,则master会模拟一条del命令发送给slave节点,slave节点再根据这个命令处理过期key。

工作流程

image.png

全量复制

1、master执行bgsave,在本地生成一份rdb快照文件;
2、master节点将rdb文件发送给slave文件,会有复制时间限制(repl-timeout:60s),超过限制,认定复制失败,可以适当调节参数;
3、对于千兆网卡,一般每秒可以传输100MB,6G的文件,传输时间可能超过60s;
4、master节点在生成rdb文件时,会将所有新的写命令缓存在内存中,在slave节点保存了rdb文件后,再将写命令复制给slave节点;
5、slave节点接收到rdb之后,从磁盘中加载rdb文件到内存中,在加载完毕前仍用旧数据继续对外提供服务,加载完毕后,会清空旧数据;
6、如果slave 节点开启了AOF,会立即执行BGREWRITEAOF,重写AOF文件。

整个过程:
master的rdb文件生成 -> 新数据存入缓存 -> rdb文件网络拷贝 -> 写命令同步slave -> rdb加载至slave内存 -> slave旧数据清理 -> slave aof rewrite

增量复制

1、如果全量复制过程中,master-slave的网络连接断掉,那么slave重新连接master时,会触发增量复制。
2、master直接从自己的backlog中获取部分丢失的数据,发送给slave节点,默认backlog为1MB。
3、master根据slave发送的psync中的offset从backlog中获取待复制的数据。

异步复制

master每次收到写命令之后会现在内部写入数据,然后异步发送写命令给slave节点。

心跳发送

主从节点会互相发送heartbeat信息。
master节点默认每隔10秒发送一次heartbeat,slave节点默认每隔1秒发送一个heartbeat。

相关机制名词解释

master和slave节点都会维护一个offset

master会自身不断累加offset,slave也会自身不断累加offset。
slave会每秒上报自己的offset给master,同时,master会保存么给slave的offset。
根据offset可以判断master节点和slave节点是否存在数据不一致的情况。

backlog

master 节点有一个backlog,默认是1MB大小。
master 节点在给slave节点做复制数据时,也会将数据在backlog中同步写一份。
backlog主要用来做全量复制中断后的增量复制。

master run id

可以通过命令info servcer查看master run id的值。
如果根据host+ip定位master节点,这种方式无法保证当master节点重启后的数据变更。
所以,需要根据master节点的run id进行区分,run id不同就做全量复制,run id相同,则做增量复制。
run id会在redis重启之后进行更新,如果需要在不更改run id的前提下重启redis,可以使用 redis-cli debug reload命令。

psync

从节点使用psync从master 节点进行复制,例如psync runid offset
master节点会根据自身的情况返回相应信息,可能是FULLRESYNC runid offset触发了全量复制,CONTINUE触发增量复制。

redis 主从复制的核心机制

1、redis采用异步复制的方式复制master节点的数据至slave节点。在redis2.8版本开始,slave会周期性地确认自己每次复制的数据量;
2、一个master节点可以配置多个slave节点。
3、slave节点可以连接其他的slave节点。
4、slave节点做复制时,不会阻塞master节点的正常工作。
5、slave节点做复制时,不会阻塞自己的读操作,slave节点会用原有的旧的数据集提供服务。在复制完成的时候,需要删除旧的数据集,加载新的数据集,在这个过程会暂停查询服务。
6、slave节点可以横向扩容,做读写分离,扩容slave节点可以提高读的吞吐量。

Master节点持久化对主从架构的安全保证意义

未开持久化的影响

如果master节点并未开启持久化操作,那么在master节点宕机重启后,master节点的数据就会全部丢失。
此时,如果slave节点同步重启后的master节点的数据集,也会造成数据的全部丢失。

如何保障主从架构下数据的不丢失

1、master节点开启持久化的操作,保证在master节点重启后,能够根据aof文件或rdb文件快速恢复数据。
2、同时,需要设计各种企业级备份方案,即定时备份本地的持久化文件至其他云服务器,保证在本地文件失效后,能够从云端获取指定时间段的数据,确保在master节点重启后,会有数据。
3、保证集群节点的高可用性,开启哨兵机制,保证在master节点宕机后,可以通过哨兵机制检测到master节点失效,重新从其他的slave节点选举一个节点作为新的master节点。