在单点故障后,我们需要保证服务不间断,所以需要使用冗余的副本提供集群服务,从而达到服务的高可用。redis 提供了主从库数据同步机制,从而保证数据副本的一致性,而主从库使用的是读写分离的机制。
通过该模式构建多个数据副本,使用读写分离的方式
为什么要读写分离呢?
如果从库也可以进行写操作,那么主从库在同一个 key 中存储的值可能会不一致,如果要保证一致性,需要通过加锁来解决,但这样会造成性能的损耗。
但如果只有主库写入,在同步给从库,则能保证所有实例中数据的一致性。
第一阶段
从库向主库发送psync命令进行数据同步,该命令包含主库的runID和复制进度offset
主库会回复 runID 和 offset 给从库
第二阶段
主从第一次同步是采用全量复制的方式,主库生成 RDB 文件,然后发送给从库,从库清空当前数据再读入 RDB 文件完成第一次同步。
在生成 RDB 文件时,还是会有新的操作的会进行,为了保持数据的一致性,会将新的操作记录到 replication buffer 中。
第三阶段
RDB 文件发送到从库后,再 replication buffer
中的操作再发送给从库。
主从同步有哪些压力?
主-从-从模式
可以手动选择一个从库(比如选择内存资源配置较高的从库),用于级联其他的从库。由从库生成 RDB 再传输给从库,减少了主库的压力。
在主库全量复制之后,会维护一个长连接,后需的操作命令通过该连接同步给从库
全量复制是通过生成 RDB 发送到从库然后进行读取后进行同步。我们知道生成 RDB 本身就是一个消耗 CPU 的操作,并且存在阻塞主线程的风险,所以我们需要尽量少的执行全量复制的操作。
所以在第一次使用 RDB 全量复制后,主从库会建立一个长连接,主库收到的新命令会再同步到从库,这样就避免频繁全量复制。
但是有一个风险点是,如果过程发生了网络中断或者阻塞,该如何解决?
当主从连接时,会将新的操作的命令写入 replication buffer
和 repl_backlog_buffer
缓冲区中
repl_backlog_buffer
是一个环形缓冲区,主库会记录当前的偏移量 master_repl_offset
,记录自己写到的位置,而从库在上面也有对应的偏移量 slave_repl_offset
,记录自己正在读到的偏移量。
在恢复连接时,从库会通过 psync
命令将自己的偏移量 slave_repl_offset
发送给主库,主库会将 slave_repl_offset
和 master_repl_offset
之间的命令同步给从库即可。
举了例子: 主库和从库之间相差了 put d e 和 put d f 两个操作,在增量复制时,主库只需要把它们同步给从库,就行了。
因为 replication buffer
是一个环形的缓存,当主从库长期断开时,是有可能被覆盖掉旧的数据,这个时候是会重新发起全量复制,主库根据从库发送的 slave_repl_offset
来判断是增量还是全量的复制。
那为什么全量复制使用 RDB 而不是使用 AOF 呢?
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有