当前位置:网站首页>深入解析Redis中的复制
深入解析Redis中的复制
2022-07-23 05:46:00 【可能我浪荡】
在Redis中,可以通过执行SLAVEOF命令或者设置slaveof选项,让一个服务器去复制另一个服务器。进行复制中的主从服务器双方的数据库将保存相同的数据。
1.旧版复制功能的实现
Redis的复制功能分为同步和命令传播两个操作:同步操作用于从服务器状态更新至主服务器当前所处状态 命令传播操作则用于在主服务器的状态被修改,导致主从服务器的状态出现不一致时,让主从服务器的数据库回到一致状态。
- 同步:
1、当客户端向从服务器发送SLAVEOF命令,要求从服务器复制主服务器时,从服务器首先需要执行同步操作。同步操作需要通过向主服务器发送SYNC命令来完成,以下是执行步骤:
(1)从服务器向主服务器发送SYNC命令
(2)收到命令的主服务器执行BGSAVE命令,在后台生成一个RDB文件,并使用一个缓冲区记录从现在开始执行的所有写命令
(3)当主服务器的BGSAVE命令执行完毕时,主服务器会将生成的RDB发送给从服务器,从服务器接收并载入这个RDB,将状态更新至主服务器执行BGSAVE时的状态、
(4)主服务器将记录在缓冲区里的所有写命令发送给从服务器,从服务器执行这些命令 - 命令传播:
1、在同步操作执行完毕之后,将达到一致状态,但这种一致并不是一成不变的。为了让主从服务器再次回到一致状态,主服务器需要对从服务器执行命令传播操作:主服务器会将自己执行的写命令,发送给从服务器执行。
2.旧版复制功能的缺陷
在Redis下,从服务器对主服务器的复制可以分为以下两种情况: □ 初次复制 □断线后重复制
对于初次复制来说,旧版复制功能能够很好地完成任务,但对于断线后重复制来说,效率非常低
SYNC命令时一个非常耗费资源的操作
3.新版复制功能的实现
为了解决旧版复制功能在处理断线重复制情况时的低效问题,从2.8版本开始,使用PSYNC来代替SYNC PSYNC命令具有完整重同步和部分重同步两种模式
- 完整重同步用于处理初次复制情况:与SYNC的执行步骤基本一致
- 部分重同步则用于处理断线后重复值情况:当从服务器在断线后重新连接主服务器时,如果条件允许,主服务器可以将主从服务器连接断开期间执行的写命令发送给从服务器,只要接收并执行这些写指令,就可以更新至主服务器当前所处的状态。
4.部分重同步的实现
- 复制偏移量:
1、执行复制的双方会分别维护一个复制偏移量:主服务器每次向从服务器传播N个字节的数据时,就将自己的复制偏移量+N。从服务器每次收到传播来的N个字节数据时,就将自己的复制偏移量+N。
2、如果主从的偏移量相同,则处于一致状态。 - 复制积压缓冲区:
1、复制积压缓冲区是由主服务器维护的一个固定长度先进先出队列,默认大小为1MB。当主服务器进行命令传播时,它不仅会将写命令发送给所有从服务器,还会将写命令入队到复制积压缓冲区里。因此,主服务器的复制积压缓冲区里会保存着一部分最近传播的写命令,并且会为队列中每个字节记录相应的复制偏移量。
2、当从服务器重新连上主服务器时,从服务器会根据PSYNC命令将自己的复制偏移量发送给主服务器,主服务器会根据这个来决定执行何种同步操作。
3、如果offset偏移量之后的数据仍然存在于缓冲区里,那么执行部分重同步。否则执行完整重同步
3. 服务器运行ID
1、每个服务器,都会有自己的运行ID
2、运行ID在启动时自动生成,由40个随机的十六进制字符组成。
3、当从服务器进行初次复制时,主服务器会将自己的运行ID传送给从服务器。当从服务器断线并重新连上一个主服务器时,从服务器将向当前连接的主服务器发送之前保存的运行ID。如果相同,则尝试执行部分重同步;否则执行完整重同步。
5.PSYNC命令的实现
- PSYNC命令的调用方法有两种:
如果从服务器以前没有复制过任何主服务器,或者之前执行过SLAVEOF no one命令,那么在开始一次新的复制时将向主服务器发送PSYNC?-1命令,主动请求主服务器进行完整重同步。
如果从服务器已经复制过某个主服务器,那么从服务器在开始一次新的复制时将向主服务器发送PSYNC命令,接收到这个命令的主服务器会通过这2个参数来判断应该执行哪种同步操作。 - 根据情况,接收到PSYNC命令的主服务器会返回以下三种中的一种:
1、如果返回+FULLRESYNC回复,那么表示将执行完整重同步。
2、如果返回+CONTINUE回复,表示执行部分重同步操作,从服务器只要等着缺少的那部分数据。
3、如果返回-ERR回复,那么表示版本低于2.8,识别不了PSYNC命令,从服务器将向主服务器发送SYNC命令,并执行完整同步操作。
6.复制的实现
- 步骤1:设置主服务器的地址和端口
1、从服务器首先要做的就是将客户端给定的主服务器IP地址以及端口保存到服务器状态的masterhost和masterport属性里。
2、SLAVEOF命令时一个异步命令,在完成属性的设置工作后,从服务器将向发送SLAVEOF命令的客户端返回OK,表示复制指令已经被接收,而实际的复制工作将在之后才真正执行。 - 步骤2:建立套接字连接
1、根据IP地址和端口,创建连向主服务器的套接字连接。
2、如果从服务器创建的套接字能成功连接到主服务器,那么从服务器将为这个套接字关联一个专门用于处理复制工作的文件事件处理器,这个处理器将负责执行后续的复制工作。
3、而主服务器将为该套接字创建相应的客户端状态,并将从服务器看作是一个连接到主服务器的客户端来对待,这时从服务器将同时具有服务器和客户端两个身份。 - 步骤3:发送PING命令
1、从服务器称为主服务器的客户端后,做的第一件事就是发送一个PING命令,有2个作用:
(1)虽然成功建立起了套接字连接,但双方并未使用该套接字进行过任何通信,通过发送PING命令可以检查套接字的读写状态是否正常。
(2)可以检查主服务器能否正常处理命令请求。
2、从服务器在发送PING命令后将遇到以下3种情况中的1种:
(1)如果返回了一个命令回复,但从服务器却不能在规定的时限内读取出命令回复的内容,那么表示网络连接状态不佳,不能继续执行复制工作的后续步骤。当出现这种情况时,从服务器断开并重新创建连向主服务器的套接字。
(2)如果返回一个错误,那么表示暂时没办法处理从服务器的命令请求,不能继续执行复制工作的后续步骤。当出现这种情况时,从服务器断开并重新创建连向主服务器的套接字。
(3)如果读取到PONG回复,那么表示网络连接正常,可以继续。 - 身份验证
1、如果从服务器设置了masterauth选项,那么进行身份验证。在需要进行身份验证的情况下,从服务器将向主服务器发送一条AUTH命令,命令的参数为从服务器masterauth选项的值。
2、从服务器在身份验证阶段可能遇到的情况有以下几种:
(1)如果主服务器没有设置requirepass选项,并且从服务器也没有设置msaterauth选项,将继续执行
(2)如果从服务器通过AUTH发送的密码和主服务器requirepass选项所设置的密码相同,那么继续执行;如果不相同,那么将返回一个invalid password错误。
(3)如果主服务器设置了requirepass选项,但从服务器却没有设置msaterauth选项,那么将返回一个NOAUTH错误。另一方面,如果主服务器没有设置,但从服务器设置了,那么将返回一个no password is set错误。
所有错误情况都会令从服务器中止目前的复制工作,并从创建套接字开始重新执行复制,直到身份验证通过,或从服务器放弃执行复制为止。 - 步骤5:发送端口信息
1、在身份验证步骤后,从服务器将执行命令REPLCONF listening-port,向主服务器发送从服务器的监听端口号。
2、主服务器在接收到这个命令后,会将端口号记录在从服务器对应客户端状态的slave_listening_port属性中。该属性目前唯一的作用就是在主服务器执行INFO replication命令时打印出从服务器的端口号。 - 步骤6:同步
1、从服务器将向主服务器发送PSYNC命令,执行同步操作。PS:在同步操作执行之前,只有从服务器时主服务器的客户端,但是在执行同步操作之后,主服务器也会成为从服务器的客户端。
2、如果PSYNC命令执行的是完整重同步操作,那么主服务器需要成为从服务器的客户端,才能将保存在缓冲区里面的写命令发送给从服务器执行。
如果是部分重同步,那么主服务器需要成为从服务器的客户端,才能向从服务器发送保存在复制积压缓冲区里的写命令。
3、正因为主服务器称为了从服务器的客户端,所以主服务器才可以通过发送写命令来改变从服务器的数据库状态,不仅同步操作需要用到这一点,这也是命令传播操作的基础。 - 步骤7:命令传播
当完成了同步后,主从服务器就会进入命令传播阶段,这时主服务器只要一直将自己执行的写命令发送给从服务器,而从服务器只要一直接收并执行写命令,就可以保证主从服务器一直保持一致了。
7.心跳检测
在命令传播阶段,从服务器默认会以每秒一次的频率,向主服务器发送命令:REPLCONF ACK<replication_offset>
- 检测主从服务器的网络连接状态
1、如果主服务器超过一秒钟没有收到从服务器发来的REPLCONF ACK命令,那么主服务器就知道连接出现问题了 - 辅助实现min-slaves配置选项
1、Redis的min-slaves-to-write 3和min-slaves-max-lag 10两个选项可以防止主服务器在不安全的情况下执行写命令
那么在从服务器的数量少于3个,或者3个从服务器的颜值都大于等于10秒时,主服务器将拒绝执行写命令 - 检测命令丢失
1、如果发现从服务器当前的复制偏移量少于自己的复制偏移量,然后主服务器就会根据从服务器提交的复制偏移量,在复制积压缓冲区里找到缺少的数据,并发送给从服务器。
8.重点回顾
- Redis2.8以前的复制功能不能高效地处理断线后重复制情况,但新添加的部分重同步功能可以解决这个问题。
- 部分重同步通过复制偏移量、复制积压缓冲区、服务器运行ID三个部分来实现。
- 在复制操作刚开始的时候,从服务器会成为主服务器的客户端,并通过向主服务器发送命令请求来执行复制步骤,而在后期,主从服务器会互相成为对方的客户端。
- 主服务器通过向从服务器传播命令来更新从服务器的状态,保持主从服务器一致,而从服务器则通过向主服务器发送命令来进行心跳检测,以及命令丢失检测。
边栏推荐
猜你喜欢

C语言数据库:详细的说明用学生管理系统了解数据库的操作,简单易懂。

socket基础知识以及各种使用场景

Common sort exchange sort

Common sorting method - Select Sorting

Axure实现增删改查

Question bank of basic principles of steel structure

C#:快速排序,有相同的数字会忽略,然后继续先前的寻找方向去找下一个满足要求的数字进行替换
![[bootloader architecture and brushing process based on UDS service]](/img/c7/de4f1e32f89173e18d74d2f624f3f9.png)
[bootloader architecture and brushing process based on UDS service]

LVS负载均衡调度原理及配置方法

unity3d:向量计算,AOE图形相交
随机推荐
SCI审稿过程中的几种状态
快速排序的按区间的三个版本及优化--友友们不一定了解
Mutual implementation of queue and heap (pure C implementation)
Jetson TX1 installation pytoch
Unity3d:特效对象池,超时删除池内GameObject,GC权值
Analysis of 100 questions and answers in Higher Algebra
Dicom开源工具库
Navicat for MySQL 安装教程
Unity3d+GameFramework:资源分析,资源依赖,循环依赖检测
C#:TopK:1万个数取前最大的100,堆排序
0动态规划 LeetCode1024. 视频拼接
Common sorting method - Select Sorting
APISIX的源码安装与使用
Common sort exchange sort
Related repo of synthetic Chinese recognition dataset
Problems encountered in configuring the historical version of detectron
SQL基础操作总结
C语言也能写植物大战僵尸
TeX or LaTeX or MikTeX or TeX Live or CTeX
嵌入式从入门到精通(入土)——超详细知识点分享1