前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >【redis】集群 主节点宕机后选择 master 的详细流程

【redis】集群 主节点宕机后选择 master 的详细流程

作者头像
椰椰椰耶
发布2025-03-29 10:01:02
发布2025-03-29 10:01:02
6400
代码可运行
举报
文章被收录于专栏:学习学习
运行总次数:0
代码可运行

使用集群

此时,使用客户端连上集群中的任何一个节点,都相当于连上了整个集群

  • 101-109 这个九个节点,是一个整体

可以通过 cluster nodes 查看整个集群的情况

image.png
image.png
  • 前面的 6379 是业务端口,后面的 16379 是管理端口
  • myself:我们刚才客户端连上的节点
  • 还可以根据 id 看到主从关系
  • 还可以看到槽位

存储数据

前面学到的所有 redis 命令,在这里都是适用的

image.png
image.png
  • 设置成集群模式之后,当前数据就分片了。k1 这个 key 通过 hash 计算之后,得到 slot 12706,属于 103 这个分片,但我们是在 101 上进行的操作
  • 我们可以在启动 redis-cli 的时候,加上 -c 选项
    • 此时客户端发现当前 key 的操作不在当前分片上的时候,就能够自动的重定向到对应的分片主机
image.png
image.png
  • 此时就触发了重定向,槽位号还是 12706
  • 客户端直接把请求转发给了 103

-c 选项添加后,redis 客户端就会根据当前 key 实际算出来的槽位号,自动找到匹配的分配主机,进一步的就可以完成操作

使用集群之后,之前学过的命令,都能正常使用(不够严谨)

  • 有些指令,是能操作多个 key 的,此时如果 key 是分散在不同的分片上,就可能出现问题了
image.png
image.png

有特殊的方式,可以解决上述问题—— hash tag

节点宕机

  • 如果是从节点挂了,没事
  • 如果是主节点挂了,就摊上事了
    • 主节点才能处理写操作,而从节点不能写

当我们尝试在从节点上写操作的时候,就会自动的被重定向到指定的主节点上

image.png
image.png
  • 主节点要是挂了,就没法写了,就出问题了

此处,集群做的工作,就和之前哨兵做的类似,会自动把该主节点旗下从节点,给挑出一个,提拔成主节点

image.png
image.png
  • 之前的时候 101 是主节点,105106 是他的从节点。在 101 挂了之后,106 成了新的主节点,代替了原来 101 的位置
  • 与此同时,105 就成了 106 的从节点了

在重启 redis1 之后,发现其还是从节点,身份恢复不了

image.png
image.png

集群机制,也能处理故障转移

  • 不过此处的故障转移处理流程和哨兵处理流程不一样

故障转移流程

1. 故障判断

识别出某个节点是否挂了

  1. 节点 A 个节点 B 发送 ping 包,B 就会给 A 返回一个 pong 包。pingpong 除了 message type 属性之外,其他部分都是一样的。这里包含了集群的配置信息(该节点 id,该节点从属于哪个分片,是主节点还是从节点,从属于谁,持有哪些 slots 的位图…)
  2. 每个节点,每秒钟,都会给一些随机的节点发起 ping 包,而不是全发一遍。这样设定是为了避免在节点很多的时候,心跳包也非常多(比如有 9 个节点,如果全发,就是 9 * 872 组心跳了,而且这是按照 N^2 这样的级别增长的)
  3. 当节点 A 给节点 B 发起 ping 包,B 不能如期回应的时候,此时 A 就会尝试重置和 B 的 TCP 连接,看能否连接成功。如果连接失败,A 就会把 B 设为 PFAIL 状态(相当于主观下线
    • 判定某个节点是否挂了,不能只听信“一面之词”
  4. A 判定 B 为 PFAIL 之后,会通过 redis 内置的 Gossip 协议,和其他节点确认 B 的状态(每个节点都会维护一个自己的“下线列表”,由于视角不同,每个节点的下线列表也不一定相同)
  5. 此时 A 发现其他很多节点,也认为 B 为 PFAIL,并且数目超过总集群个数的一般,那么 A 就会把 B 标记成 FAIL(相当于客观下线),并且把这个消息同步给其他节点(其他节点收到之后,也会把 B 标记成 FAIL

B 是否下面,就已经明确了

2. 故障迁移
  • 如果 B 是从节点,那么不需要进行故障迁移
  • 如果 B 是主节点,那么就会由 B 的从节点(比如 C 和 D)触发故障迁移了

  1. 从节点判定自己是否具有参选资格。如果从节点和主节点已经太久没通信(此时认为从节点的数据和主节点差异太大了),时间超过阈值,就失去竞选资格
    • 很久没通信,就是很久没同步过数据了,从节点的数据和主节点相比,估计差异比较大了
  2. 具有资格的节点,比如 C 和 D,就会先休眠一定时间
    • 休眠时间 = 500ms 基础时间 + [0, 500ms]随机时间 + 排名 * 1000ms
    • offset 的值越大,数据就越接近主节点,排名越靠前,休眠时间就越短
  3. 比如 C 的休眠时间到了,C 就会给其他所有集群的节点,进行拉票操作。但是只有主节点才有投票资格
  4. 主节点就会把自己的票投给 C(每个主节点只有 1 票)。当 C 收到的票超过主节点数目的一半,C 就会晋升成主节点(C 自己负责执行 slaveof no one,并且让 D 执行 slaveof C
  5. 同时,C 还会把自己成为主节点的消息,同步给其他集群的节点,大家也都会更新自己保存的集群结构信息

谁休眠时间短,大概率就是新的主节点了

上述选举的过程,称为 Raft 算法,是一种在分布式系统中广泛使用的算法

  • 哨兵中,是先竞选出 leader,然后 leader 负责找一个从节点,升级成主节点
  • 这里是直接投片选出新的主节点

集群宕机

以下三种情况会出现集群宕机:

  • 某个分片,所有的主节点和从节点都挂了
    • 该分片就无法提供数据服务了
  • 某个分片,主节点挂了,但是没有从节点
  • 超过半数的 master 节点都挂了
    • 如果突然一系列的 master 都挂了,此时说明集群遇到了非常严重的情况。此时就得赶紧停下来,检查检查是不是有什么问题

如果集群中有个节点挂了,无论是什么节点,程序员都要尽快处理好

集群扩容

101-109 九个主机,构成了三主六从结构的集群了。现在将 110111 也加入到集群中,以 110master111slave

  • 把数据分片从三变为四

集群扩容操作,是一件风险较高,成本较大的操作

1. 将新主节点加入到集群

命令:

代码语言:javascript
代码运行次数:0
运行
复制
redis-cli --cluster add-node 172.30.0.110:6379 172.30.0.101:6379
  • 第一个 IP 指被新增的节点是什么
  • 第二个 IP 指集群上的任意一个节点,表示要把新节点加到哪个集群中
image.png|394
image.png|394
image.png
image.png
  • 原来的那些 master,都有响应的 slots。但是新增的这个,没有 slots
    • 需要我们手动进行分配

2. 分配 slots

把之前三组 master 上面的 slots 拎出来一些,分配给新的 master

代码语言:javascript
代码运行次数:0
运行
复制
redis-cli --cluster reshard 172.30.0.101:6379
  • IP 是任意的一个节点的
image.png|459
image.png|459

此处会先打印出当前集群每个机器的情况,并且要求用户输入要移动多少个 slots

  1. 四个分片,一共是 16384 个,除 4 得到的就是 4096
  2. 然后会询问让哪个节点来接收,粘贴对应主机的 ID
  3. 输入要从哪些节点来移动 slots
    1. all,表示从其他每个持有 slotsmaster 都拿过来点
    2. 手动指定,从某一个或者某几个节点来移动 slots(以 done 为结尾)
  4. 输入 all 之后,会给出一个搬运的计划(还没真正开始搬运),当程序员输入 yes 之后,搬运真正开始
    • 此时不仅仅是 slots 重新划分,也会把 slots 上对应的数据,也搬运到新的主机上
image.png
image.png
  • 此时可以看到新增的主节点分配到了 slots

如果在搬运 slots / key 的过程中,此时客户端能否访问 redis 集群呢?

  • 搬运 key 这个过程,大部分 key 是不用搬运的。针对这些未搬运的 key,此时可以正常访问,针对这些正在搬运中的 key,是可能会出现访问出错的情况
  • 假设客户端访问 k1,集群通过分片算法,得到 k1 是第一个分片的数据,就会重定向到第一个分片的节点,就可能在重定向过去之后,正好 k1 被搬走了,自然就无法访问了

3. 将从节点加入到集群

代码语言:javascript
代码运行次数:0
运行
复制
redis-cli --cluster add-node 172.30.0.111:6379 172.30.0.101:6379 --clusterslave --cluster-master-id [172.30.1.110 节点的 nodeId]
image.png
image.png

执行完毕后,就添加完成了

image.png
image.png

小结

  1. 集群是什么?解决了什么问题?
  2. 数据分片算法(面试重点
    1. 哈希求余
    2. 一致性哈希算法
    3. 哈希槽分区算法(redis 使用的方式)
  3. 搭建一个 redis 集群
  4. 集群容灾,故障转移
  5. 集群扩容
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-03-28,如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 使用集群
  • 存储数据
  • 节点宕机
    • 故障转移流程
      • 1. 故障判断
      • 2. 故障迁移
  • 集群宕机
  • 集群扩容
    • 1. 将新主节点加入到集群
    • 2. 分配 slots
    • 3. 将从节点加入到集群
  • 小结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档