当前位置:网站首页 > R语言数据分析 > 正文

redis 连接哨兵(redis连接哨兵命令)



  Redis的复制功能分为同步(sync)和命令传播两个操作

1.1.1 命令传播

  作用:作用于将从服务器的数据库状态更新至主服务器当前所处的数据库状态。

  从服务器对服务器的同步操作需要通过向主服务器发送SYNC命令来完成,以下是SYNC命令的执行步骤:

  1. 从服务器向主服务器发送SYNC命令。

  2. 收到SYNC命令的主服务器执行BGSAVE命令,在后台生成一个RDB文件,并使用一个缓冲区记录从现在开始执行的所有写命令。

  3. 当主服务器的BGSAVE命令执行完毕后时,主服务器会将BGSAVE命令生成的RDB文件发送给从服务器,从服务器接收并载入RDB文件,将自己的数据库状态更新至主服务器执行BGSAVE命令时的数据库状态。

  4. 主服务器将记录在缓冲区的所有写命令发送给从服务器,从服务器执行这些写命令,将自己的数据库状态更新至主服务器数据库当前所处的状态。
在这里插入图片描述

1.1.2 命令传播

  作用:用于主服务器的数据库状态被修改,导致主从服务器的数据库状态出现不一致时,让主从服务器的数据库重新回到一致状态。

  比如同步完成后,主服务器删除了key,从服务器没删除,这时主从数据库又不一致了,那为了让主从服务器继续保持一致,主服务器需要对从服务器执行命令传播操作:主服务器将写命令发送给从服务器执行,从服务器执行后,主从就一致了。

  虽然能让主从保持一致,但是对于断线后重复制,效率特别低。因为断线后重复制时,从服务器向主服务器发送SYNC命令,主服务器将新生成的RDB文件发送给从服务器,从服务器接收和载入这个RDB文件,更新至主服务器当前所处状态。整个过程是全量同步,而不是增量

  为了解决旧版复制功能在处理断线重复制情况时的低效问题,Redis从2.8版本开始,使用PSYNC命令代替SYNC命令来执行复制时的同步操作。

  PSYNC命令具有完整重同步和部分重同步两种模式:

  完整重同步用于处理初次复制情况,执行步骤跟SYNC命令的执行步骤基本一样,都是通过让主服务器创建并发送RDB文件,以及向从服务器发送保存在缓冲区里的写命令来进行同步。

  部分重同步用于处理断线后重复制情况:当从服务器在断线后重新连接主服务器时,如果条件允许,主服务器可以将主从服务器连接断开期间执行的写命令发送给从服务器,从服务器只要接收并执行这些写命令,就可以主从一致。

  如下图所示,PSYNC命令只需要将从服务器缺少的写命令发送给从服务器执行就可以。而SYNC命令需要生成、传送和载入整个RDB文件。
在这里插入图片描述
在这里插入图片描述

  部分重同步由以下三个部分构成:

  1. 主服务器的复制偏移量和从服务器的复制偏移量

  2. 主服务器的复制积压缓冲区

  3. 服务器的运行ID

1.4.1 复制偏移量

  主服务器每次向从服务器传播N个字节的数据时,就将自己的复制偏移量的值加上N。从服务器每次收到主服务器传播来的N个字节的数据时,就将自己的复制偏移量的值加上N。

  如果主从服务器处于一致时,那两者的偏移量总是相同的。

  假设从服务器A在断线后又连上了主服务器,那么从服务器将向主服务器发送PSYNC命令,报告从服务器A当前的复制偏移量为10086,那么这时,主服务器应该对从服务器执行完整重同步还是部分重同步呢?如果执行部分重同步,主服务器又如何补偿从服务器A在断线期间丢失的那部分数据呢?以上问题的答案都和复制积压缓冲区有关。

1.4.2 复制积压缓冲区

  复制积压缓冲区是由主服务器维护的一个固定长度的先进先出(FIFO)队列,默认大小为1MB。
  当主服务器进行命令传播时,它不仅会将写命令发送给所有从服务器,还会将写命令入队到复制积压缓冲区。因为主服务器的复制积压缓冲区里会保存着一部分最近传播的写命令,并且复制积压缓冲区会为队列中的每个字节记录相应的复制偏移量,如下表所示:
在这里插入图片描述

  当从服务器重新连接上主服务器时,从服务器会通过PSYNC命令将自己的复制偏移量offset发送给主服务器,主服务器会根据这个复制偏移量来决定对从服务器执行何种同步操作:

  如果offer偏移量之后的数据(也即是offset+1开始的数据)仍然存在于复制积压缓冲区里,那么主服务器将对从服务器执行部分重同步。

  相反,如果offset偏移量之后的数据已经不存在于复制积压缓冲区,那么主服务器将对从服务器执行完整重同步操作。因为复制积压缓冲区是固定大小,如果offset偏移量之后的数据已经不存在于复制积压缓冲区,说明从服务器已经落后很久了,比如从offset=10086,但是主服务器复制积压缓冲区里的最小的offset=10096,那中间10字节的数据,怎么知道是哪些,所以无法部分重同步。

  所以复制积压缓冲区的大小要设置恰当,因为如果主服务器需要执行大量写命令,又或者从服务器断线后重连所需的时间比较长,那么复制积压缓冲区太小的话,PSYNC命令的复制重同步模式就不能正常发挥作用。

  复制积压缓冲区大小= 2*断线后重连主服务器所需的平均时间(单位秒) * 平均每秒写命令数据量(协议格式的写命令的长度总和),比如平均5秒连上,平均每秒1M的写数据,那最好复制积压缓冲区大小= 10M

1.4.2 服务器运行ID

  每个Redis服务器,主和从,都会有自己的运行ID。运行ID在服务器启动时自动生成,由40个随机的十六进制字符组成。

  当从服务器对主服务器初次复制时,主服务器会将自己的运行ID传送给从服务器,而从服务器会将这个运行ID保存起来。

  当从服务器断线并重新连上一个主服务器时,从服务器将向当前连接的主服务器发送之前保存的运行ID:

  如果从服务器保存的运行ID和当前连接的主服务器的运行ID相同,说明从服务器断线之前复制的就是当前连接的这个主服务器,主服务器就可以继续尝试执行部分重同步操作。

  相反,如果从服务器保存的运行ID和当前连接的主服务器的运行ID不一致,说明从服务器断线之前复制的主服务器并不是当前连接的这个主服务器,主服务器将对从服务器执行完整重同步操作。

  举例:假设从服务器正在复制一个运行id为1的主服务器,那么在网络断开重新连上主服务器之后,从服务器将向主服务器发送这个运行ID,主服务器将根据自己的运行ID时不是1来判断是执行部分重同步还是完整重同步。

  如下图所示:第一次复制,向主服务器发送命令PSYNC ? -1,表示要完整重同步。命令PSYNC 表示部分重同步,runid是上一次复制的主服务器的运行ID,offset是服务器当前的复制偏移量。

  主服务器回复有3种:

  1. 主服务器返回+FULLRESYNC 回复,表示主服务器将于从服务器执行完整重同步操作:runid是这个主服务器的运行ID,从服务器会将这个ID保存起来,在下一次发送PSYNC命令时使用,offset是主服务器当前的复制偏移量,从服务器将这个值作为自己的初始化偏移量。

  2. 主服务器返回CONTINUE回复,表示将执行部分重同步。

  3. 主服务器返回-ERR回复,表示主服务器的版本低于Redis2.8,识别不了PSYNC命令。
在这里插入图片描述

  通过向从服务器发送SLAVEOF <mater_ip> <master_port>,可以让从服务器去复制一个主服务器。

1.6.1 步骤1:设置主服务器的地址和端口

  向从服务器发送命令SLAVEOF 127.0.0.1 6379,从服务器首先要做的就是把给到的主服务器的ip和端口保存到服务器状态的masterhost属性和masterport属性里:
在这里插入图片描述
  SLAVEOF命令是异步的,从服务器向客户端返回OK,然后才会真正执行复制工作。

1.6.2 步骤2:建立套接字连接

  从服务器根据设置的IP和端口,创建连向主服务器的套接字。

1.6.3 步骤3:发送PING连接

  前面建立了套接字连接,但是双方未通信,发送PING命令检查套接字的读写状态是否正常。
在这里插入图片描述

1.6.4 步骤4:身份验证

  如果主服务器设置了masterauth选项,那么要进行身份验证,否则就不需要。从服务器向主服务器发送一条AUTH命令,命令的参数是从服务器的masterauth选项的值,这个值也是主服务器设置的requirepass选项值。
在这里插入图片描述

1.6.5 步骤5:发送端口信息

  在身份验证步骤之后,从服务器将执行命令REPLCONF listening-port ,向主服务器发送从服务器的监听端口号

  例如在我们的例子中,从服务器的监听端口为12345,那么从服务器将向主服务器发送命令 REPLCONF listening-port 12345,如下图所示:
在这里插入图片描述

1.6.6 步骤6:同步

  从服务器向主服务器发送PSYNC命令

1.6.7 步骤7:命令传播

  完成同步之后,主从服务器进入命令传播阶段,这时主服务器只要一直将自己执行的写命令发送给从服务器,而从服务器只要一直接收并执行主服务器发来的写命令,就可以保证主从服务器一直保持一致了。

  在命令传播阶段,从服务器默认会以每秒一次的频率,向主服务器发送命令REPLCONF ACK <replication_offset>,检测主从服务器的网络连接状态和检测命令丢失。

  由一个或多个Sentinel实例组成的Sentinel系统,可以监视任意多个主服务器和从服务器,当主服务器下线是,就会从从服务器中选一个当主服务器。原来的主服务器重新上线时,就会成为从服务器。

  Sentinel默认会以每10秒一次的频率,通过命令连接向被监视的主服务器发送INFO命令,并通过分析INFO命令的回复来获取主服务器的当前信息。

  举例:如下下图所示,一主三从,Sentinel将持续向主服务器发送INFO命令,并获得如下回复:
在这里插入图片描述
在这里插入图片描述
  Sentinel可以获得两方面的信息:


  1. 服务器本身的信息,包括run_id:服务器运行ID和role:服务器角色。

  2. 从服务器信息,每个从服务器都由一个“slave”字符串开头的行记录。ip是从服务器的ip,port是从服务器的端口。

  主观下线:默认情况下,Sentinel会以每秒一次的频率向所有连接的实例(包括master、slave和其他Sentinel)发送PING命令,并通过实例返回的回复来判断是否在线。Sentinel配置文件中的down_after_milliseconds选项指定了Sentinel判断实例进入主观下线所需的时间长度,单位是毫秒。比如配置了5000毫秒,那么5s内连续向Sentinel返回无效回复,Sentinel就会将其标记为主观下线

  客观下线:当Sentinel将一个主服务器判断为主观下线之后,为了确认这个主服务器是否真的下线了,它会向同样监视这一主服务器的其他Sentinel进行询问,看它们是否也认为主服务器进入了下线状态(可能是主观下线或者客观下线)。当Sentinel从其他Sentinel那里收到足够数量的已下线判断之后,Sentinel就会将从服务器判定为客观下线,并对主服务器执行故障转移操作

  当一个主服务器被判断为客观下线时,监视这个下线主服务器的各个Sentinel会进行协商,选举出一个领头Sentinel,并由领头Sentinel对下线主服务器执行故障转移操作。领头Sentinel是怎么选的呢?

  1)所有在线的Sentinel都有被选为领头Sentinel的资格

  2)所有Sentinel都有一次将某个Sentinel设置为局部领头Sentinel的机会,并且局部领头一旦设置,就不能再改了

  3)每个发现主服务器进入客观下线的Sentinel都会要求其他Sentinel将自己设置为局部领头Sentinel

  4)Sentinel设置局部领头Sentinel的规则是先到先得:最先向目标Sentinel发送设置要求的源Sentinel将成为目标Sentinel的局部领头Sentinel,而之后接收到的所有设置要求都会被目标Sentinel拒绝

  5)如果某个Sentinel被半数以上的Sentinel设置成了局部领头Sentinel,那么这个Sentinel成为领头Sentinel

  6)如果在给定时限内,没有一个Sentinel被选举为领头Sentinel,那么各个Sentinel将在一段时间之后再次进行选举,直到选出领头Sentinel为止

  选举领头Sentinel的方法就是Raft算法

  在选举出领头Sentinel之后,领头Sentinel将对已下线的主服务器执行故障转移操作:

  1)在已下线主服务器属下的所有从服务器里面,挑选出一个从服务器,并将其转换为主服务器

  2)让已下线主服务器属下的所有从服务器改为复制新的主服务器

  3)将已下线主服务器设置为新的主服务器的从服务器,当这个旧的主服务器重新上线时,它就会成为新的主服务器的从服务器

  新的主服务器是怎么挑选出来的呢?领头Sentinel会将已下线主服务器的所有从服务器保存到一个列表里面,然后按照以下规则,一项一项地对列表进行过滤:

  1)删除列表中所有处于下线或者断线状态的从服务器,保证列表中剩余的从服务器都是正常在线的

  2)删除列表中所有最近5秒内没有回复过领头Sentinel的INFO命令的从服务器,保证列表中剩余的从服务器都是最近成功进行过通信的

  3)删除所有与已下线主服务器连接断开超过down-after-milliseconds * 10毫秒的从服务器:down-after-milliseconds选项指定了判断主服务器下线所需的时间。这样做的目的是保证列表中剩余的从服务器都没有过早地与主服务器断开连接,换句话说,列表中剩余的从服务器保存的数据都是比较新的

  4)领头Sentinel将根据从服务器的优先级,对列表中剩余的从服务器进行排序,并选出优先级最高的从服务器。如果有多个具有相同最高优先级的从服务器,那么领头Sentinel将按照从服务器的复制偏移量,对具有相同最高优先级的所有从服务器进行排序,并选出偏移量最大的从服务器。因为偏移量最大,意味着保存的数据最新

  5)如果有多个优先级最高、复制偏移量最大的从服务器,那么领头Sentinel将按照运行ID对这些从服务器进行排序,并选出运行ID最小的从服务器

  Redis集群是Redis提供的分布式数据库方案,集群通过分片(sharding)来进行数据共享,并提供复制和故障转移功能。

  一个Redis集群通常通常由多个节点(node)组成,每个节点相互独立

  Redis集群通过分片的方式来保存数据库中的键值对:集群的整个数据库被分为16384个槽(slot),数据库中的每个键都属于这16384个槽的其中一个,集群中的每个节点都可以处理0个或最多16384个槽。给定键key属于哪个卡槽,会有一个公式来计算

  比如我们知道键msg所在的卡槽是节点A负责的,但是偏偏在节点B上发送set命令时,节点B会向客户端返回MOVED错误,指引客户端转向至节点A

  Redis集群的重新分片操作可以将任意数量已经指派给某个节点(源节点)的槽改为指派给另一个节点(目标节点),并且相关槽所属的键值对也会从源节点被移动到目标节点

  重新分片操作可以在线(online)进行,在重新分片的过程中,集群不需要下线,并且源节点和目标节点都可以继续处理命令请求

  在进行重新分片期间,源节点向目标节点迁移一个槽的过程中,可能会出现这样一种情况:属于被迁移槽的一部分键值对保存在源节点里面,而另一部分键值对则保存在目标节点里面。

  当客户端向源节点发送一个与数据库键有关的命令,并且命令要处理的数据库键恰好就属于正在被迁移的槽时:

  1)源节点会先在自己的数据库里查找指定的键,如果找到的话,就直接执行客户端发送的命令。

  2)相反地,如果源节点没能在自己的数据库里找到指定的键,那么这个键有可能已经被迁移到了目标节点,源节点将向客户端发送一个ASK错误,指引客户端转向正在导入槽的目标节点,并再次发送之前想要执行的命令

  注意和moved错误的区别,moved错误是客户端向节点发送一个关于槽i的命令,而槽i又没有指派给这个节点的话,那么节点将向客户端返回一个moved错误。但是如果节点正在导入槽i,并且发送命令的客户端带有REDIS_ACKING标识,那么节点将破例执行这个关于槽i的一次命令一次

  ASK错误和MOVED错误都会导致客户端转向,它们的的区别是:

  1)MOVED错误代表槽的负责权已经从一个节点转向了另一个节点,在客户端收到关于槽i的MOVED错误后,客户端每次遇到关于槽i的命令请求时,都可以直接将命令请求发送至MOVED错误所指向的节点,因为该节点就是目前负责槽i的节点

  2)与此相反,ASK错误只是两个节点在迁移槽的过程中使用的一种临时措施:在客户端收到关于槽i的ASK错误之后,客户端只会在接下来的一次命令请求中将关于槽i的命令请求发送至ASK错误所指示的节点,但这种转向不会对客户端今后发送关于槽i的命令请求产生任何影响,客户端仍会将关于槽i的命令请求发送至目前负责处理槽i的节点,除非ASK错误再次出现

  Redis集群中的节点分为主节点和从节点,比如集群中有3个主节点ABC,节点A下有2个从节点,那当节点A进入下线状态时,集群中仍在正常运作的几个主节点将在节点A的两个从节点中选出一个节点作为新的主节点,这个新的主节点将接管原来节点A负责处理的槽,并继续处理客户端发送的命令请求

  集群中的每个节点都会定期地向集群中的其它节点发送PING消息,以此来检测对方是否在线,如果接收PING消息的节点没有在规定的时间内,向发送PING消息的节点返回PONG消息,那么发送PING消息的节点就会将接收PING消息的节点标记为疑似下线

  如果在一个集群里面,半数以上负责处理槽的主节点都将某个主节点x报告为疑似下线,那么这个主节点x将被标记为已下线(FAIL),将主节点x标记为已下线的节点会向集群广播一条关于主节点x的FAIL消息,所有收到这条FAIL消息的节点都会立即将主节点x标记为已下线

  当一个从节点发现自己正在复制的主节点进入了已下线状态时,从节点将开始对下线主节点进行故障转移,以下是故障转移的执行步骤:

  1)复制下线主节点的所有从节点里面,会有一个从节点被选中

  2)被选中的从节点会执行SLAVEOF no one命令,成为新的主节点

  3)新的主节点会撤销所有对已下线主节点的槽指派,并将这些槽全部指派给自己

  4)新的主节点向集群广播一条PONG消息,这条PONG消息可以让集群中的其它节点立即知道这个节点已经由从节点变成了主节点,并且这个主节点已经接管了原本由已下线节点负责处理的槽

  5)新的主节点开始接收和自己负责处理的槽有关的命令请求,故障转移完成。

  集群选举新的主节点的方法如下:

  1)集群里每个负责处理槽的主节点都有一次投票的机会,而第一个向主节点要求投票的从节点将获得主节点的投票

  2)当从节点发现自己正在复制的主节点进入下线状态时,从节点会向集群广播一条消息,要求所有收到这条消息、并且具有投票权的主节点向这个从节点投票

  3)如果一个主节点具有投票权(它正在负责处理槽),并且这个主节点尚未投票给其它从节点,那么这个主节点将向要求投票的从节点返回一条ACK消息,表示这个主节点支持从节点成为新的主节点

  4)当一个从节点收集到大于等于N/2+1张支持票时,这个从节点就会当选为新的主节点。为什么要求N/2+1,因为具有大于等于N/2+1张支持票的从节点只会有一个,这确保了新的主节点只会有一个

  5)如果没有从节点能收集到足够多的支持票,那就再次进行选举,直到选出新的主节点为止

  这跟选举领头Sentinel的方法非常相似,因为两者都是基于Raft算法的领头选举

到此这篇redis 连接哨兵(redis连接哨兵命令)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • dtr英文缩写(英文缩写dtp的中文含义)2025-08-04 17:00:07
  • j flash(j flash报错 ram check fail)2025-08-04 17:00:07
  • rmsprop算法是自适应(rmsprop算法中文名)2025-08-04 17:00:07
  • TreeSize Free(treesize free安装出现错误)2025-08-04 17:00:07
  • archangel怎么读(archard怎么读)2025-08-04 17:00:07
  • swagger无法访问(swagger ui打不开)2025-08-04 17:00:07
  • nowcoder官网(nowcoderoj)2025-08-04 17:00:07
  • qpainter(Qpainter图层用法)2025-08-04 17:00:07
  • rmsprop算法是自适应(rls自适应滤波算法推导)2025-08-04 17:00:07
  • store苹果商店下载(app store苹果商店下载)2025-08-04 17:00:07
  • 全屏图片