谈一谈Redis的复制
- 为什么Redis需要复制?
- 建立冗余数据,数据备份
- 当节点出现问题时,能够实现故障恢复
- 当访问量很大的时候,可以依据数据复制来实现请求分流
- Redis的复制功能同时也是Redis可用性的基础
- CAP理论
前面提到Redis的复制是可用性的基础
- 首先,我们需要明白Redis的复制发生在分布式的环境中;而分布式系统的基石则是CAP理论
CAP理论阐述了数据一致性、可用性、分区容忍性的取舍;换而言之,对于系统而言,CAP在现实的环境中最多只能符合两个;也就是说在 分区发生时,系统需要在数据一致性、可用性之间做出取舍;
- 当网络分区发生后,对于任何节点都只能与同一个分区的节点进行通信;而不能与其余分区的节点通信;
- 如果需要保证数据的一致性,则需要停止所有服务在进行数据同步;反之,当不停止服务时,各节点的数据总是存在误差
谈谈数据一致性
- 数据的一致性可以分为强一致性、弱一致性;强一致性是指当任何时候取到的数据都是最新的;弱一致性则是指后续的操作不能马上读取最新的数据,但是经过一段时间后,各节点的数据都是一致的
- Redis集群默认采取的异步通知的方式,也就是说,Redis集群默认认为性能比数据一致性更重要;采取最终一致性策略
谈谈Redis同步的流程
- Redis的同步流程
Redis的同步、命令传播
- Redis的复制由两部分操作构成,分别是同步、命令传播
- 同步是指复制主服务器的当前状态
- 命令传播是指主服务器被修改,使从服务器保证与主服务器一致的手段
- 老版本的Redis同步的实现
- 1.从服务器向主服务器发送SYNC指令
- 2.主服务器执行BGSAVE指令,后台生成RDB文件;同时,使用缓冲区记录所有开始执行的指令
- 3.主服务器将RDB文件推送给从服务器,同时从服务载入RDB文件,将自身恢复为主服务器执行BGSAVE时的状态
- 4.主服务器将记录在缓冲区的所有写命令发送给从服务器;从服务器执行命令,更改自身状态
老版本的Redis同步策略看似没有问题,仔细思考一下,如果同步时,服务器宕机了。还没有同步完的数据该怎么办?
第一种解法:在执行一次SYNC指令
- 理论上在执行一次SYNC可以达到目的,但是一般不这么干,为啥子?
- 因为SYNC指令代价太大
- SYNC指令步骤
- 1.主服务器新建子线程来生成RDB文件(消耗CPU、内存、IO资源)
- 2.将RDB文件传输给从服务器(消耗网络资源)
- 3.从服务器载入新的RDB文件,会暂停主线程(影响吞吐量)
- 第二种解法:Redis2.8推出了PSYNC指令代替SYNC指令
Redis新版本的同步实现
- PSYNC指令具有两种同步模式,完整重同步、部分重同步
- 完整重同步用于解决初次同步的情况
- 部分重同步用于解决断线后重新同步的情况
- PSYNC指令解决了旧版本断线后重新复制时效率较低的情况
部分重同步的实现
- 部分重同步引入了三个概念,复制偏移量、复制积压缓冲区、服务器运行ID
- 复制偏移量:主从服务器分别维护了一个复制偏移量;当且仅当偏移量一致时,认为主从服务器的状态是一致的
- 复制积压缓冲区:一个固定长度的FIFO队列,记录着最近的传播的命令及其相对应的复制偏移量
- 如果断线重连之后复制偏移量对应的数据依然存在于复制积压缓冲区,则执行部分重同步;否则执行完整重同步
- 服务器运行ID:每个Redis服务器都有自身的ID;如果说主服务器中存在着从服务的ID,则认为之前连结过,尝试进行部分重同步;否则进行完整重同步
- 图片如下: