前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >【redis】哨兵相关知识超详解(覆盖面试考点)

【redis】哨兵相关知识超详解(覆盖面试考点)

作者头像
椰椰椰耶
发布2025-03-28 11:12:38
发布2025-03-28 11:12:38
9800
代码可运行
举报
文章被收录于专栏:学习学习
运行总次数:0
代码可运行
  • 小结

Redis 的主从复制模式下,⼀旦主节点由于故障不能提供服务,需要⼈⼯进⾏主从切换,同时⼤量的客⼾端需要被通知切换到新的主节点上,对于上了⼀定规模的应⽤来说,这种⽅案是⽆法接受的,于是 Redis2.8 开始提供了 Redis Sentinel(哨兵)加个来解决这个问题。本章主要内容如下:

  • Redis Sentinel 的概念
  • Redis Sentinel 的部署
  • Redis Sentinel 命令
  • Redis Sentinel 客⼾端
  • Redis Sentinel 实现原理

基本概念

哨兵机制,是通过独立的进程来体现的,和之前的 redis server 是不同的进程

![[Pasted Image 20250323223036_347.png]]

  • redis-sentinel:不负责存储数据,只是对其他的 redis-server 进程起到监控作用
  • 通常哨兵节点也会搞一个集合(多个哨兵节点构成),避免单个哨兵挂了

人工恢复主节点故障

在实际开发中,对于服务器后端开发,监控程序是非常必要的

  • 服务器要求有比较高的可用性,7*24 运行
  • 服务器长期运行,总会有一些“意外”,具体什么时候出现意外,我们也不知道,同时,也不能全靠人工来盯着服务器运行
  • 我们就可以写一个程序,用程序来盯着服务器的运行状态——监控程序

往往还需要搭配“报警程序

  • 发现服务器的运行状态出现状态异常了
  • 给程序员报警,通知程序员,这个服务器挂了/出问题了(短信/电话/邮件/微信/钉钉/飞书…)

操作流程

image.png
image.png

运维人员通过监控系统,发现 redis 主节点故障宕机,程序员如何恢复?

  1. 先看看主节点还能不能抢救,好不好抢救
  2. 如果主节点这边是什么原因挂的,不好定位;或者原因知道,但是短时间内难以解决,就要挑一个从节点,设置为新的主节点
    1. 把选中的从节点,通过 slaveof no one,自立山头
    2. 把其他的从节点,修改 slaveof 的主节点 ip port,连上新的主节点
    3. 告知客户端(修改客户端配置),让客户端能够连接新的主节点,用来完成修改数据的操作
    • 当前的挂了的主节点,修好了之后,就可以作为一个新的从节点,挂到这组机器中

只要是涉及到人工干预,不说繁琐,至少很烦人。另外,这个操作过程如果出错了的话,可能会导致问题更加严重。通过人工干预的做法,就算程序员第一时间看到了报警信息,第一时间处理,也需要消耗较长时间

哨兵自动恢复主节点故障

image.png
image.png
  • 哨兵节点集合就是多个单独的 redis sentinel 进程(部署在三台不同的服务器上)
  • 并且这三个哨兵进程,就会监控现有的 redis masterslave
    • 监控:这些进程之间,会建立 TCP 长连接,通过这样的长连接,定期发送心跳包
  • 借助上述的监控机制,就可以及时发现某个主机是否挂了
    • 如果从节点挂了,其实没关系
    1. 如果可能是主节点挂了,哨兵就要发挥作用
      • 此时一个哨兵节点发现主节点挂了还不够,需要多个哨兵节点来共同认同这个事情(防止出现误判
    2. 主节点确实挂了,这些哨兵节点中,就会推举出一个 leader,由这个 leader 负责从现有的节点中,挑选一个作为新的主节点
    3. 挑选出新的主节点之后,哨兵节点就会自动控制该被选中的节点,执行 slaveof no one,并且控制其他从节点,修改 slaveof 到新的主节点上
    4. 哨兵节点会自动的通知客户端程序,告知新的主节点是谁,并且后续客户端再进行写操作,就会针对新的主节点进行操作了

redis 哨兵的核心功能:

  1. 监控
  2. 自动的故障转移
  3. 通知

哨兵集

redis 哨兵节点,有一个也是可以完场上述的需求的

但是:

  1. 如果哨兵节点只有一个,其自身也容易出现问题。万一这个哨兵节点挂了,redis 节点也挂了,就无法进行自动的恢复过程了
  2. 哨兵节点出现误判的概率也比较高。毕竟网络传输数据是很容易出现延迟或者丢包的,如果只有一个哨兵节点,出现上述问题之后,影响就比较大

哨兵节点最好是奇数个,所以最少也应该是 3 个

基本的原则:在分布式系统中,应该避免使用“单点”(冗余)

环境搭建

我们搭建的结构:

  • 一个主节点
  • 两个从节点
  • 三个哨兵节点
image.png|344
image.png|344

按理说,这六个节点是要要六个不同的服务器主机上。此时我们只有一个服务器,我们就在一个服务器上,来完成这里的环境搭建

  • 在实际工作中,把上述节点放在一个服务器上,是没有意义的(一个服务器挂了,就全军覆没了)

由于这些节点,还挺多的,相互之间容易大家,依赖的端口号/配置文件/数据文件… 如果我们直接部署,就需要小心翼翼的去避免这些冲突

  • 类似于前面配置主从结构的方式
  • 这样比较繁琐,也会和在不同主机上部署,存在较大差异(很多冲突都不用考虑)

docker

是什么

虚拟机:通过软件,在电脑上模拟出另外的一些硬件(构造了另一个虚拟的电脑)

  • 虚拟机这样的软件,就可以使用一个计算机,来模拟出多个电脑的情况
  • 但是虚拟机有一个很大的问题,比较吃配置,这个事情对于低配的云服务器来说,压力山大

相比之下,使用 docker 就可以有效的解决上述问题。

docker 可以认为是一个“轻量级”的虚拟机,起到了虚拟机这样的隔离环境的效果,但是又没有吃很多的硬件资源。即使是配置比较拉胯的服务器,也能构造出好几个这样的虚拟的环境

  • 这也是后端开发这块非常流行的组件
准备工作

https://www.runoob.com/docker/macos-docker-install.html

  1. 先安装 dockerdocker-compose 检查是否安装
代码语言:javascript
代码运行次数:0
运行
复制
docker --version

docker-compose --version
  1. 停止之前的 redis 服务器

避免之后出现一些冲突

  1. 使用 docker 获取到 redis 的镜像

docker 中的“镜像”和“容器”类似于“可执行程序“和“进程“的关系

  • 容器可以看做一个轻量级的虚拟机。
  • 镜像,可以自己构建,也可以直接拿别人已经构建好的
    • docker hub(github) 包含了很多其他大佬们构建好的镜像,也提供了 redis 官方提供的镜像,可以直接拖下来使用

获取 redis 镜像的命令:

代码语言:javascript
代码运行次数:0
运行
复制
docker pull redis:5.0.9
  • git pull 使用 git 从中央仓库拉取代码
  • docker pull 使用 docker 从中央仓库(默认就是从 docker hub)来拉取镜像
  • redis:5.0.9 是镜像的版本

拉取到的镜像,里面包含一个精简的 Linux 操作系统,并且上面会安装 redis。只要直接基于这个镜像创建一个容器跑起来,此时,redis 服务器就搭建好了

image.png
image.png
  • 此时就搭建好了 docker 的镜像,大小为 92.9MB

随后我们就基于这个 docker 镜像,搭建 redis 哨兵环境

网络问题

如果遇到网络问题,就要换一下国内的镜像仓库,加速

代码语言:javascript
代码运行次数:0
运行
复制
{
  "registry-mirrors": [
    "https://registry.docker-cn.com",
    "http://hub-mirror.c.163.com",
    "https://docker.mirrors.ustc.edu.cn",
    "https://dockerhub.azk8s.cn",
    "https://mirror.ccs.tencentyun.com",
    "https://registry.cn-hangzhou.aliyuncs.com",
    "https://docker.mirrors.ustc.edu.cn",
    "https://docker.1panel.live",
    "https://atomhub.openatom.cn/",
    "https://hub.uuuadc.top",
    "https://docker.anyhub.us.kg",
    "https://dockerhub.jobcher.com",
    "https://dockerhub.icu",
    "https://docker.ckyl.me",
    "https://docker.awsl9527.cn"
  ]

}
容器编排

此处我们直接用 docker-compose 来进行容器编排

  • 此处我们涉及到的多个 redis server,也有多个 redis 哨兵节点,每一个 redis server 或者每一个 redis 哨兵节点都是作为一个单独的容器了
  • 此处就有 6 个容器了,如果一个一个用 docker 手动创建容器,就比较麻烦,相比来说是用“容器编排”的方式就比较合理

容器编排就是,通过一个配置文件,把具体要创建哪些容器,每个容器运行的各种参数描述清楚。后续通过一个简单的命令,就能够批量的启动/停止这些容器了

  • 使用 yml 这样的格式来作为配置文件
文件格式

经典的配置文件格式:xml

代码语言:javascript
代码运行次数:0
运行
复制
<student>
	<id>1</id>
	<name>张三</name>
	<age>18</age>
</student>
  • <> 成对出现的,就叫做标签
  • html 中的标签,都是标准规定的
  • xml 里面的标签都是自定义的
    • 写起来特别啰嗦,并且也比较占用空间

后来又有了 JSON

代码语言:javascript
代码运行次数:0
运行
复制
{
	id: 1,
	name: '张三',
	age: 18
}

yml 格式和 json 有一些相似之处,yml 虽然没有 json 这么火,但是还是挺广泛的

代码语言:javascript
代码运行次数:0
运行
复制
student:
	id: 1
	name: "张三"
	age: 18
  • 它和 json 都是这种比较直观的键值对结构,json 是使用 {} 来表示层级结构,yml 则是使用缩进来表示

yml 相对于 json 的优势:对于格式要求更严格,可读性会更好,更有助于人来理解

编排步骤

分为两组 yml,先后启动

我们其实也可以用于一个 yml 文件,直接启动 6 个容器,但是:

  • 如果把这六个容器同时启动,可能是哨兵先启动完成,数据节点后启动完成,哨兵就可能会先认为是数据节点挂了
  • 虽然对大局不影响,但是会影响到观察执行日志的过程

搭建主从节点
  1. 创建三个容器,作为 redis 的数据节点(一主两从)
    • 这个名字不能改
    image.png|359
    image.png|359

将下面的配置复制进去

代码语言:javascript
代码运行次数:0
运行
复制
version: '3.7'
services:
  master:
    image: 'redis:5.0.9'
    container_name: redis-master
    restart: always
    command: redis-server --appendonly yes
    ports: 
      - 6379:6379
  slave1:
    image: 'redis:5.0.9'
    container_name: redis-slave1
    restart: always
    command: redis-server --appendonly yes --slaveof redis-master 6379
    ports:
      - 6380:6379
  slave2:
    image: 'redis:5.0.9'
    container_name: redis-slave2
    restart: always
    commandcommand: redis-server --appendonly yes --slaveof redis-master 6379
    ports:
      - 6381:6379
  • sevices:我们将要启动哪几个容器
    • masterslave1slave2 (这些名字自定义)
  • image:当前的容器是基于哪个镜像创建的
  • container_name:容器名字
  • restart异常情况终止后,是否重启
  • command:在启动 redis 服务器的时候,所用到的命令行选项
    • slaveof 后面不必写主节点 ip,直接写主节点的容器名就行了
    • 容器启动之后,被分配的 ip 是什么,也不知道
  • ports端口映射宿主机:容器内部端口
    • docker 容器可以理解成一个轻量的虚拟机。在这个容器里,端口号和外面宿主机的端口号,是两个体系。如果容器外面用了个 5000 端口,容器内也能用 5000 端口,并不冲突
    • 三个容器,每个容器的内部端口号都是自成一个小天地,容器 1 的 6379 和容器 2 的 6379 之间是不会有冲突的
    • 但是有时候,我们希望在容器外面能访问到容器里面的端口号,就可以把容器内部的端口映射成宿主机的端口。后续访问宿主机的这个端口,就相当于在访问对应容器的对应容器的对应端口了
    • 站在宿主的角度,访问上述几个端口的时候,也不知道这个端口实际上是一个宿主机上的服务,还是来自与容器内部的服务,只要正常去使用即可

这种映射过程,就非常像 NAT

  • 宿主机就像带有 NAT 功能的路由器,这个路由器能管理好几个局域网里面的机器
  • 正常来说,外面的没法访问局域网里面的设备,但是可以通过访问 NAT 设备上的某个端口,从而访问到局域网内部的某个设备的某个端口了
  1. 启动容器 使用命令
代码语言:javascript
代码运行次数:0
运行
复制
docker-compose up -d
image.png
image.png
image.png
image.png
image.png
image.png
  • 启动 6379 端口的 redis 服务器之后,可以看到这是个主节点,下面还有两个从节点
image.png
image.png
搭建哨兵节点
  1. 创建三个容器,作为 redis 的哨兵节点

redis 哨兵节点,是单独的 redis 服务器进程

  • 用哨兵节点,监控服务器进程
image.png
image.png

在哨兵节点的配置文件中,粘贴下面的配置

代码语言:javascript
代码运行次数:0
运行
复制
version: '3.7'
services:
  sentinel1:
    image: 'redis:5.0.9'
    container_name: redis-sentinel-1
    restart: always
    command: redis-sentinel /etc/redis/sentinel.conf
    volumes:
      - ./sentinel1.conf:/etc/redis/sentinel.conf
    ports:
      - 26379:26379
  sentinel2:
    image: 'redis:5.0.9'
    container_name: redis-sentinel-2
    restart: always
    command: redis-sentinel /etc/redis/sentinel.conf
    volumes:
      - ./sentinel2.conf:/etc/redis/sentinel.conf
    ports:
      - 26380:26379
  sentinel3:
    image: 'redis:5.0.9'
    container_name: redis-sentinel-3
    restart: always
    command: redis-sentinel /etc/redis/sentinel.conf
    volumes:
      - ./sentinel3.conf:/etc/redis/sentinel.conf
    ports:
      - 26381:26379
  • volumes:在当前目录下创建出 sentinel1.confsentinel2.confsentinel3.conf 这三个配置文件,然后把这三个配置文件映射到即将创建的这三个容器中
    • 哨兵节点,会在运行过程中,对配置文件进行自动修改。因此,就不能拿一个配置文件,给三个容器分别进行映射
  • portdocker 的一个核心功能,能够进行端口的映射,容器内部乐意使用什么端口都行,映射出去之后,还是需要确保端口不能重复
哨兵节点配置文件

我们看一下这三个配置文件的具体细节

  • 初始情况下,这三个配置文件内容可以是一样的
代码语言:javascript
代码运行次数:0
运行
复制
bind 0.0.0.0
port 26379
sentinel monitor redis-master redis-master 6379 2
sentinel down-after-milliseconds redis-master 1000
  • bind:绑定一个 ip 地址,允许其他端口进行访问
  • port:主节点端口号
  • sentinel monitor:告诉 redis 节点,去监控哪个服务器
    • 服务器名字,这里其实是 ip,但是使用 dockerdocker 会自动进行域名解析
    • 服务器端口号(容器外的)
    • 法定票数。哨兵节点需要去判定当前的 redis 是否挂了,超过法定票数个哨兵意见一致,才确认挂了(更稳健,避免网络波动的影响造成误判)
  • sentinel down-after-milliseconds:心跳包的超时时间。超过超时时间之后包还没回来,就认为是挂了

  1. 进行配置
image.png
image.png
  1. 启动容器 按照后台启动的方式启动
image.png
image.png

启动容器后,我们使用命令:

代码语言:javascript
代码运行次数:0
运行
复制
docker-compose logs
  • 查看日志,发现报错了:不能解析出主节点实例的主机名(此处哨兵节点不认识 redis-master
    • redis-master 相当于一个域名,docker 会进行域名解析,将其解析成对应容器的 ip(ip 可能会变,但是容器名字是不变的)

使用 docker-compose 一下,启动了 N 个容器,此时 N 个容器都处于同一个“局域网”中

  • 可以使这 N 个容器之间可以相互访问
  • 三个 redis-server 节点,是一个局域网;三个哨兵节点,是另一个局域网
  • 默认情况下,这两个网络是不互通的

解决方案: 可以使用 docker-compose 把此处的两组服务放到同一个局域网中

  • docker network ls 列出当前 docker 中的局域网
image.png|366
image.png|366
  • 此处先启动了三个 redis server 节点,就相当于自动创建了第一个局域网。再启动后面三个哨兵节点,就直接让这三个节点加入到上面的局域网中,而不是创建新的局域网

在刚刚的 yml 配置文件中,最后再加上

代码语言:javascript
代码运行次数:0
运行
复制
networks:
  default:
   	external:
   	  name: redis-data_default

完整配置为:

代码语言:javascript
代码运行次数:0
运行
复制
version: '3.7'
services:
  sentinel1:
    image: 'redis:5.0.9'
    container_name: redis-sentinel-1
    restart: always
    command: redis-sentinel /etc/redis/sentinel.conf
    volumes:
      - ./sentinel1.conf:/etc/redis/sentinel.conf
    ports:
      - 26379:26379
  sentinel2:
    image: 'redis:5.0.9'
    container_name: redis-sentinel-2
    restart: always
    command: redis-sentinel /etc/redis/sentinel.conf
    volumes:
      - ./sentinel2.conf:/etc/redis/sentinel.conf
    ports:
      - 26380:26379
  sentinel3:
    image: 'redis:5.0.9'
    container_name: redis-sentinel-3
    restart: always
    command: redis-sentinel /etc/redis/sentinel.conf
    volumes:
      - ./sentinel3.conf:/etc/redis/sentinel.conf
    ports:
      - 26381:26379
networks:
  default:
    external:
      name: redis-data_default
image.png
image.png

使用 docker network inspect redis-data_default 命令,可以查看 redis-data_default 网络被哪些容器连接

image.png
image.png

上述的操作,就完成了此处的配置


我们再打开 sentinel.conf 这三个配置问价,发现里面发生了变化

代码语言:javascript
代码运行次数:0
运行
复制
bind 0.0.0.0
port 26379
sentinel myid f1fd960a20a1ba19973fb8fee67b666e00b85f27
sentinel deny-scripts-reconfig yes
# Generated by CONFIG REWRITE
dir "/data"
sentinel monitor redis-master 172.18.0.2 6379 2
sentinel down-after-milliseconds redis-master 1000
sentinel config-epoch redis-master 0
sentinel leader-epoch redis-master 0
sentinel known-replica redis-master 172.18.0.3 6379
sentinel known-replica redis-master 172.18.0.4 6379
sentinel known-sentinel redis-master 172.18.0.7 26379 3437afc8086d37ea3204d3522a0640db2028e045
sentinel known-sentinel redis-master 172.18.0.6 26379 f1fd960a20a1ba19973fb8fee67b666e00b85f27
sentinel known-sentinel redis-master 172.18.0.5 26379 a6a389363f12cbb25085a22680575d297589c46a
sentinel current-epoch 0
  • 配置重写:这些是哨兵节点启动之后,自动进行修改的
  • 三个文件里面的具体信息都不一样

哨兵节点作用演示

哨兵存在的意义:能够在 redis 主从结构出现问题的时候(比如主节点挂了),此时哨兵节点就能帮我们选出一个主节点,来代替之前挂了的节点,保证整个 redis 仍然是可用状态

查看各节点状态 docker ps -a

image.png
image.png

模拟

我们模拟一下主节点挂了的情况。手动干掉主节点 docker stop redis-master

image.png
image.png
  • 当主节点挂了之后,哨兵节点就开始工作了
  • 我们看一下哨兵节点的日志
image.png
image.png
  1. 哨兵发现当前 redis-master 是一个 sdown 状态,于是开始投票
    • sdown:主观下线,本哨兵认为,主节点挂了(单方面)
  2. 出现 +odown 状态
    • +odown:客观下线,好几个哨兵都认为,主节点挂了,达成一致(法定票数)
    • 此时,这个主节点挂了的事情就石锤了
  3. 此时就需要哨兵节点选出一个从节点,作为新的主节点,此处就要提拔出一个新的主节点
    • switch:进行切换,从 0.2 切换到了 0.4

我们尝试练一下原来的主节点,端口号为:6379

image.png
image.png
  • 我们发现连接不上去(因为挂了)

再连一下 6380

image.png|418
image.png|418
  • 连上去后发现这个节点就是被提拔的主节点

再连一下 6381

image.png|325
image.png|325

我们重启原来的主节点 redis-master 之后

image.png
image.png
  • 此时还是从节点,他已经失去了主节点这个身份

哨兵重选主节点流程

#高频面试

1 . 主观下线

哨兵节点通过心跳包,判定 redis 服务器是否正常工作。如果心跳包没有如约而至,就说明 redis 服务器挂了

此时还不能排除网络波动的影响,因此就只能是单方面认为这个 redis 节点挂了

2 . 客观下线

多个哨兵都认为主节点挂了。认为挂了的哨兵数目达到法定票数,哨兵们就认为这个主节点是客观下线

是否可能出现非常严重的网络波动,导致所有的哨兵都联系不上 redis 主节点,误判成挂了呢?

  • 当然是有的。如果出现这个情况,怕是用户的客户端也连不上 redis 主节点了
  • 此时这个主节点基本也就无法正常工作了

“挂了”不一定是进程崩了,只要是无法正常访问,都可以视为是挂了

3 . 投出 leader

让多个哨兵节点,选出一个 leader 节点,由这个 leader 负责选出一个从节点作为新的主节点

image.png
image.png
  • 后面的编号,就是 sentinel1 的编号(在 conf 配置文件里面可以看到)
  • 1 号哨兵立即给自己投了一票,推举自己成为 leader
  • 三个哨兵都投给了哨兵 1
image.png
image.png
  • 成为 leader 是要为大家服务的,当 1 号哨兵说他想为大家服务的时候,2 和 3 可能是纷纷举手赞成的(谁发现客观下线,谁就先给自己投)
  • 每个哨兵手里只有一票,当哨兵 1 第一个发现当前是客观下线之后,就立即给自己投一票,并且告诉了 2 和 3(2 和 3 当他们没有投出这个票的时候,收到拉票请求,就会投出去。如果有多个拉票请求,就回投给最先到达的),我来负责。2 和 3 反应慢了半拍,才发现是客观下线,一看 1 乐意负责这个事情,就立即投了赞成票
  • 如果总的票数超过哨兵总数的一般,选举就完成了。哨兵个数设为奇数节点,就是为了方便投票

上面投票过程,就是看谁反应快(网络延时小)

4 . leader 挑选主节点

此时 leader 选举完毕,leader 就要挑选一个从节点,作为新的主节点

  1. 优先级:每个 redis 数据节点,都会在配置文件中,有一个优先级的设置
    • slave-priority,不去改就都是一样的
    • 优先级高的从节点就会胜出
  2. offset:优先级一样,谁的 offset 更大,就胜出
    • 从节点从主节点这边同步数据的进度。数值越大,就说明从节点的数据和主节点就越接近
  3. run id:优先级和 offset 都一样,选 run id 更小的(随机)
    • 每个 redis 节点启动的时候随机生成的一串数字,大小全凭缘分

把新的主节点指定好之后,leader 就会控制这个节点,执行 slave no one,成为 master,再控制其他节点,执行 slave of,让这些其他节点,以新的 master 作为主节点了

尤其是注意选举的过程。不是直接选出新的主节点,而是先选 leader,再由 leader 负责后续的主节点指定

小结

  • 哨兵节点不能只有一个,否则哨兵节点挂了可会影响系统可用性
  • 哨兵节点最好是奇数个,方便选举 leader,得票更容易超过半数
  • 哨兵节点不负责存储数据,仍然是 redis 主从节点负责存储
  • 哨兵+主从复制解决的问题是“提高可用性”,不能解决“数据极端情况下写丢失”的问题
  • 哨兵+主从复制不能提高数据的存储容量。当我们需要存的数据接近或者超过机器的物理内存,这样的结构就难以胜任了
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-03-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 基本概念
  • 人工恢复主节点故障
    • 操作流程
  • 哨兵自动恢复主节点故障
    • 哨兵集
  • 环境搭建
    • docker
      • 是什么
      • 准备工作
      • 容器编排
  • 哨兵节点作用演示
    • 模拟
  • 哨兵重选主节点流程
    • 1 . 主观下线
    • 2 . 客观下线
    • 3 . 投出 leader
    • 4 . leader 挑选主节点
  • 小结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档