Redis的主从同步的理解 – 记忆角落

Redis的主从同步的理解

/ 0评 / 0

Redis的主从同步的理解

首先,什么是主从?

主从也称主从集群,部署了多个Redis实例,如下图所示:

image-20220118091836707

其中

Q&A:为什么从库不能写?

考虑到数据合并的复杂性,假如一个key,多次更新,每次操作在不同的实例上执行,为了保证数据的全局一致性,势必要加全局锁,保证在集群范围上串行化操作且在最新的数据基础上更新,这个成本还是很大的。

为了降低系统复杂度,节约成本。主从同步架构方案一般都是在主库上写,在从库上读。分工明确,职责单一。

有人会问那Redis Cluster 模式呢,Redis Cluster模式是另一种设计方案。采用水平分割方式,通过CRC16(key)算法,将数据拆分到若干个实例中,每个实例只对自己负责的槽位的数据读、写,从而分摊集群压力。

为了保证数据不丢失,Redis提供两种数据同步方式

Q&A:什么时候采用 RDB ? 什么时候采用 AOF ?

建立主从关系

首先,启动两个redis 实例,IP地址分别是 192.168.10.1192.168.10.2 ,开始时,他们之间没有任何关联。

我们通过终端命令,登录 192.168.10.2 机器,执行命令

replicaof 192.168.10.1 6379

此时 192.168.10.2 实例就成了 192.168.10.1 的从库。

image-20220118093630780

当主从实例建立好关联后,接下来,就开始进入数据同步环节

主从同步

image-20220118094455831

主从库数据同步分为三步:

第一步:

从库(192.1768.10.2)向主库(192.168.10.1)发送 psync 命令,带了两个参数(主库的runID和同步进度offset)

第二步:

主库在生成RDB文件时,主线程是阻塞的,对外不提供服务。一旦RDB文件生成,在数据同步过程中,不受影响,主库可以对外服务。后续的写命令数据会存到 replication buffer

第三步:

主库将增量写命令发送给从库,从库放映式执行这些命令,从而实现了主从同步。

但生产环境,通常是一主多从,每个从库初始同步时,都要主库生成RDB文件,显然开销很大。

Q&A:有什么解决方案可以减轻一主多从,库生成RDB文件开销很大的问题?

当从节点存在多个时,主库的压力显著增加,具体体现在两个方面:

1.当从库同步主库时,要fork子进程,有多少个从节点,就要fork多少个子进程,每个子进程都要生成RDB。导致主库系统压力过大

2.生成的RDB要同步给从库,占用网络带宽

基于上面的困境,演化出新的模式,主-从-从模式,具体玩法如下图:

image-20220118100849199

现有虽然有6个从库,但直接跟主库关联同步数据的只有两个实例,大大减轻了主库的压力。但是如果网络突然断了或者有问题怎么办呢?

Q&A:网络闪断对主从同步的影响有什么?

主从实例间同步数据主要有两种方式:全量同步增量同步

全量同步就是同步RDB文件

增量同步是要引入一个缓冲区,repl_backlog_buffer,它是一个环形设计,增量命令都是先存入这个缓冲区的。主库有生产位移,称之为master_repl_offset 。从库有拉取位移,称之为slave_repl_offset

image-20220118102849010

正常情况下,master_repl_offsetslave_repl_offset 大小是接近的,也就是说主从库两者间的数据近乎同步。

每次同步数据时,从库向主库发送 psync 命令,把自己的 slave_repl_offset 发给主库,主库基于此偏移位置,向从库发送增量数据。

由于采用了环形结构,如果主库的生产速度比从库的拉取速度快很多时,就会出现套圈现象。

为什么采用环形?主要为了让空间循环使用,像市场的行车记录仪、监控设备等,大多都是采用循环覆盖式存储。如果空间满了,将之前最老的数据覆盖掉。虽然可能丢失了部分数据,但是性价比高。

回到上面的问题,如果被套圈了怎么办?

image-20220118103251164

如上图所示,从库 psync 命令,请求的offset 是 4,但是主节点已经生产到了 15 ,将之前的 1、2、3、4、5 全部覆盖掉了。

有两个解决方案:

1.调大 repl_backlog_buffer 缓冲区大小,该值是由 repl_backlog_size参数控制

缓冲空间大小 = 主库写入速度 * 操作大小 - 从库拉取速度 * 操作大小

2.还有一种方式是Redis 自身提供的解决方案。

此时会触发全量复制,跟第一次建立主从关系同步数据一样。通过全量方式,一次性弥补主从间的数据大缺口。

Q&A:主节点挂了怎么办

如果只是传统意义上的主从模式,主节点挂了,通常要手工完成切换。

效率不言而喻了,尤其是线上生产系统,根本没法接受这种方案。

这时候,要引入哨兵机制了,哨兵机制可以实现主从库的自动切换,有效解决了故障转移。整个过程分为三个阶段:监控、选主、通知。

1.监控。

哨兵进程会周期给所有的主库、从库发送 PING 命令,检测机器是否处于服务状态。如果没有在设置时间内收到回复,则判定为下线。

当然,网络抖动,也会存在误判可能,如何避免?

引入哨兵集群,多个哨兵实例一起判断,降低误判率。判断标准就是,假如 n 个哨兵实例,至少有 n/2+1 个判定一致,才可以定论。

2.选主

主要是看各个节点的打分情况,打分规则分为 从库优先级从库复制进度从库ID号。只要有一轮,某个从库得分最高,则选举它为主库。

3.通知

把选举后的新主库发送给所有节点,让所有的从库执行 replicaof 命令,和master建立主从关系、数据同步复制。

发表评论

您的电子邮箱地址不会被公开。