1、保证redis主从实例,数据一致的机制
- 当客户端对master执行写操作,过期key操作或因为达到最大内存删除key等改变数据集的操作时,只要副本与master连接,master就向副本发送相应的数据修改命令。
- 当副本与master断开连接后,比如因为网络故障或重启等原因。当副本与master恢复连接后,会尝试与master进行一次部分同步数据,以同步断开连接期间丢失的数据。如果无法达到增量同步的条件,会进行一次全量同步。
2、全量同步的过程
当副本集向master发出全量同步数据请求的时候,master开启一个后台线程进行一次RDB快照的生成,同时在内存中开始记录此刻以后客户端执行的修改数据集的命令。当RDB文件生成之后,就发送给副本,副本把RDB文件保存在本地磁盘,然后再加载到内存中。然后master把buffer中记录的命令发送给副本。如果master接收到多个并发的全量同步请求,它会只进行一次RDB快照的生成。redis 2.8.18版本以后,支持不需要磁盘做中间存储RDB的全量复制,master可以直接把RDB写到副本的内存中,在副本的redis.conf中配置repl-diskless-sync 即可。
3、redis主从机制的关键点
- redis主从之间同步数据命令是异步的,当master向副本发送一条数据命令时,副本并不是立即确认执行结果,而是定期的返回确认结果。所以即使副本可能还没有执行命令,master也会认为已经成功,直接返回成功的结果。
- 一个master可以有多个副本集。
- 副本本身也可以被另外的副本连接,构成级联的结构,但是二级副本或更下级的副本只会同步master的数据改动。
- 对于master,当master有一个或多个副本进行全量或增量同步数据时,master不会阻塞,可以继续处理读或写请求。
-
对于副本,当副本从master同步全量数据时,默认也可以处理查询请求,使用老的数据集。可以修改默认配置,使副本在全量同步时拒绝处理请求。但是当全量同步完成时,副本即会新启一个线程删除旧的数据集,然后在主线程中加载新的数据集,在加载新的数据集的过程中,副本肯定会拒绝请求的,如果数据集比较大,加载过程可能会持续几分钟。
-
副本集既可以用于读写分离,还可以提高数据的安全性,以及redis的可用性。
4、如何唯一定义一个master的数据集的版本
每个master的数据集都有一个Replication ID和offset
Replication ID, offset
其中Replication ID是一个随机数,表示一个数据集的时代。当副本升级为master时,会生成一个新的Replication ID。
offset表示这个数据集执行了多少条数据更改,每次master执行一次数据更改,offset就会加1,即使没有副本连接,这个offset也会一直增加的。
5、到底Replication ID是什么?
当一个实例第一次作为master启动时或者副本升级为master时,都会生成一个新的Replication ID。
当副本升级为master时,这样的master实例会有两个Replication ID,main ID和secondary ID。此时,副本会把原来的Replication ID也就是之前的master的Replication ID设置为secondary ID,然后重新生成一个Replication ID作为main ID,offset就只有一个就是此时的offset。当副本升级master完成时,此时其他副本连接这个新的master时同步数据时,使用的Replication ID就是上一个master的Replication ID,就能和新的master的secondary ID匹配。这样就只需要进行一次部分同步就行了,如果没有secondary ID那么这种情况下,副本都要进行一次全量同步。至于为什么副本升级为master时,要新生成一个Replication ID,是因为之前的master可能还在提供服务,如果副本不生成一个新的Replication ID,那就会可能出现相同的Replication ID和offset,但是对应老的master和新的master两个不同的数据集的情况。
6、什么情况下进行全量同步,什么情况下进行部分同步。
当一个副本连接到master时,会发送 PSYNC 命令进行部分同步,副本会把它持有的Replication ID和offset发送给master,与master的Replication ID和offset做比较,这样就能获取缺失的增量数据。但是如果master的buffer中没有记录这么多的增量数据或者副本所持有的Replication ID在当前的master中匹配不到,那么副本就会进行一次全量同步。
当一个副本因为需要重启时,重启后如果想要只进行部分同步,那RDB持久化机制就必须开启,因为Replication ID和offset会存在RDB文件中,AOF中没有这些信息。关闭副本时最好使用 SHUTDOWN ,这样会先执行一次快照,然后再停机。
7、设置至少有N个副本连接master时,master才接受写请求
如何确定副本和master连接正常
- 副本每秒钟和master ping一次,向master确认已经处理了同步的数据命令
- master会记录每个副本最后一个ping的时间
- 可以用min-replicas-max-lag配置master 连接的副本距离最后一次ping最多过了几秒如果没有再次ping就算副本失联,还可以用min-replicas-to-write 配置最少有几个副本连接正常才可以接受写请求。
因为副本确认master同步的数据命令是异步的,所以master确认与其它的副本失联最少是有一秒的时间间隔的,这就意味着例如当master出现网络故障并且副本升级为新的master后,客户端可能会继续向master写入数据,那么当旧的master网络恢复,就会成为为新的master的副本时,然后同步新的master的数据,那么故障期间客户端向旧的master写入的一部分数据就会被覆盖。
8、配置一个实例为master的副本
在副本实例上执行
replicaof 192.168.1.1 6379
9、查看主从系统中master和副本的信息