admin管理员组文章数量:1033944
【redis】集群 主节点宕机后选择 master 的详细流程
使用集群
此时,使用客户端连上集群中的任何一个节点,都相当于连上了整个集群
- 从
101-109
这个九个节点,是一个整体
可以通过 cluster nodes
查看整个集群的情况
- 前面的
6379
是业务端口,后面的16379
是管理端口 myself
:我们刚才客户端连上的节点- 还可以根据
id
看到主从关系 - 还可以看到槽位
存储数据
前面学到的所有 redis
命令,在这里都是适用的
- 设置成集群模式之后,当前数据就分片了。
k1
这个key
通过hash
计算之后,得到slot 12706
,属于103
这个分片,但我们是在101
上进行的操作 - 我们可以在启动
redis-cli
的时候,加上-c
选项- 此时客户端发现当前
key
的操作不在当前分片上的时候,就能够自动的重定向到对应的分片主机
- 此时客户端发现当前
- 此时就触发了重定向,槽位号还是
12706
- 客户端直接把请求转发给了
103
-c
选项添加后,redis
客户端就会根据当前 key
实际算出来的槽位号,自动找到匹配的分配主机,进一步的就可以完成操作
使用集群之后,之前学过的命令,都能正常使用(不够严谨)
- 有些指令,是能操作多个
key
的,此时如果key
是分散在不同的分片上,就可能出现问题了
有特殊的方式,可以解决上述问题——
hash tag
节点宕机
- 如果是从节点挂了,没事
- 如果是主节点挂了,就摊上事了
- 主节点才能处理写操作,而从节点不能写
当我们尝试在从节点上写操作的时候,就会自动的被重定向到指定的主节点上
- 主节点要是挂了,就没法写了,就出问题了
此处,集群做的工作,就和之前哨兵做的类似,会自动把该主节点旗下从节点,给挑出一个,提拔成主节点
- 之前的时候
101
是主节点,105
和106
是他的从节点。在101
挂了之后,106
成了新的主节点,代替了原来101
的位置 - 与此同时,
105
就成了106
的从节点了
在重启 redis1
之后,发现其还是从节点,身份恢复不了
集群机制,也能处理故障转移
- 不过此处的故障转移处理流程和哨兵处理流程不一样
故障转移流程
1. 故障判断
识别出某个节点是否挂了
- 节点 A 个节点 B 发送
ping
包,B 就会给 A 返回一个pong
包。ping
和pong
除了message type
属性之外,其他部分都是一样的。这里包含了集群的配置信息(该节点 id,该节点从属于哪个分片,是主节点还是从节点,从属于谁,持有哪些slots
的位图…) - 每个节点,每秒钟,都会给一些随机的节点发起
ping
包,而不是全发一遍。这样设定是为了避免在节点很多的时候,心跳包也非常多(比如有9
个节点,如果全发,就是9 * 8
有72
组心跳了,而且这是按照N^2
这样的级别增长的) - 当节点 A 给节点 B 发起
ping
包,B 不能如期回应的时候,此时 A 就会尝试重置和 B 的TCP
连接,看能否连接成功。如果连接失败,A 就会把 B 设为PFAIL
状态(相当于主观下线)- 判定某个节点是否挂了,不能只听信“一面之词”
- A 判定 B 为
PFAIL
之后,会通过redis
内置的Gossip
协议,和其他节点确认 B 的状态(每个节点都会维护一个自己的“下线列表”,由于视角不同,每个节点的下线列表也不一定相同) - 此时 A 发现其他很多节点,也认为 B 为
PFAIL
,并且数目超过总集群个数的一般,那么 A 就会把 B 标记成FAIL
(相当于客观下线),并且把这个消息同步给其他节点(其他节点收到之后,也会把 B 标记成FAIL
)
B 是否下面,就已经明确了
2. 故障迁移
- 如果 B 是从节点,那么不需要进行故障迁移
- 如果 B 是主节点,那么就会由 B 的从节点(比如 C 和 D)触发故障迁移了
- 从节点判定自己是否具有参选资格。如果从节点和主节点已经太久没通信(此时认为从节点的数据和主节点差异太大了),时间超过阈值,就失去竞选资格
- 很久没通信,就是很久没同步过数据了,从节点的数据和主节点相比,估计差异比较大了
- 具有资格的节点,比如 C 和 D,就会先休眠一定时间
休眠时间 = 500ms 基础时间 + [0, 500ms]随机时间 + 排名 * 1000ms
offset
的值越大,数据就越接近主节点,排名越靠前,休眠时间就越短
- 比如 C 的休眠时间到了,C 就会给其他所有集群的节点,进行拉票操作。但是只有主节点才有投票资格
- 主节点就会把自己的票投给 C(每个主节点只有 1 票)。当 C 收到的票超过主节点数目的一半,C 就会晋升成主节点(C 自己负责执行
slaveof no one
,并且让 D 执行slaveof C
) - 同时,C 还会把自己成为主节点的消息,同步给其他集群的节点,大家也都会更新自己保存的集群结构信息
谁休眠时间短,大概率就是新的主节点了
上述选举的过程,称为
Raft
算法,是一种在分布式系统中广泛使用的算法
- 哨兵中,是先竞选出
leader
,然后leader
负责找一个从节点,升级成主节点 - 这里是直接投片选出新的主节点
集群宕机
以下三种情况会出现集群宕机:
- 某个分片,所有的主节点和从节点都挂了
- 该分片就无法提供数据服务了
- 某个分片,主节点挂了,但是没有从节点
- 超过半数的
master
节点都挂了- 如果突然一系列的
master
都挂了,此时说明集群遇到了非常严重的情况。此时就得赶紧停下来,检查检查是不是有什么问题
- 如果突然一系列的
如果集群中有个节点挂了,无论是什么节点,程序员都要尽快处理好
集群扩容
101-109
九个主机,构成了三主六从结构的集群了。现在将 110
和 111
也加入到集群中,以 110
为 master
,111
为 slave
- 把数据分片从三变为四
集群扩容操作,是一件风险较高,成本较大的操作
1. 将新主节点加入到集群
命令:
代码语言:javascript代码运行次数:0运行复制redis-cli --cluster add-node 172.30.0.110:6379 172.30.0.101:6379
- 第一个 IP 指被新增的节点是什么
- 第二个 IP 指集群上的任意一个节点,表示要把新节点加到哪个集群中
- 原来的那些
master
,都有响应的slots
。但是新增的这个,没有slots
- 需要我们手动进行分配
2. 分配 slots
把之前三组 master
上面的 slots
拎出来一些,分配给新的 master
redis-cli --cluster reshard 172.30.0.101:6379
- IP 是任意的一个节点的
此处会先打印出当前集群每个机器的情况,并且要求用户输入要移动多少个 slots
- 四个分片,一共是
16384
个,除4
得到的就是4096
- 然后会询问让哪个节点来接收,粘贴对应主机的
ID
- 输入要从哪些节点来移动
slots
all
,表示从其他每个持有slots
的master
都拿过来点- 手动指定,从某一个或者某几个节点来移动
slots
(以done
为结尾)
- 输入
all
之后,会给出一个搬运的计划(还没真正开始搬运),当程序员输入yes
之后,搬运真正开始- 此时不仅仅是
slots
重新划分,也会把slots
上对应的数据,也搬运到新的主机上
- 此时不仅仅是
- 此时可以看到新增的主节点分配到了
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]
执行完毕后,就添加完成了
小结
- 集群是什么?解决了什么问题?
- 数据分片算法(面试重点)
- 哈希求余
- 一致性哈希算法
- 哈希槽分区算法(redis 使用的方式)
- 搭建一个
redis
集群 - 集群容灾,故障转移
- 集群扩容
【redis】集群 主节点宕机后选择 master 的详细流程
使用集群
此时,使用客户端连上集群中的任何一个节点,都相当于连上了整个集群
- 从
101-109
这个九个节点,是一个整体
可以通过 cluster nodes
查看整个集群的情况
- 前面的
6379
是业务端口,后面的16379
是管理端口 myself
:我们刚才客户端连上的节点- 还可以根据
id
看到主从关系 - 还可以看到槽位
存储数据
前面学到的所有 redis
命令,在这里都是适用的
- 设置成集群模式之后,当前数据就分片了。
k1
这个key
通过hash
计算之后,得到slot 12706
,属于103
这个分片,但我们是在101
上进行的操作 - 我们可以在启动
redis-cli
的时候,加上-c
选项- 此时客户端发现当前
key
的操作不在当前分片上的时候,就能够自动的重定向到对应的分片主机
- 此时客户端发现当前
- 此时就触发了重定向,槽位号还是
12706
- 客户端直接把请求转发给了
103
-c
选项添加后,redis
客户端就会根据当前 key
实际算出来的槽位号,自动找到匹配的分配主机,进一步的就可以完成操作
使用集群之后,之前学过的命令,都能正常使用(不够严谨)
- 有些指令,是能操作多个
key
的,此时如果key
是分散在不同的分片上,就可能出现问题了
有特殊的方式,可以解决上述问题——
hash tag
节点宕机
- 如果是从节点挂了,没事
- 如果是主节点挂了,就摊上事了
- 主节点才能处理写操作,而从节点不能写
当我们尝试在从节点上写操作的时候,就会自动的被重定向到指定的主节点上
- 主节点要是挂了,就没法写了,就出问题了
此处,集群做的工作,就和之前哨兵做的类似,会自动把该主节点旗下从节点,给挑出一个,提拔成主节点
- 之前的时候
101
是主节点,105
和106
是他的从节点。在101
挂了之后,106
成了新的主节点,代替了原来101
的位置 - 与此同时,
105
就成了106
的从节点了
在重启 redis1
之后,发现其还是从节点,身份恢复不了
集群机制,也能处理故障转移
- 不过此处的故障转移处理流程和哨兵处理流程不一样
故障转移流程
1. 故障判断
识别出某个节点是否挂了
- 节点 A 个节点 B 发送
ping
包,B 就会给 A 返回一个pong
包。ping
和pong
除了message type
属性之外,其他部分都是一样的。这里包含了集群的配置信息(该节点 id,该节点从属于哪个分片,是主节点还是从节点,从属于谁,持有哪些slots
的位图…) - 每个节点,每秒钟,都会给一些随机的节点发起
ping
包,而不是全发一遍。这样设定是为了避免在节点很多的时候,心跳包也非常多(比如有9
个节点,如果全发,就是9 * 8
有72
组心跳了,而且这是按照N^2
这样的级别增长的) - 当节点 A 给节点 B 发起
ping
包,B 不能如期回应的时候,此时 A 就会尝试重置和 B 的TCP
连接,看能否连接成功。如果连接失败,A 就会把 B 设为PFAIL
状态(相当于主观下线)- 判定某个节点是否挂了,不能只听信“一面之词”
- A 判定 B 为
PFAIL
之后,会通过redis
内置的Gossip
协议,和其他节点确认 B 的状态(每个节点都会维护一个自己的“下线列表”,由于视角不同,每个节点的下线列表也不一定相同) - 此时 A 发现其他很多节点,也认为 B 为
PFAIL
,并且数目超过总集群个数的一般,那么 A 就会把 B 标记成FAIL
(相当于客观下线),并且把这个消息同步给其他节点(其他节点收到之后,也会把 B 标记成FAIL
)
B 是否下面,就已经明确了
2. 故障迁移
- 如果 B 是从节点,那么不需要进行故障迁移
- 如果 B 是主节点,那么就会由 B 的从节点(比如 C 和 D)触发故障迁移了
- 从节点判定自己是否具有参选资格。如果从节点和主节点已经太久没通信(此时认为从节点的数据和主节点差异太大了),时间超过阈值,就失去竞选资格
- 很久没通信,就是很久没同步过数据了,从节点的数据和主节点相比,估计差异比较大了
- 具有资格的节点,比如 C 和 D,就会先休眠一定时间
休眠时间 = 500ms 基础时间 + [0, 500ms]随机时间 + 排名 * 1000ms
offset
的值越大,数据就越接近主节点,排名越靠前,休眠时间就越短
- 比如 C 的休眠时间到了,C 就会给其他所有集群的节点,进行拉票操作。但是只有主节点才有投票资格
- 主节点就会把自己的票投给 C(每个主节点只有 1 票)。当 C 收到的票超过主节点数目的一半,C 就会晋升成主节点(C 自己负责执行
slaveof no one
,并且让 D 执行slaveof C
) - 同时,C 还会把自己成为主节点的消息,同步给其他集群的节点,大家也都会更新自己保存的集群结构信息
谁休眠时间短,大概率就是新的主节点了
上述选举的过程,称为
Raft
算法,是一种在分布式系统中广泛使用的算法
- 哨兵中,是先竞选出
leader
,然后leader
负责找一个从节点,升级成主节点 - 这里是直接投片选出新的主节点
集群宕机
以下三种情况会出现集群宕机:
- 某个分片,所有的主节点和从节点都挂了
- 该分片就无法提供数据服务了
- 某个分片,主节点挂了,但是没有从节点
- 超过半数的
master
节点都挂了- 如果突然一系列的
master
都挂了,此时说明集群遇到了非常严重的情况。此时就得赶紧停下来,检查检查是不是有什么问题
- 如果突然一系列的
如果集群中有个节点挂了,无论是什么节点,程序员都要尽快处理好
集群扩容
101-109
九个主机,构成了三主六从结构的集群了。现在将 110
和 111
也加入到集群中,以 110
为 master
,111
为 slave
- 把数据分片从三变为四
集群扩容操作,是一件风险较高,成本较大的操作
1. 将新主节点加入到集群
命令:
代码语言:javascript代码运行次数:0运行复制redis-cli --cluster add-node 172.30.0.110:6379 172.30.0.101:6379
- 第一个 IP 指被新增的节点是什么
- 第二个 IP 指集群上的任意一个节点,表示要把新节点加到哪个集群中
- 原来的那些
master
,都有响应的slots
。但是新增的这个,没有slots
- 需要我们手动进行分配
2. 分配 slots
把之前三组 master
上面的 slots
拎出来一些,分配给新的 master
redis-cli --cluster reshard 172.30.0.101:6379
- IP 是任意的一个节点的
此处会先打印出当前集群每个机器的情况,并且要求用户输入要移动多少个 slots
- 四个分片,一共是
16384
个,除4
得到的就是4096
- 然后会询问让哪个节点来接收,粘贴对应主机的
ID
- 输入要从哪些节点来移动
slots
all
,表示从其他每个持有slots
的master
都拿过来点- 手动指定,从某一个或者某几个节点来移动
slots
(以done
为结尾)
- 输入
all
之后,会给出一个搬运的计划(还没真正开始搬运),当程序员输入yes
之后,搬运真正开始- 此时不仅仅是
slots
重新划分,也会把slots
上对应的数据,也搬运到新的主机上
- 此时不仅仅是
- 此时可以看到新增的主节点分配到了
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]
执行完毕后,就添加完成了
小结
- 集群是什么?解决了什么问题?
- 数据分片算法(面试重点)
- 哈希求余
- 一致性哈希算法
- 哈希槽分区算法(redis 使用的方式)
- 搭建一个
redis
集群 - 集群容灾,故障转移
- 集群扩容
本文标签: redis集群 主节点宕机后选择 master 的详细流程
版权声明:本文标题:【redis】集群 主节点宕机后选择 master 的详细流程 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/jiaocheng/1748101674a2253214.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论