目录
主从复制的意义
Redis在大多数业务场景下,是作为数据缓存层存在的,主要面对读大于写的应用场景;这种场景下,单一Redis存在性能瓶颈,以主从结构提供服务可以使业务变得更加灵活,可以直观地应用读写分离等优化手段,如下图
主从复制功能静态结构
如上图所示,将主从节点分开来看。从节点上跟主从复制相关的功能有认证请求、心跳交换、配置请求和最重要的数据同步,从节点上几个功能是通过状态机来进行组织和调用,在后面的流程中会仔细画出;而在主从同步中,主节点的所有行为都是在接收到从节点的相关请求后被动应答,主从之间的互动会在后面的流程中使用时序图进行说明
主从复制相关配置
名称 | 作用 | 默认 | 取值范围 |
replicaof | 指定复制的对象 | 不启用 | replicaof <masterip> <masterport> |
masterauth | 配置主节点的密码 | 不启用 | masterauth <master-password> |
masteruser | 配置用于同步的用户,用于高版本,Redis加入用户权限控制之后 | 不启用 | masteruser <username> |
replica-serve-stale-data | 在从节点复制过程中,或从节点已与主节点失联,从节点是否继续应答客户端的请求 | yes | yes|no |
repl-diskless-sync | 从节点同步主节点的数据时,是否令主节点放弃落盘而直接通过网络传输数据 | no | yes|no |
repl-diskless-sync-delay | 采用不落盘复制时,主节点一旦收到同步请求后,等待多久再产生复制数据(等待过程中有可能有更多从节点发起同步) | 5 | int |
repl-diskless-load | 从节点收到复制信息后是否马上加载而不先落盘 | disabled | disabled|on-empty-db|swapdb |
repl-ping-replica-period | 从节点ping主节点的间隔 | 10 | int |
repl-timeout | 主从复制的超时时间 | 60 | int |
repl-disable-tcp-nodelay | 是否主动减少主从同步占用的TCP带宽 | no | yes|no |
repl-backlog-size | 主节点存储复制进度占用的空间大小(用于psync) | 1mb | 空间标识 |
repl-backlog-ttl | 主节点释放repl-backlog前等待的时间(从没有从节点接入开始计算) | 3600 | int |
replica-priority | 用于哨兵模式下决定哪个从节点更可能被晋升,越小越可能被晋升,特殊地,0表示不能被晋升 | 100 | int |
min-replicas-to-write | 主节点需要至少多少个从节点才能接受写入请求 | 0 | int |
min-replicas-max-lag | 在上面的feature开启后,从节点的延迟必须在多少秒之内才算有效 | 10 | int |
replica-announce-ip | 在NAT或docker部署模式下,从节点宣告自己的IP | 无 | IP |
replica-announce-port | 在NAT或docker部署模式下,从节点宣告自己的端口 | 无 | 0-65535 |
主从复制流程
从节点复制时的状态转换
如图所示,从节点按照一定顺序进行转移,转移的过程中一旦从主节点取到非法的返回值,或者向主节点写配置没写进去,就走到失败的REPL_STATE_CONNECT;另外,集群中从节点升为主或被reset,会导致走到REPL_STATE_NONE,相当于直接打断复制过程。
主从复制时序图
如图所示,主从同步的交互时序图如上图所示,在sync(全量同步)之前,主从间的互动都是从节点发起某种请求,主节点作出相应的应答,主导过程在从节点,至于从节点详细的状态变化,可以看上一节讲解从节点的状态机。在主从关系成功建立之后,从节点发起sync请求,主节点根据从节点的请求中参数决定触发全量同步或是增量同步,对于首次建立的主从,第一次同步必然是全量,在此以后的psync请求就尽可能走增量,从复制缓冲区中将新的数据同步给从节点。
增量主从复制的目的
psync
psync特性在2.8版本发布,Redis的主从同步终于有了增量复制的手段。这一次是一次针对复制效率的优化。
主节点维护了一个复制缓冲区,从节点记录下主节点的ID,每次复制时带上主节点ID和复制偏移量,如果主节点ID对得上且偏移量仍在缓冲区内,则将增量部分同步给从节点即可完成本次复制
这里在上面的时序图中体现了,不再赘述
psync2
psync特性在4.0版本发布,这一次从节点不止存储主节点的ID和偏移量,还会存储上一个主节点的ID和偏移量。优化的思路还是与psync一致。这一次是一次针对高可用框架的优化。
Redis在3.0引入集群之后,可以横向扩容,但是集群中每一个主节点和它的从节点看起来仍是一个星型的复制拓扑,当集群中的节点发生failover之后,新上位的主节点仍记录着上一个主节点的ID和偏移,其他从节点就可以自然地和新的主节点进行增量同步。在3.0之前,虽然也能搭出来星型复制,用sentinel做高可用,但其实主从框架在实际场景下可能是用VIP或者LB更为实用,毕竟读大于写。在集群架构的引入后,这个优化就显得非常地自然和重要。