《Redis设计与实现》阅读总结-3

第 12 章 事件

        Redis服务器是一个事件驱动程序,服务器需要处理两类事件:文件事件和时间事件

一、文件事件

1. 文件处理器:Redis基于Reactor模式开发了自己的网络事件处理器被称为文件处理器

  • 文件事件处理器使用I/O多路复用程序来同时监听多个套接字,并且根据套接字目前执行的任务来为套接字链接不同的事件处理器。
  • 当被监听的套接字准备好执行连接应答(accept)、取读(read)、写入(write)、关闭(close)等操作时,与操作相应的文件事件就会产生,这时事件处理器就会调用套接字之前关联好的事件处理器来处理这些事件。

2. 文件事件处理器的构成:

套接字、I/O多路复用程序、文件事件分派器(dispatcher),以及事件处理器

3. I/O多路复用程序的实现:

  • Redis的I/O多路复用程序的所有功能都是通过包装常见的select、epoll、evport和kqueue这些I/O多路复用函数来实现的,每个I/O多路复用函数库在Redis源码中都有一个单独文件。
  • Redis为每个I/O多路复用函数库都实现了相同的API,所以I/O多路复用程序的底层实现可以互换的。

4. 事件的类型: ae.h/AE_READABLE事件和ae.h/AE_WRITABLE事件:

  • 当套接字变得可读时(客户端对套接字执行 write或close操作),或者有新的可应答(acceptable)套接字出现时,客户端对服务器的监听套接字执行connect操作,套接字产生AE_READABLE事件。
  • 当套接字变得可写时(客户端对套接字执行read操作),套接字产生AE_WRITABLE事件。
  • Tips:I/O多路复用程序允许服务器同时监听套接字的AE_READABLE事件和AE_WRITABLE事件,如果一个套接字同时产生了这两种事件,那么文件事件分派器会优先处理AE_READABLE事件,等到 AE_READABLE事件处理完之后,才处理 AE_WRITABLE事件。服务器先读套接字,后写套接字。

5. API:

        见P154

6. 文件事件的处理器:

  • 应答处理器:为了对连接服务器的各个客户端进行应答,服务器要为监听套接字关联连接应答处理器。
  • 请求处理器:为了接收客户端传来的命令请求,服务器要为客户端套接字关联命令请求处理器。
  • 回复处理器:为了向客户端返回命令的执行结果,服务器要为客户端套接字关联命令回复处理器。
  • 复制处理器:当主服务器和从服务器进行复制操作时,主从服务器都需要关联特别为复制功能编写的复制处理器。

        在这些事件处理器里面,服务器最常用的:与客户端进行通信的连接应答处理器、命令请求处理器和命令回复处理器。

二、时间事件

1. 时间事件分类:

        定时事件、周期性事件

2. 时间事件组成:

  • id:服务器为时间事件创建的全局唯一ID(标识号)。ID号按从小到大的顺序递增,新事件的ID号比旧事件的ID号要大。
  • when:毫秒精度的UNIX时间戳,记录了时间事件的到达( arrive)时间。
  • timeProc:时间事件处理器,一个函数。当时间事件到达时,服务器就会调用相应的处理器来处理事件。

3. 时间事件是定时事件还是分时事件取决于时间事件处理器的返回值:

  • 如果事件处理器返回ae.h/ AE_NOMORE,那么这个事件为定时事件。该事件在达到一次之后就会被删除,之后不再到达。
  • 如果事件处理器返回一个非AE_NOMORE的整数值,那么这个事件为周期性时间。当一个时间事件到达之后,服务器会根据事件处理器返回的值。对时间事件的when属性进行更新,让这个事件在一段时间之后再次到达,并以这种方式一直更新并运行下去。比如说,如果一个时间事件的处理器返回整数值30,那么服务器应该对这个时间事件进行更新,让这个事件在30毫秒之后再次到达。

4. 实现:

        服务器将所有时间事件都放到一个无序链表中,每当时间事件执行器运行时,它就遍历整个链表,查询所有已经到达的时间事件,并调用相应的事件处理器。

5. API

        见P157

三、事件的调度与执行

四、重点回顾

  • Redis服务器是一个事件驱动程序,服务器处理的事件分为时间事件和文件事件两类。
  • 文件事件处理器是基于Reactor模式实现的网络通信程序。
  • 文件事件是对套接字操作的抽象:每次套接字变为可应答( acceptable)、可写(writable)或者可读( readable)时,相应的文件事件就会产生。
  • 文件事件分为AE_READABLE事件(读事件)和 AE_WRITABLE事件(写事件)两类。
  • 时间事件分为定时事件和周期性事件:定时事件只在指定的时间到达一次,而周期性事件则每隔一段时间到达一次
  • 服务器在一般情况下只执行servercron函数一个时间事件,并且这个事件是周期性事件。
  • 文件事件和时间事件之间是合作关系,服务器会轮流处理这两种事件,并且处理事件的过程中也不会进行抢占。
  • 时间事件的实际处理时间通常会比设定的到达时间晚一些。

第 13 章 客户端

一、相关知识点

  • Redis服务器是典型的一对多服务器应用程序。
  • Redis使用由I/O多路复用技术实现的文件事件处理器。
  • Redis服务器使用单线程单进程的方式处理命令请求。
  • 对于每个与服务器进行连接的客户端,服务器都为这些客户端建立相应的redis.h/redisClient结构(客户端状态),这个结构包括:
    • 客户端的套接字描述符。
    • 客户端的名字。
    • 客户端的标志值(fag)。
    • 指向客户端正在使用的数据库的指针,以及该数据库的号码。
    • 客户端当前要执行的命令、命令的参数、命令参数的个数,以及指向命令实现函数的指针。
    • 客户端的输入缓冲区和输出缓冲区。
    • 客户端的复制状态信息,以及进行复制所需的数据结构。
    • 客户端执行 BRPOP、 BLPOP等列表阻塞命令时使用的数据结构。
    • 客户端的事务状态,以及执行ATCH命令时用到的数据结构。
    • 客户端执行发布与订阅功能时用到的数据结构。
    • 客户端的身份验证标志。
    • 客户端的创建时间,客户端和服务器最后一次通信的时间,以及客户端的输出缓冲区大小超出软性限制( soft limit)的时间。

二、其他

        见P162-175

三、重点回顾

  • 服务器状态结构使用clents链表连接起多个客户端状态,新添加的客户端状态会被放到链表的末尾。
  • 客户端状态的flags属性使用不同标志来表示客户端的角色,以及客户端当前所处的状态。
  • 输入缓冲区记录了客户端发送的命令请求,这个缓冲区的大小不能超过1GB。
  • 命令的参数和参数个数会被记录在客户端状态的argv和argc属性里面,而cmd属性则记录了客户端要执行命令的实现函数。
  • 客户端有固定大小输出缓冲区和可变大小输出缓冲区两种缓冲区可用,,其中固定大小输出缓冲区的最大大小为16KB,而可变大小输出缓冲区的最大大小不能超过服务器设置的硬性限制值。
  • 输出缓冲区限制值有两种,如果输出缓冲区的大小超过了服务器设置的硬性限制,那么客户端会被立即关闭;除此之外,如果客户端在一定时间内,一直超过服务器设置的软性限制,那么客户端也会被关闭。
  • 当一个客户端通过网络连接连上服务器时,服务器会为这个客户端创建相应的客户端状态。网络连接关闭、发送了不合协议格式的命令请求、成为 LIENT KILL命令的目标、空转时间超时、输出缓冲区的大小超出限制,以上这些原因都会造成客户端被关闭。
  • 处理Lua脚本的伪客户端在服务器初始化时创建,这个客户端会一直存在,直到服务器关闭。
  • 载人AOF文件时使用的伪客户端在载入工作开始时动态创建,载入工作完毕之后关闭。

第 14 章 服务器

一、相关知识点

        Redis服务器负责与多个客户端建立网络连接,处理客户端发送的命令请求,在数据库中保存客户端执行命令所产生的数据,并通过资源管理来维持服务器自身的运转。

二、命令请求的执行过程

三、serverCron函数

        Redis服务器中的serverCron函数默认每隔100毫秒执行一次,这个函数负责管理服务器的资源。

四、初始化服务器

        见P193

五、还原数据库状态

  • 如果服务器开启AOF持久化功能,那么服务器使用AOF文件来还原数据库状态。
  • 如果服务器没有开启AOF持久化功能,那么服务器使用RDB文件来还原数据库状态。

六、执行事件循环

七、重点回顾

  • 一个命令请求从发送到完成主要包括以下步骤:
    • 1) 客户端将命令请求发送给服务器;
    • 2) 服务器读取命令请求,并分析出命令参数;
    • 3) 命令执行器根据参数查找命令的实现函数,然后执行实现函数并得出命令回复;
    • 4) 服务器将命令回复返回给客户端。
  • servercron函数默认每隔100毫秒执行一次,它的工作主要包括更新服务器状态信息,处理服务器接收的 SIGTERM信号,管理客户端资源和数据库状态,检查并执行持久化操作等等。
  • 服务器从启动到能够处理客户端的命令请求需要执行以下步骤:
    • 1) 初始化服务器状态;
    • 2) 载入服务器配置;
    • 3) 初始化服务器数据结构;
    • 4) 还原数据库状态;
    • 5) 执行事件循环。

第 15 章 复制

一、相关知识点

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

  • 同步操作用于将从服务器的数据状态更新至主服务器当前所处的数据库状态。
  • 命令传播操作则用于在主服务器的数据库状态被修改,导致主从服务器状态出现不一致时,让主从服务器的数据库重新回到一致状态。

二、同步

1. 从服务器对主服务器的同步操作主要痛向主服务器发送SYNC命令(老版本)、PSYNC命令(新版本)完成。

2. 主从服务器同步通信过程:

3. SYNC命令非常消耗资源:

4. PSYNC命令:

  • PSYNC命令具有完整重同步( full resynchronization)和部分重同步( partial resynchronization)两种模式:
    • 完整重同步用于处理初次复制情况:完整重同步的执行步骤和SYNC命令的执行步骤基本一样,它们都是通过让主服务器创建并发送RDB文件,以及向从服务器发送保存在缓冲区里面的写命令来进行同步。
    • 部分重同步则用于处理断线后重复制情况:当从服务器在断线后重新连接主服务器时,如果条件允许,主服务器可以将主从服务器连接断开期间执行的写命令发送给从服务器,从服务器只要接收并执行这些写命令,就可以将数据库更新至主服务器当前所处的状态。

5. PSYNC命令的部分重同步模式解决了旧版复制功能在处理断线后重复制时出现的低效情况。

6. PSYNC命令部分重同步的实现:

它由以下三个部分组成:

  • 主服务器的复制偏移量(replication offset)和从服务器的复制偏移量。

  • 主服务器的复制积压缓冲区(replication backlog),它是一个固定长度先进先出的队列,默认大小是1MB。

  • 服务器的运行ID(runID),
    • 无论主从服务器都会有自己的运行ID
    • 运行ID在服务器启动时自动生成,由40个随机的16进制字符组成。

7. PSYNC执行情况图:

三、命令传播

        在同步操作执行完毕之后,主从服务器两者的数据库将达到一致状态,但这种一致并不是一成不变的,每当主服务器执行客户端发送的鞋命令时,主服务器的数据库就有可能被修改,并导致主从服务器状态不再一致。为了让主从服务器再次回到一致状态,主服务需要对从服务器执行命令传播操作

四、复制的实现

        通过向从服务器发送SLAVEOF命令,我们可以让一个从服务器去复制一个主服务器。2.8以上版本的复制功能的详细实现步骤如下:

  • 设置主服务器的地址和端口
  • 建立套接字链接
  • 发送PING命令
  • 身份验证
  • 发送端口信息
  • 同步
  • 命令传播

五、心跳检测

1. 在命令传播阶段,从服务器会以每秒一次的频率,向主服务器发送命令:

REPLCONF ACK <replication_offset>

2. 发送 REPLCONF ACK命令的作用:

  • 检测主从服务器的网络连接状态。
  • 辅助实现min-slaves选项。

  • 检测命令丢失。如果因为网络故障,主服务器传播给从服务器的写命令在半路丢失,那么从服务器向主服务器发送REPLCONF ACK命令时,主服务器将发觉从服务器当前的复制偏移量少于自己的复制偏移量,然后主从服务器将少的数据重新发送给从服务器。

六、重点回顾

  • Redis2.8以前的复制功能不能高效地处理断线后重复制情况,但 Redis2.8新添加的部分重同步功能可以解决这个问题。
  • 部分重同步通过复制偏移量、复制积压缓冲区、服务器运行ID三个部分来实现。
  • 在复制操作刚开始的时候,从服务器会成为主服务器的客户端,并通过向主服务器发送命令请求来执行复制步骤,而在复制操作的后期,主从服务器会互相成为对方的客户端。
  • 主服务器通过向从服务器传播命令来更新从服务器的状态,保持主从服务器一致,而从服务器则通过向主服务器发送命令来进行心跳检测,以及命令丢失检测。

第 16 章 Sentinel(哨兵)

        Sentinel是Redis的高可用性(HA)解决方案:由一个或多个Sentinel实例组成的Sentinel系统可以监视任意多个主服务器,以及主服务器属下的所有从服务器,当被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器上级为主服务器。

一、启动初始化Sentinel:

1. 命令:

redis-sentinel ../sentinel.conf

redis-server ../sentinel.conf --sentinel

2. 步骤:

  • 初始化服务器
  • 将普通Redis服务器使用的代码替换成sentinel专用代码
  • 初始化Sentinel状态
  • 根据给定配置文件,初始化sentinel的监视主服务器列表。
  • 创建连向主服务器的网络连接。

3. 初始化服务器:

        Sentinel本质只是一个运行在特殊模式下得Redis服务器,所以启动Sentinel的第一步就是初始化一个普通的Redis服务器。

4. 使用Sentinel专用代码:

  • 端口改变:普通默认6379-->Sentinel默认26379
  • 服务器命令表改变:redisCommandTable --> sentinelcmds

5. 初始化Sentinel状态:

        服务器会初始化一个sentinel.c/sentinelState结构,这个结构保存了所有和Sentinel功能有关的状态。

6. 初始化sentinel状态的master属性:

  • Sentinel状态中的master字典记录了所有被Sentinel监视的主服务器相关信息:
    • 字典的键是被监视主服务的名字。
    • 字典的值是被监视主服务器对应的sentinel.c/sentinelRedisInstance结构

  • Sentinel状态的初始化将引发对master字典的初始化,而master字典的初始化是根据被载入的Sentinel的配置文件来进行的。

7. 创建连向主服务器的网络连接:

对于每个被Sentinel监视的主服务器来说,Sentinel会创建两个连向主服务器的异步网络连接:

  • 一个是命令连接,这个连接专门用于向主服务器发送命令,并接受命令回复。
  • 另一个是订阅连接,这个连接专门用于订阅主服务器的__sentinel__:hello频道。

二、获取主服务信息

  1. Sentinel默认会以每十秒一次的频率,通过命令连接向被监视的主服务发送INFO命令,并通过分析INFO命令的回复来获取主服务器的当前的信息。
  1. Sentinel通过分析主服务器返回的INFO命令回复,Sentinel可以获取以下两方面的信息:
  • 记录关于主服务器本身的信息,包括run_id域记录的服务器运行ID,以及role域记录的服务器角色。Sentinel根据这些信息将对主服务器的实例结构进行更新。
  • 记录主服务器属下所有从服务器的信息,Sentinel根据这些信息更新主服务器实例结构的slave字典中。

3. 主服务器实例结构和从服务器实例结构之间的区别:

  • 主服务器实例结构的flags属性的值为SRI_MASTER,而从服务器实例结构的flags属性的值为 SRI_SLAVE。
  • 主服务器实例结构的name属性的值是用户使用Sentinel配置文件设置的,而从服务器实例结构的name属性的值则是Sentinel根据从服务器的IP地址和端口号自动设置的。

三、获取从服务器信息:

  • 当Sentinel发现主服务器有更新的从服务器出现时,Sentinel除了会为这个新的从服务器创建相应的实例结构之外,Sentinel还会创建连接到从服务器的命令连接和订阅连接。

  • 在创建命令连接之后,Sentinel在默认情况下,会以每十秒钟一次的频率通过命令连接向从服务器发送INFO命令,获取如下内容回复:

四、向主服务器和从服务器发送信息

        在默认情况下,Sentinel会以每两秒钟一次的频率,通过命令连接向所有被监视的主服务器和从服务器发送以下格式命令:

PUNLISH __sentinel__:holle "<s_ip>,<s_port>,<s_runid>,<s_epoch>,<m_name>,<m_ip>,<m_port>,<m_epoch>"

五、接受来自主服务器和从服务器频道信息

  • 当Sentinel与一个主服务器或从服务器建立起订阅连接之后,Sentinel就会通过订阅连接,向服务器发送以下命令:
SUBSCRIBE __sentinel__:hello
  • Sentinel对 __sentinel__:hello频道的订阅会一直持续到Sentinel与服务器的连接断开为止。
  • Sentinel既通过命令向服务器的 __sentinel__:hello频道发送消息,又通过订阅连接从服务器的__sentinel__:hello频道中接收消息。

1. 更新sentinels字典:

  • sentinels字典数据结构:
    • 键:Sentinel的名字,格式为ip:port
    • 值:键所对应的Sentinel的实例结构。
  • sentinel字典(除了Sentinel本身之外的)保存所有同样监视这个主服务器的其他Sentinel的资料(当一个Sentinel接收到其他Sentinel发送的消息时,该Sentinel会提取Sentinel相关参数,保存或更新到sentinels字典)。

2. 创建连向其他Sentinel的命令连接:

当Sentinel通过频道信息发现一个新的Sentinel时,它不仅会为新Sentinel在sentinels字典中创建相应的实例结构,还会创建一个连向新Sentinel的命令连接,而新Sentinel也同样会创建连向这个Sentinel的命令连接,最终监视同一个主服务的多个Sentinel将形成相互连接的网络。

六、检测主观下线状态

  • 在默认情况下,Sentinel会以每秒一次的频率向所有与它创建了命令连接的实例(包括主服务器、从服务器、其他Sentinel在内)发送PING命令,并通过实例返回PING命令回复判断实例是否在线。
  • 实例对PING命令的回复可以分为一下两种:
    • 有效回复:实例返回+PONG、-LOADING、-MASTERDOWN三种回复的一种。
    • 无效回复:返回有效回复之外的其他回复或者名在指定时间内返回任何回复。

七、检测客观下线状态

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

1. 发送SENTINEL is-master-down-by-addr命令,询问其他Sentinel是否同意主服务器已下线:

SENTINEL is-master-down-by-addr <ip> <port> <current_epoch> <runid>

2. 接收SENTINEL is-master-down-by-addr命令:

Sentinel 接收SENTINEL is-master-down-by-addr命令后,会根据ip+端口号,检查主服务器是否已下线,然后向源Sentinel返回一条包含三个参数的Multi Bulk 回复:

3. 接收SENTINEL is-master-down-by-addr命令的回复:

        根据其他Sentinel发回的SENTINEL is-master-down-by-addr命令的回复,Sentinel将统计其他Sentinel同意主服务已下线的数量,当这个数量达到配置指定的判断客观下线所需的数量时,Sentinel会将主服务实例机构flags属性的SRI_O_DOWN标识打开,标识主服务器已经进入客观下线状态

八、选举领头Sentinel

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

以下Redis选举头领Sentinel的规则和方法:

  • 所有在线的Sentinel都有被选为领头Sentinel的资格。
  • 每次进行领头Sentinel选举之后,不论选举是否成功,所有Sentinel的配置纪元(configuration epoch) 的值都会自增一次。配置纪元实际上就是一个计数器,并没有什么特别的。
  • 在一个配置纪元里面,所有Sentinel都有一次将某个Sentinel设置为局部领头Sentinel的机会,并且局部领头一旦设置,在这个配置纪元里面就不能再更改。
  • 每个发现主服务器进入客观下线的Sentinel都会要求其他Sentinel将自己设置为局部领头 Sentinel。
  • 当一个 Sentinel(源 Sentinel)向另一个 Sentinel(目标 Sentinel)发送 SENTINEL is- master-down-by-addr命令,并且命令中的 runid参数不是 * 符号,而是源Sentinel的运行ID时,这表示源 Sentinel要求目标Sentinel将自己设置为目标Sentinel的局部领头Sentinel。
  • Sentinel设置局部领头Sentinel的规则是先到先得:最先向目标Sentinel发送设置要求的源Sentinel将成为目标Sentinel的局部领头Sentinel,而之后接收到的所有设置要求都会被目标Sentinel拒绝。
  • 目标Sentinel在接收到 SENTINEL is- master-down-by-addr命令之后,将向源 Sentinel返回一条命令回复,回复中的leader runid参数和leader epoch参数分别记录了目标Sentinel的局部领头Sentinel的运行ID和配置纪元。
  • 源 Sentinel在接收到目标 Sentinel返回的命令回复之后,会检查回复中leader epoch参数的值和自己的配置纪元是否相同,如果相同的话,那么源 Sentinel 继续取出回复中的leader runid参数,如果leader runid参数的值和源 Sentinel的运行ID一致,那么表示目标Sentinel将源Sentinel设置成了局部领头Sentinel。
  • 如果有某个Sentinel被半数以上的Sentinel设置成了局部领头Sentinel,那么这个Sentinel成为领头Sentinel。
  • 如果在给定时限内,没有一个 Sentinel被选举为领头Sentinel,那么各个 Sentinel将在一段时间之后再次进行选举,直到选出领头 Sentinel为止。

九、故障转移

        在选举产生领头Sentinel之后,领头Sentinel将对已下线的主服务执行故障转移操作,主要包括以下三个步骤:

  • 1)在已下线主服务器属下的所有从服务器里面,选择出一个从服务器,并将其转换为主服务器。
  • 2)让已下线主服务属下的所有从服务器改为复制新的主服务器。
  • 3)将已下线主服务器设置为新的主服务器的从服务器,当这个旧的主服务器重新上线时,他就会成为新的主服务器的从服务器。

1. 选择新的主服务器:

        选择一个状态良好、数据完整的从服务器,然后向这个从服务器发送SLAVEOF no one命令,将这个从服务器状态为主服务器。

2. 修改从服务器的复制目标:

        领头Sentinel通过向从服务器发送SLAVEOF命令实现修改从服务器的复制目标

3. 将旧的主服务器变为从服务器:

        因为旧的主服务器已经下线,所有这种设置是保存在server1对应的实例结构里面的,当sever1重新上线时,Sentinel就会向它发送SLAVEOF命令,让他成为server2的从服务器。

十、重点回顾

  • Sentinel只是运行在特殊模式下的Redis服务器,它使用了和普通模式不同的命令表,所有Sentinel模式能够使用的命令与普通Redis服务器能够使用的命令不同。
  • Sentinel会读入用户指定的配置文件,为每个要被监视的主服务器创建相应的实例结构,并创建连向主服务器的命令连接和订阅连接,其中命令连接用于向主服务器发送命令请求,而订阅连接则用于接收指定频道的消息。
  • Sentinel通过向主服务器发送INFO命令来获得主服务器属下所有从服务器的地址信息,并为这些从服务器创建相应的实例结构,以及连向这些从服务器的命令连接和订阅连接。
  • 在一般情况下, Sentinel以每十秒一次的频率向被监视的主服务器和从服务器发送INFO命令,当主服务器处于下线状态,或者 Sentinel正在对主服务器进行故障转移操作时, Sentinel向从服务器发送INFO命令的频率会改为每秒一次。
  • 对于监视同一个主服务器和从服务器的多个 Sentinel来说,它们会以每两秒一次的频率,通过向被监视服务器的 __sentinel__:hello频道发送消息来向其他Sentinel宣告自己的存在。
  • 每个 Sentinel也会从__sentinel__:hello 频道中接收其他Sentinel发来的信息,并根据这些信息为其他 Sentinel创建相应的实例结构,以及命令连接。
  • Sentinel只会与主服务器和从服务器创建命令连接和订阅连接, Sentinel与 Sentinel 之间则只创建命令连接。
  • Sentinel以每秒一次的频率向实例(包括主服务器、从服务器、其他 Sentinel)发送PING命令,并根据实例对PING命令的回复来判断实例是否在线,当一个实例在指定的时长中连续向Sentinel发送无效回复时, Sentinel 会将这个实例判断为主观下线。
  • 当 Sentinel 将一个主服务器判断为主观下线时,它会向同样监视这个主服务器的其他Sentinel进行询问,看它们是否同意这个主服务器已经进入主观下线状态。
  • 当 Sentinel收集到足够多的主观下线投票之后,它会将主服务器判断为客观下线,并发起一次针对主服务器的故障转移操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/747901.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

electron线上跨域问题

一、配置background.js win new BrowserWindow({webPreferences: {nodeIntegration: true, // 使渲染进程拥有node环境//关闭web权限检查&#xff0c;允许跨域webSecurity: false,// Use pluginOptions.nodeIntegration, leave this alone// See nklayman.github.io/vue-cli-p…

win11系统重装?正版系统Windows11安装重启!保姆级重装系统攻略!

随着科技的不断发展&#xff0c;Windows 11系统已经逐渐成为了众多电脑用户的新选择。然而&#xff0c;当当电脑出现严重故障、受到病毒攻击、软件冲突、系统升级失败、硬件更换或升级、系统性能下降或个性化需求等情况时&#xff0c;重装系统可能是一个有效的解决方案。本文将…

江协科技51单片机学习- p16 矩阵键盘

&#x1f680;write in front&#x1f680; &#x1f50e;大家好&#xff0c;我是黄桃罐头&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​…

武汉星起航:跨境电商浪潮下,中国卖家扬帆出海,书写国际新篇章

随着全球化进程的加速和互联网技术的飞速发展&#xff0c;跨境出口电商模式已成为中国卖家海外拓展的重要渠道。这一模式不仅为商家带来了巨大的市场机遇&#xff0c;更为中国卖家在全球舞台上展示其独特魅力和竞争力提供了宝贵平台。武汉星起航将从多个维度探讨中国卖家海外发…

基于 GD32F450 的Zephyr 的基本测试-编译工程

一、cmake 编译 hello world 测试 打开示例工程 hello world cd ~/zephyrproject/zephyr/samples/hello_world新建 build 目前&#xff0c;用于存放临时文件目录&#xff0c;并进入该目录 mkdir -p build && cd build通过 cmake 指令 生成 gd32f450z 工程的 makefil…

聚观早报 | 小鹏MONA M03曝光;iPhone 16系列电池改进

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。 整理丨Cutie 6月25日消息 小鹏MONA M03曝光 iPhone 16系列电池改进 一加Ace 3 Pro三款配色 字节跳动与博通合作开发AI芯片 蚂…

【efinix】efinity如何安装官方补丁patch

efinix官网可以下载efinity的官方补丁。 下载 efinity-2023.2.307.5.10-windows-x64-patch.zip 解压缩补丁zip 压缩包内容 files/ : updated files to be copied into the Efinity installation run.sh : patch installation script (Linux on…

Open3D 显示带有强度的点云数据

目录 一、概述 1.1强度信息的意义 1.2应用场景 二、代码实现 三、实现效果 一、概述 在点云数据中&#xff0c;强度&#xff08;Intensity&#xff09;指的是激光雷达传感器在扫描环境时&#xff0c;每个点返回的反射强度值。这些强度值代表了激光脉冲返回的能量&#xff…

python目录树生成器

代码如下&#xff1a; import os from colorama import Fore, Style, init from tkinter import Tk, Label, Entry, Button, Text, Scrollbar, RIGHT, Y, END# 初始化 colorama init(autoresetTrue)def print_directory_tree(root_dir, text_widget, indent, lastTrue):"…

Qt Quick Effect Maker 工具使用介绍

一、介绍 随着 Qt 版本的不断升级,越来越多的功能被加入 Qt,一些新的工具也随之应运而生,Qt Quick Effect Maker 工具是 Qt 6.5 之后才新添加的工具,之前的名字应该是叫做 Qt shader tool 这个模块。 以下是官方的释义:Qt Quick Effect Maker是一个用于为Qt Quick创建自定…

SpringAOP执行流程——从源码画流程图

文章目录 了解ProxyFactory入门操作添加多个Advice的执行顺序关于异常Advice关于proceed()方法指定方法才进行增强逻辑 创建代理对象的其他方式ProxyFactoryBeanBeanNameAutoProxyCreatorDefaultAdvisorAutoProxyCreator 对SpringAOP的理解TargetSourceProxyFactory选择JDK/CJL…

安卓免费短剧大全v1.0.2/全部无需VIP实时更新全平台短剧

在当今社会&#xff0c;时间成为了许多人最为宝贵的资源。忙碌的工作与繁重的日常事务&#xff0c;常常让我们难以拨出时间沉浸于长篇大幅的影视作品中。对于那些热爱剧情、渴望在生活中点缀一抹戏剧色彩的朋友们而言&#xff0c;这无疑是一种挑战。 然而&#xff0c;随着免费…

Ubuntu挂载window的网络共享文件夹爱

1.进入win10创建一个用户smb密码也是smb 2.右键进入文件夹共享 3.进入Ubuntu安装支持cifs-utils sudo apt update sudo apt install cifs-utils 4.sudo mkdir /mnt/shared 5.挂载&#xff1a; sudo mount -t cifs -o usernamesm bpasswordsmb //172.16.11.37(windowsIP)/s…

C语言学习记录20240626

飞船无论朝哪边行驶&#xff0c;都能通过结构体记录获取它的初始坐标、转向角度和在该方向行进的距离&#xff0c;需要根据这些信息计算飞船移动后的坐标。 向量(vector)指具有大小(magnitude)和方向(direction)的量&#xff0c;可以理解为有方向的线段。 标量或纯量(scalar)指…

甲子光年专访天润融通CEO吴强:客户经营如何穿越低速周期?

作者&#xff5c;陈杨、编辑&#xff5c;栗子 社会的发展从来都是从交流和联络开始的。 从结绳记事到飞马传信&#xff0c;从电话电报到互联网&#xff0c;人类的联络方式一直都在随着时代的发展不断进步。只是传统社会通信受限于技术导致效率低下&#xff0c;对经济社会产生影…

明星周边物品交易购物系统

摘 要 随着明星文化的兴起和粉丝经济的蓬勃发展&#xff0c;明星周边产品的市场需求日益增长。明星周边物品包括各种与明星相关的商品&#xff0c;如T恤、海报、手办、签名照等&#xff0c;它们成为粉丝们表达对明星喜爱和支持的方式之一。通过“星光璀璨”来形象化地表达明星…

创意设计师,如何在AIGC时代寻找价值?

在当今AIGC&#xff08;人工智能生成内容&#xff09;时代&#xff0c;技术的浪潮席卷了各个行业&#xff0c;创意设计领域也不例外。对于创意设计师来说&#xff0c;这既是一个充满挑战的时代&#xff0c;也是一个蕴藏无限机遇的时代。在这个时代背景下&#xff0c;如何寻找并…

高校心理咨询管理系统

摘 要 随着高校学生心理问题的增多&#xff0c;心理咨询服务在高校中的重要性日益凸显。然而&#xff0c;传统的心理咨询管理方式存在着诸多问题&#xff0c;如信息不透明、咨询师资源不足等。为了解决这些问题&#xff0c;本文设计并实现了一种基于Java Web的高校心理咨询管理…

AutoEncoder简介

1.介绍 作为一种无监督或者自监督算法&#xff0c;自编码器本质上是一种数据压缩算法。 编码器&#xff1a; 输入图像&#xff08;在这个例子中是一个28x28像素的数字“9”&#xff09;首先被输入到编码器中。编码器的任务是将这个输入压缩成一个更小的、密集的表示形式&…

Linux系统安装Lua语言及Lua外部库

安装Lua Lua语言是一种轻量级、高效且可扩展的脚本语言&#xff0c;具有简洁易学的语法和占用资源少的特点。它支持动态类型&#xff0c;提供了丰富的表达式和运算符&#xff0c;同时具备自动垃圾回收机制和跨平台性。Lua语言易于嵌入到其他应用程序中&#xff0c;并可与其他语…