
文章目录1. 主从复制1.1 主从复制是怎么个事1.2 拓扑结构1.2.1 一主一从拓扑1.2.2 一主多从拓扑1.2.3 树形拓扑1.3 主从复制原理1.3.1 复制过程1.3.2 数据同步PSYNC1.3.2.1 replicationid/replid (复制id)1.3.2.2 复制偏移量维护1.3.3 psync运行流程1.3.4 全量复制1.3.4.1 全量复制流程1.3.5 部分复制1.3.6 复制积压缓冲区1.3.7 实时复制1. 主从复制在分布式系统中有一个非常关键的问题单点问题。如果某个服务器程序只有一个节点1. 可用性问题如果这个机器挂了意味着服务就中断了。2. 单点服务器的性能和并发量也是比较有限的。引入分布式系统主要就是为了解决上述的单点问题。在分布式系统中往往有多个服务器 来部署redis服务从而构成一个redis集群此时就可以让这个集群给整个分布式系统提供服务。Redis的几种部署方式1. 主从模式2. 主从 哨兵模式3. 集群模式1.1 主从复制是怎么个事在若干个Redis节点中有一个是主节点其余的是从节点。从节点上的数据要随着主节点变化从节点上的数据要和主节点保持一致。本来在主节点上保存一堆数据引入从节点之后就是要把主节点上的数据复制到从节点上后续如果主节点的数据有修改也会同步到从节点上。在实际业务场景中读操作往往要比写操作更加频繁。在Redis主从模式中从节点上的数据不允许修改只能读取数据主节点可以进行读操作和写操作。主从复制是只能从“主”复制到“从”不能从“从”复制到“主”复制。上面我们说单点问题如果这个节点挂了那么整个Redis服务就挂了。使用主从结构来进行部署再采用异地多活在不同的机房进行部署防止全部部署在一个机房中如果这个机房挂了那么Redis服务也就挂了的方式进行部署就大大保证了可用性。主节点和从节点之间是通过网络来进行传输的TCPTCP内部支持nagle算法这个算法是默认开启的。开启nagle算法会增加TCP的传输延迟但是会减少网络带宽。关闭nagle算法会减少TCP的传输延迟会增加网络带宽。Nagle算法问题当程序频繁的发送体积非常小的数据每个数据包的有效载荷可能只有1-2个字节。然而每个网络数据包都包含至少40个字节的TCP和IP头部信息发送一个字节的数据实际需要传输41个字节这样不仅网络利用率极低还会增加路由器的负担加剧网络拥塞影响整体网络效率。算法原理当发送方应用程序第一次调用send写入数据时即使数据量很小系统也会立即发送这个数据包。在收到第一个数据包的确认ACK之前如果缓冲区中积累的数据达到了最大报文长度此时发送方会立即将这个满载的大数据包发送出去。在这个过程中一直没有积累到最大报文长度当收到了第一个数据包的ACK确认发送方也会立即将缓冲区内积累的所有数据包打包成一个数据包发送出去。1.2 拓扑结构1.2.1 一主一从拓扑在主节点上进行读操作和写操作在从节点上进行读操作。但是如果写请求太多此时会给主节点造成一些压力。可以通过关闭主节点的AOF只在从节点上开启AOF从而减小主节点的压力。但是主节点关闭了AOF就会有一个缺陷如果主节点挂了不能自动重启。如果自动重启了没有AOF文件就会丢失数据进一步的主从同步会把从节点的数据也给删了。当主节点挂了之后让主节点从从节点获取AOF文件再启动就可以解决上面的问题。1.2.2 一主多从拓扑这种一主多从的结构在从节点越多主节点发生修改就要同步到从节点上多份加大了主节点的负载。1.2.3 树形拓扑主节点只需要同步部分从节点剩下的节点交给从节点慢慢的去向从节点的从节点进行同步这样主节点就不需要那么高的网络带宽了。但是这样一旦主节点的数据进行了修改同步是延时就变的更长了。1.3 主从复制原理1.3.1 复制过程在 Redis 主从复制中始终是由从节点主动发起并向主节点建立连接的。1. 从节点保存主节点的ip和端口号。 2. 从节点与主节点建立socket连接TCP连接三次握手。 3. 验证主节点是否能够正常工作发送ping. 4. 是否需要密码验证 5. 数据同步。 6. 进入命令传播阶段主节点持续发送写命令。1.3.2 数据同步PSYNC1.3.2.1 replicationid/replid (复制id)replicationid是主节点生成的主节点在启动时或者晋升为主节点时都会生成repplicationid即使是同一个主节点每次重启replicationid也是不一样的。从节点和主节点建立了复制关系就会从主节点这边获取到主节点的replicationid。127.0.0.1:6379info replication# Replicationrole:master connected_slaves:0 master_replid:1da596acecf5a34b4b2aae45bd35be785691ae69 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:0 second_repl_offset:-1 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0master_replid 和 master_replid2假设现在是一主一从结构主节点是A从节点是B。主节点A会生成replid从节点B会获取到A的replid。如果A和B在通信过程中出现了一些网络抖动B就可能以为A挂了B就会自己成为主节点于是B给自己生成了一个新的master_replid。虽然B自己生成了一个但是它也会用master_replid2记录之前那个旧的replid。如果后续网络恢复了B就可以根据master_replid2找到之前的主节点之前的主节点会作为B的从节点继续提供服务。如果后续A节点的网络没有恢复B就继续充当主节点处理后续的请求。1.3.2.2 复制偏移量维护offset就是在描述进度主节点和从节点都会维护自己的偏移量。主节点会收到很多修改操作的命令每个命令都要占用几个字节主节点会把这些每个命令的字节数进行累加。从节点的偏移量就描述了现在从节点从主节点那里同步数据同步到了哪里。如果从节点的偏移量和主节点的偏移量一样了那么就代表此刻从节点和主节点中的数据完全保持一致了。1.3.3 psync运行流程从节点发送psync时带有replid 和offset值主节点就根据psync的参数来进行判定这次是按照全量复制合适还是部分复制合适。replicationid描述数据的来源。offset描述数据的复制进度。psync可以从主节点获取全量数据也可以获取一部分数据1. offset -1获取全量数据。2. offset 具体的正整数从当前偏移量开始获取。1.3.4 全量复制全量复制⼀般用于初次复制场景Redis 早期支持的复制功能只有全量复制它会把主节点全部数据⼀次性发送给从节点当数据量较⼤时会对主从节点和网络造成很⼤的开销。全量复制的时机从节点首次和主节点进行数据同步。主节点不方便进行部分复制的时候。1.3.4.1 全量复制流程从节点发送PSYNC命令请求同步由于是第一次进行复制从节点没有主节点的replid和复制偏移量所以发送pysnc ? -1。主节点根据命令判断出来要进行全量复制回复FULLRESYNC。从节点就收到主节点的运行信息并进行保存。主节点执行bgsave命令生成RDB同时启动复制积压缓冲区。主节点将RDB文件发送到从节点从节点保存RDB数据到本地硬盘。主节点将从生成RDB到接收完成期间主节点执行的写命令写入到复制缓冲区中等从节点保存完RDB文件之后主节点再将缓冲区中的数据补发给从节点补发的文件仍按以rdb的二进制格式追加写入到收到的rdb文件中保持主从一致性。从节点清空旧数据。从节点加载RDB文件得到与主节点一致的数据。如果从节点已经开启了AOF持久化在上述的加载过程中从节点就会产生出很多的AOF日志此时残生的AOF日志整体来说可能会产生一定的冗余信息因此会针对AOF日志进行重写。主机点生成的RDB二进制文件不是直接保存到文件中的而是直接进行网络传输了从节点也是直接把接收到的数据进行加载。这样就是无硬盘模式(省下了一系列是读硬盘和写硬盘的操作)。runid 和 replidrunid每个节点都不同是用来标识一次redis的运行的。runid主要是用在支撑redis哨兵这个功能的。replid具有主从关系主从节点是相同的。1.3.5 部分复制⽤于处理在主从复制中因网络闪断等原因造成的数据丢失场景当从节点再次连上主节点后如果条件允许主节点会补发数据给从节点。因为补发的数据远小于全量数据可以有效避免全量复制的过高开销。部分复制的时机 从节点已经从主节点上复制过数据了。因为网络抖动或者从节点重启了从节点需要重新从主节点这边同步数据。1.3.6 复制积压缓冲区积压缓冲区数据是内存中的简单固定长度的队列会记录最近一段时间主节点修改的数据。从节点通过心跳包发送给主节点自己的offset进度主节点判断这个进度是否在积压缓冲区之内如果确实是在挤压缓冲区内就进行部分复制否则就进行全量复制。1.3.7 实时复制从节点已经和主节点同步好数据了但是之后从节点还会源源不断的收到修改的请求需要把这些同步给从节点。从节点和主节点之间会建立TCP的长连接然后主节点把自己收到的修改请求通过TCP长连接发送给从节点从节点再根据这些修改请求修改内存中的数据。心跳包机制在进行实时复制的时候需要保证连接处于一个可用的状态。主节点默认每隔10s给从节点发送一个ping命令从节点收到之后就相应pong.从节点默认每隔一秒钟就给主节点发送一个特定的请求上报当前从节点复制数据的offset。实时复制是主从节点保持同步的常态过程部分复制是网络中断后恢复同步的补救措施。