06.主从库数据一致

我们学习了AOF和RDB,如果Redis出现了宕机的情况,可以分别通过回访日志和重新读入RDB文件进行恢复数据,保证少的丢失数据,提高可靠性

不过,在实际使用过程中,如果Redis出现了宕机,在恢复过程中,是无法提供服务的

那么为了避免中断问题,提高服务的冗余量,可以将一个数据同时保存在多个实例中,如果有一个实例出现了故障,需要过一段时间才能恢复,但其他的实例并不会被影响

Redis对于上述的多实例保存的实现,就利用了主从库模式,来保证数据副本的高可用

读操作,是主库和从库都可以接受的

写操作,只有主库执行

图片

为了避免数据的不一致,所以仅支持主库接受写请求

而我们主要调查和学习的方向,是关于主从库同步过程

首先,我们需要看一下主从库的第一次同步是如何进行的

我们在启动多个Redis的时候,可以使用replicaof来形成主从库的关系,比如有两个实例 A:172.16.19.3  B:172:16.19.5,执行如下的命令

replicaof 172.16.19.3  6379

这样B就成为A的从库了,接下来B和A要进行第一次的同步

图片

首先是从库发送建立连接的请求,建立了长连接,从而方便发送同步命令

首先从库给主库发送psync命令,表明要进行数据同步,pysnc包含了主库的runID和复制进度offset两个参数

runID,每个Reids实例启动的时候自动生成一个随机ID,用来随机表示这个实例,第一次复制的时候,runID为?

offset,这时候设置为-1 表示第一次复制

然后主库发送一个ACK,一个FULLRESYNC相应,表示第一次复制采用的全量复制,FULLRESYNC带上了主库的runID和主库当前的复制进度offset,返回给从库,从库收到响应后,记录下这两个参数,方便下次同步直接拉去

然后主库生成一个RDB文件,执行bgsave命令来进行生成,然后发给从库在收到RDB文件后,后清空当前的数据库,然后重新加载RDB文件,这是为了避免之前数据的影响,从库需要先将数据库清空

最后为了避免主从在传递RDB文件的时候,主库新收到的数据无法同步给从库,主库内存中记录了专门的replication buffer,在发送完成RDB之后,将replication buffer中的操作也发给从库

然后在主从复制的过程中,如果全部的从库都连接到主库上的话,主库为了维护和从库的网络连接,以及传输RDB,会造成不小的负担,所以Redis还支持了主从从的模式

就是将一个从库作为二级主库,负责级联其他的从库,也是使用 replicaof 所选从库IP 6379

这样就可以减少主库的压力

图片

在主从库之间,利用一个长连接来及数据的操作和同步

不过如果网络出现了问题和断链,那么就需要考虑重新连接后的数据同步问题

如果是简单的解决方案,可以考虑在出现了网络问题之后,主从库之间就重新进行一次全量复制,开销不小

而在Redis中,则是利用了一个repl_backlog_buffer的缓冲区,来保证主从库之间的数据同步

在这个缓冲区中,是一个环形缓冲区,主库在其中记录自己小大的位置,从库记录自己读到的位置

一开始的时候,主从的位置在一起,是其起始位置,随着主库不断接收新的写操作,写操作会增加偏移量,而从库则不断的往主库的偏移量上靠拢,所以一般情况下两者偏移量基本相等

图片

主从库的连接恢复后,从库会给主库发psync命令,将自己当前的slave_repl_offset发给主库,

然后主库判断自己的master_repl_offset和slave_repl_offset之间的差距

然后根据差距来走不同的流程

如果在repl_backlog_buffer的范围区间之内,那么主库直接同步给从库就可以了

但由于repl_backlog_buffer是一个环形数组,类似redo log buffer,在缓冲区写满的时候,主库继续写入,会覆盖掉之前的写入操作,这种时候,如果slave_repl_offset的小于最小的缓冲,那么就只能考虑RDB全量复制了

图片

为了避免过多的RDB复制,可以考虑调整repl_backlog_size,这个参数和所需的缓冲空间有关,缓冲空间的计算方式为  主库写入速度 * 操作大小 – 主从间的网络传输速度 * 操作大小

一般最后再乘以2,获得repl_backlog_size的最终值

一般,每秒写入2000个操作,每个操作大小为2KB,这样就需要2MB的缓冲空间, 然后乘以2,最终设置为4MB

那么总结一下本节学习,主要是关于Redis的主从库的同步原理,有三种模式,全量复制,基于长连接的命令传播,以及增量复制

全量复制是供第一次同步使用的,对于此,建议一个Redis实例的数据库不要太大,在几GB级别比较合适,减少RDB文件生成,传输和重新加载的开销,为了避免多个从库同时和主库进行全量复制,还可以采用 主-从-从的模式,减少主库的压力

最后就是增量复制过程中,repl_backlog_size这个配置参数,如果配置的小,那么就可能导致从库的复制进度赶不上主库,导致从库进行全量备份,可以考虑对应增大参数

最后一个问题,RDB和AOF记录相比,AOF的操作命令更全,为何不考虑使用AOF呢?

在说到repl_backlog_size的时候,就联想到了redo_log_buffer,

对于AOF为何没有采用,AOF文件就因为保存的完整,所以体积更大,不适合传输,而且读取更加缓慢,不如二进制的RDB文件

发表评论

邮箱地址不会被公开。 必填项已用*标注