写点什么

Redis - 复制

发布于: 2021 年 06 月 05 日
Redis - 复制

复制,是 Redis 内部的一个机制,即把数据复制成多个副本分别部署在不同的机器,解决单点问题,提高可用性。

复制机制

建立复制

采用主从结果,由从节点执行命令:slaveof host port 发起建立流程。默认情况下,从节点是只读的,不能写,也强烈建议不要变更该配置,避免主从数据不一致。

断开复制

同样由从节点发起,执行命令:slaveof no one

断开复制,从节点晋升为主节点,此时从节点的数据不会保持不变,不会清空,只是不能再从之前的主节点同步到数据了

也可以执行命令:slaveof otherhost otherport

切换为另一个主节点,重新发起复制建立流程。

复制过程

1、从节点执行 slaveof host port 命令后记录下主节点地址信息,随后异步开始复制建立流程

2、从节点向主节点建立 tcp 连接

3、从节点向主节点发送 ping,检查主节点运行状态

4、密码校验(目的是为了数据安全,不能随便建立复制)

5、同步数据集

6、命令持续同步

一开始复制时,主节点大概率已经有了很多数据,此时需要将这些数据先尽快同步到从节点,后续主节点新增处理的写命令在持续的同步到从节点,即存量和增量数据的复制,第 5、6 两步就是解决这两种场景。

同步数据集

命令格式:psync replicationid offset

其中 replicationid 即为 runid,offset 为当前从节点已复制的偏移量 psync 命令由从节点发起,向指定的主节点同步指定偏移量后续的数据。

psnc 命令运行需要下述组件支持:

1、主从节各自复制偏移量

所谓的偏移量即写命令字节长度的累加和,用以记录当前复制到哪里了。

1)参与复制的主、从节点都会维护自身的复制偏移量。

2)主节点复制偏移量:写入命令的字节长度累加和

3)从节点复制偏移量:主节点写入命令同步给从节点,从节点也进行字节长度累加和。

2、主节点复制积压缓冲区

当主节点有连接的从节点被创建时,主节点不但会把写入命令发送给从节点,还会写入复制积压缓冲区,便于后续同步到从节点失败时进行重发送。

该缓冲区采取先进先出策略,可保存一定量最新的写入命令,默认 1MB。

3、主节点运行 ID

每个 Redis 启动后都会动态分配一个 40 位的十六进制字符串作为运行 ID,用以标识 Redis 节点,即 fsync 命令中的 replicationid。

sync 命令用于建立复制后的第一次数据集同步,由从节点发起,将数据从主节点同步到从节点。

第一次同步时有两种情况:

1、全量同步

此时主从节点之间从来没有建立过复制,没有同步过数据,所以需要将主节点的所有数据同步到从节点。全量同步的过程:

1)从节点向主节点发送命令:psync ? -1

此时从节点还没有主节点 id 信息(通过 slaveof,只知道 ip 和端口),也还没有同步过,所以 offset=-1。

2)主节点回复

主节点根据命令形式知道这是首次同步,返回主节点 id 以及 offset,并告知从节点即将开始全量同步。

3)从节点保存主节点 id 以及 offset

4)主节点开始 RDB 持久化(fork,快照)

5)主节点发送 RDB 文件给从节点,从节点清空数据并加载 RDB 文件

若从节点开启了 AOF 持久化,加载完后会立即进行一次重写,保证 AOF 文件立刻可用。

6)上述步骤过程中,主节点仍然在接受写命令,主节点将该部分命令保存在复制客户端缓冲区(该缓冲区仅在全量复制场景起作用)中,从节点加载完 RDB 文件后,主节点再将该部分命令发送给从节点。


2、部分同步

比如主从之前已经建立过复制,已经同步了数据,但中间出现网络闪断,复制链接断开,需要再次建立复制链接。但此时从从节点已经复制过了数据。在 2.8 版本之前,这种场景下仍然需要做全量复制,成本较高,所以之后的版本进行了优化,从节点只需要再同步在网络中断期间主节点新增的这部分数据即可,不需要做全量复制。

此时发送命令:psync replicationid offset 即可。replicationid 和 offset 是实际的主节点 id 和偏移量,

而不是全量复制时的?和-1。

命令持续同步

同步数据集完成,则意味着存量数据复制完成,后面即开始增量数据复制。

主节点执行写入命令后即返回,异步的将命令同步给从节点(所以数据可靠性并没有特别高)。

如果从节点同步异常,命令丢失,会再发起部分同步,补齐丢失的命令。

相关使用问题

避免通过主从达到读写分离

主从复制时存在如下问题,不太建议通过主从复制做读写分离。

1、主从同步有延时

2、要业务程序处理从节点失效的问题

读写分离主要为了减轻单节点的性能压力,完全可以使用 cluster 达到更好的效果。

规避全量复制

全量复制需要主节点 RDB 持久化、传输 RDB 文件、从节点清除数据并加载 RDB 以及可能的 AOF 重写,都是耗资源的操作,所以最好避免。

有如下场景会产生全量复制,需注意:

1、首次同步

2、主节点重启后,主节点 id 变化,从节点拿之前的 id 向主节点同步,主节点会发起全量同步

3、部分同步时,从节点所需的 offset 已经不再复制积压缓冲区,不足不了丢失的命令,此时会触发全量同步。

用户头像

还未添加个人签名 2020.04.30 加入

还未添加个人简介

评论

发布
暂无评论
Redis - 复制