前言:
之前总是带着问题查资料,都是零碎的知识点,没有系统的学习过redis,现根据大佬 三歪的Redis文章(Java技术公众号:Java3y)重新学习。
这篇主要讲的内容有:
Redis主从复制原理
全量复制和部分复制、以及心跳机制
一、Redis主从架构

主服务器负责接收写请求
从服务器负责接收读请求
从服务器的数据由主服务器复制过去。主从服务器的数据是一致的
主从架构的好处:
数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。 故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余。 负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。 高可用基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础。
二、主从复制配置
2.1 建立主从复制
默认情况下,每台Redis服务器都是主节点;
主从复制的开启,完全是在从节点发起的,不需要我们在主节点做任何事情;
通过 slaveof命令,使之变为从节点。
# slaveof <masterip> <masterport>,则该Redis实例成为从节点。slaveof 192.168.101.3 6379
2.2 断开主从复制
通过slaveof no one断开。需要注意的是,从节点断开复制后,不会删除已有的数据,只是不再接受主节点新的数据变化。
slaveof no one
主从复制过程大体可以分为3个阶段:连接建立阶段(即准备阶段)、数据同步阶段、命令传播阶段;
3.1 连接建立阶段(主从节点之间建立连接)
从服务器设置主服务器的IP和端口
建立与主服务器的Socket连接
发送PING命令(检测Socket读写是否正常与主服务器的通信状况)
身份验证(看有没有设置对应的验证配置)
从服务器给主服务器发送端口的信息,主服务器记录监听的端口
创建stock连接成功之后从节点:为该socket建立一个专门处理复制工作的文件事件处理器,负责后续的复制工作,如接收RDB文件、接收命令传播等。主节点:接收到从节点的socket连接后(即accept之后),为该socket创建相应的客户端状态,并将从节点看做是连接到主节点的一个客户端,后面的步骤会以从节点向主节点发送命令请求的形式来进行。身份验证:如果从节点中设置了masterauth选项:则从节点需要向主节点进行身份验证;没有设置该选项,则不需要验证。从节点进行身份验证是通过向主节点发送auth命令进行的,auth命令的参数即为配置文件中的masterauth的值。如果主节点设置密码的状态,与从节点masterauth的状态一致(一致是指都存在且密码相同,或者都不存在),则身份验证通过,复制过程继续;如果不一致,则从节点断开socket连接,并重连。

3.2 数据同步阶段
从服务器发送psync命令请求同步数据,此时根据主从节点当前状态的不同,同步方式可能是全量复制或部分复制。
3.2.1 全量复制
从服务器向主服务器发送PSYNC命令(Redis2.8之前是SYNC命令)
收到PSYNC命令的主服务器执行BGSAVE命令,在后台生成一个RDB文件。并用一个缓冲区来记录从现在开始执行的所有写命令。
当主服务器的BGSAVE命令执行完后,将生成的RDB文件发送给从服务器,从服务器首先清除自己的旧数据,然后接收和载入RBD文件。将自己的数据库状态更新至与主服务器执行BGSAVE命令时的状态。
主服务器将所有缓冲区的写命令发送给从服务器,从服务器执行这些写命令,达到数据最终一致性。
如果从节点开启了AOF,则会触发bgrewriteaof的执行,从而保证AOF文件更新至主节点的最新状态

3.2.2 部分复制
部分复制可以让我们断线后重连只需要同步缺失的数据(而不是Redis2.8之前的同步全部数据),这是符合逻辑的!
部分复制功能由以下部分组成:
主从服务器的复制偏移量
主服务器的复制积压缓冲区
服务器运行的ID(run ID)
名词解释:复制偏移量:执行复制的双方都会分别维护一个复制偏移量主服务器每次传播N个字节,就将自己的复制偏移量加上N从服务器每次收到主服务器的N个字节,就将自己的复制偏移量加上N复制积压缓冲区:由主节点维护的、固定长度的、先进先出(FIFO)队列,默认大小1MB(大小可调)当主服务器进行命令传播时,不仅仅会将写命令发送给所有的从服务器,还会将写命令入队到复制积压缓冲区里面(这个大小可以调的)。
主从复制偏移量不同 && 复制积压缓冲区存在丢失的偏移量的数据,那就执行部分复制,否则执行全量复制。
3.3 命令传播阶段
当完成了同步之后,主从服务器就会进入命令传播阶段。这时主服务器只要将自己的写命令发送给从服务器,而从服务器接收并执行主服务器发送过来的写命令,就可以保证主从服务器一直保持数据一致了!
从服务器会向主服务器发送REPLCONF ACK命令
频率是每秒1次;命令格式为:REPLCONF ACK <offset>,其中offset指从节点保存的复制偏移量
检测主从服务器的网络状态:该命令会被主节点用于复制超时的判断
检测命令丢失:从节点发送了自身的offset,主节点会与自己的offset对比,如果从节点数据缺失(如网络丢包),主节点会推送缺失的数据
辅助实现保证从节点的数量和延迟:Redis主节点中使用min-slaves-to-write(最小从服务器数)和min-slaves-max-lag(从服务器最大确认延迟)参数,来保证主节点在不安全的情况下不会执行写命令
主从服务器的关系:
连接建立阶段,从服务器是主服务器的客户端
数据同步阶段,主从服务器互为客户端(发送psync命令、推送缓冲区的写命令)
命令传播阶段,主从服务器互为客户端(推送写命令、心跳机制)
参考资料:
https://www.cnblogs.com/kismetv/p/9236731.html
https://mp.weixin.qq.com/s/6nBUoP2cid1Qn8XngDMjJw




