Redis 主从复制
主从复制的主要作用
- 数据冗余:主从复制实现了数据的热备份, 是持久化之外的另一种数据冗余方式
- 故障恢复:当主节点出现故障时,从节点能够继续提供服务(这其实是服务冗余的思路)
- 负载均衡:主从节点配合读写分离,由主节点提供写服务,从节点提供读服务,分担服务器负载。在写少读多的情况下,能够大大提高服务的负载
- 高可用基石:为集群和哨兵模式提供基础
主从常见的拓扑结构
根据拓扑的复杂性,一共有三种结构:一主一从、一主多从、树状主从。一主一从和一主多从比较简单,就不再赘述。树状主从,相比与前两者,提供了将某个从节点作为复制层的能力,从而降低了主节点同步数据的压力。主节点可以先将某个数据同步给充当复制层的从节点,再由该从节点将数据继续同步给其余从节点。
主从复制的流程
- 保存主节点的信息,如 ip 和 port
- 建立连接
- 发送 ping 命令,确保连接可用
- 权限验证:如果主节点需要密码,则从节点使用正确的密码通过验证
- 同步数据:主节点将全部数据同步给从节点
- 命令持续复制:主节点持续地将写命令同步给从节点
主从数据同步方式
同步方式分为:全量复制和部分复制
全量复制
undefined/notes/_Attachments/%E5%85%A8%E9%87%8F%E5%A4%8D%E5%88%B6.excalidraw- 从节点发送
psync命令进行数据同步。由于是第一次复制,从节点没有复制偏移量和主节点运行 ID,所以发送psync ? -1命令 - 主节点由
psync ? -1解析出当前为全量复制,回复+FULLRESYNC响应 - 从节点接收主节点响应,并保存主节点运行 ID 和偏移量 offset
- 主节点执行
bgsave保存 RDB 到本地 - 主节点发送 RDB 文件给从节点,从节点将 RDB 文件保存在本地并直接作为数据文件
- 在从节点接收 RDB 数据期间,主节点持续响应写命令,因此主节点会把这期间的写命令保存在复制客户端缓冲区内。当从节点加载完 RDB 文件后,主节点再将缓冲区内的写命令发送给从节点,从而保证主从之间的数据一致性
- 从节点接收完主节点的全部数据后,会清空自身的旧数据
- 从节点加载 RDB 文件(加载完之后主节点会发送缓冲区内的写命令)
- 如果开启了 AOF 持久化,则从节点在加载完 RDB 之后,会立刻做
bgrewriteaof操作,保证全量复制之后 AOF 持久化文件立即可用
部分复制
当从节点正在复制主节点时,如果出现网络问题或命令丢失等异常情况,从节点会向主节点要求补发丢失的命令数据。如果主节点的复制积压缓冲区内存在这部分数据,则直接发给从节点,这样就可以保证主从节点复制的一致性。
undefined/notes/_Attachments/%E9%83%A8%E5%88%86%E5%A4%8D%E5%88%B6.excalidraw- 当主从节点出现网络中断时,如果超过 repl-timeout 时间,主节点会认为从节点故障并中断复制连接
- 主从连接中断期间,主节点会将命令保存在复制积压缓冲区内,默认最大缓存为 1MB
- 当主从节点网络恢复后,由于从节点已经保存了自身已经复制的偏移量和主节点的运行 ID,因此它将偏移量和 ID 通过 psync 命令发送给主节点,要求进行部分复制
- 主节点接收到 psync 命令后,首先核对参数 runId 是否与自身一致,再根据偏移量在自身的复制积压缓冲区内查找。如果偏移量之后的数据存在缓冲区中,则对从节点发送 +CONTINUE 响应,表示可以进行部分复制。
- 主节点根据偏移量将复制积压缓冲区内的数据发送给从节点,保证主从复制进入正常状态
主从复制存在的问题
- 如果主节点故障,则需要手动将某个从节点升级为主节点。此时还需要修改应用的主节点地址以及命令其它从节点复制新的主节点
- 主节点的写能力受到单机的限制
- 主节点的存储能力受到单机的限制