|NO.Z.00037|——————————|^^ 配置 ^^|——|Hadoop&Redis.V05|——|Redis.v05|高可用|哨兵模式|检测原理|故障转移|
一、哨兵模式检测原理:哨兵模式故障转移:执行流程
### --- 启动并初始化Sentinel
~~~ Sentinel是一个特殊的Redis服务器
~~~ 不会进行持久化
~~~ Sentinel实例启动后
~~~ 每个Sentinel会创建2个连向主服务器的网络连接
~~~ 命令连接:用于向主服务器发送命令,并接收响应;
~~~ 订阅连接:用于订阅主服务器的—sentinel—:hello频道。

### --- 获取主服务器信息
~~~ Sentinel默认每10s一次,向被监控的主服务器发送info命令,
~~~ 获取主服务器和其下属从服务器的信息。
127.0.0.1:6379> info
# Server
redis_version:5.0.5
os:Linux 3.10.0-957.el7.x86_64 x86_64
run_id:21ca92f85ea36a2069a9f2a8dece0a69c882df53
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6381,state=online,offset=273126,lag=0
slave1:ip=127.0.0.1,port=6379,state=online,offset=273126,lag=0
master_replid:79608f9a720c3bfc9625e25a86ffc3d66d01e102
master_replid2:1a6e0ff57df19a1dcceb353a02e14d2f8fd8c9c8
master_repl_offset:273126
second_repl_offset:155657
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:273126
### --- 获取从服务器信息
~~~ 当Sentinel发现主服务器有新的从服务器出现时,
~~~ Sentinel还会向从服务器建立命令连接和订阅连接。
~~~ 在命令连接建立之后,Sentinel还是默认10s一次,
~~~ 向从服务器发送info命令,并记录从服务器的信息。

# Server
redis_version:5.0.5
os:Linux 3.10.0-229.el7.x86_64 x86_64
run_id:e289b3286352aaf8cc9f1ac7ebcc6d36131b8321
# Replication
role:slave
master_host:127.0.0.1
master_port:6380
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:251825
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:79608f9a720c3bfc9625e25a86ffc3d66d01e102
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:251825
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:195890
repl_backlog_histlen:55936
### --- 向主服务器和从服务器发送消息(以订阅的方式)
~~~ 默认情况下,Sentinel每2s一次,
~~~ 向所有被监视的主服务器和从服务器所订阅的—sentinel—:hello频道上发送消息,
~~~ 消息中会携带Sentinel自身的信息和主服务器的信息。
PUBLISH _sentinel_:hello "< s_ip > < s_port >< s_runid >< s_epoch > < m_name > <
m_ip >< m_port ><m_epoch>"
### --- 接收来自主服务器和从服务器的频道信息
~~~ 当Sentinel与主服务器或者从服务器建立起订阅连接之后,
~~~ Sentinel就会通过订阅连接,向服务器发送以下命令:
subscribe —sentinel—:hello
### --- Sentinel彼此之间只创建命令连接,
~~~ 而不创建订阅连接,因为Sentinel通过订阅主服务器或从服务器,
~~~ 就可以感知到新的Sentinel的加入,而一旦新Sentinel加入后,
~~~ 相互感知的Sentinel通过命令连接来通信就可以了。
### --- 检测主观下线状态
~~~ Sentinel每秒一次向所有与它建立了命令连接的实例(主服务器、
~~~ 从服务器和其他Sentinel)发送PING命令
~~~ 实例在down-after-milliseconds毫秒内返回无效回复(除了+PONG、-LOADING、-MASTERDOWN外)
~~~ 实例在down-after-milliseconds毫秒内无回复(超时)
~~~ Sentinel就会认为该实例主观下线(SDown)
### --- 检查客观下线状态
~~~ 当一个Sentinel将一个主服务器判断为主观下线后
~~~ Sentinel会向同时监控这个主服务器的所有其他Sentinel发送查询命令主机的
SENTINEL is-master-down-by-addr <ip> <port> <current_epoch> <runid>
~~~ # 其他Sentinel回复
~~~ 判断它们是否也认为主服务器下线。
~~~ 如果达到Sentinel配置中的quorum数量的Sentinel实例都判断主服务器为主观下线,
~~~ 则该主服务器就会被判定为客观下线(ODown)。
<down_state>< leader_runid >< leader_epoch >
### --- 选举Leader Sentinel
~~~ 当一个主服务器被判定为客观下线后,
~~~ 监视这个主服务器的所有Sentinel会通过选举算法(raft),
~~~ 选出一个Leader Sentinel去执行failover(故障转移)操作。
二、哨兵leader选举
### --- Raft
~~~ Raft协议是用来解决分布式系统一致性问题的协议。
~~~ Raft协议描述的节点共有三种状态:Leader, Follower, Candidate。
~~~ term:Raft协议将时间切分为一个个的Term(任期),可以认为是一种“逻辑时间”。
三、选举流程:
### --- Raft采用心跳机制触发Leader选举
~~~ 系统启动后,全部节点初始化为Follower,term为0。
~~~ 节点如果收到了RequestVote或者AppendEntries,就会保持自己的Follower身份
~~~ 节点如果一段时间内没收到AppendEntries消息,在该节点的超时时间内还没发现Leader,
~~~ Follower就会转换成Candidate,自己开始竞选Leader。
~~~ # 一旦转化为Candidate,该节点立即开始下面几件事情:
~~~ 增加自己的term。
~~~ 启动一个新的定时器。
~~~ 给自己投一票。
~~~ 向所有其他节点发送RequestVote,并等待其他节点的回复。
~~~ 如果在计时器超时前,节点收到多数节点的同意投票,就转换成Leader。同时向所有其他节点发送
~~~ # AppendEntries,告知自己成为了Leader。
~~~ 每个节点在一个term内只能投一票,采取先到先得的策略,
~~~ Candidate前面说到已经投给了自己,Follower会投给第一个收到RequestVote的节点。
~~~ Raft协议的定时器采取随机超时时间,这是选举Leader的关键。
~~~ 在同一个term内,先转为Candidate的节点会先发起投票,从而获得多数票。
四、Sentinel的leader选举流程
### --- Sentinel的leader选举流程
~~~ 某Sentinel认定master客观下线后,该Sentinel会先看看自己有没有投过票,
~~~ 如果自己已经投过票给其他Sentinel了,在一定时间内自己就不会成为Leader。
~~~ 如果该Sentinel还没投过票,那么它就成为Candidate。
### --- Sentinel需要完成几件事情:
~~~ 更新故障转移状态为start
~~~ 当前epoch加1,相当于进入一个新term,在Sentinel中epoch就是Raft协议中的term。
~~~ 向其他节点发送is-master-down-by-addr 命令请求投票。命令会带上自己的epoch。
~~~ 给自己投一票(leader、leader_epoch)
~~~ # 当其它哨兵收到此命令时,
~~~ 可以同意或者拒绝它成为领导者;(通过判断epoch)
~~~ # Candidate会不断的统计自己的票数,
~~~ 直到他发现认同他成为Leader的票数超过一半而且超过它配置的quorum,这时它就成为了Leader。
~~~ # 其他Sentinel等待Leader从slave选出master后,
~~~ 检测到新的master正常工作后,就会去掉客观下线的标识。
五、故障转移
### --- 当选举出Leader Sentinel后,Leader Sentinel会对下线的主服务器执行故障转移操作,
~~~ # 主要有三个步骤:
~~~ # 它会将失效Master 的其中一个Slave 升级为新的Master ,
~~~ 并让失效Master 的其他Slave 改为复制新的Master ;
~~~ # 当客户端试图连接失效的Master 时,
~~~ 集群也会向客户端返回新Master 的地址,使得集群可以使用现在的Master 替换失效Master 。
~~~ # Master 和Slave 服务器切换后,
~~~ Master 的redis.conf 、Slave 的redis.conf 和sentinel.conf
~~~ 的配置文件的内容都会发生相应的改变,即,
~~~ Master 主服务器的redis.conf配置文件中会多一行replicaof 的配置,
~~~ sentinel.conf 的监控目标会随之调换。
六、主服务器的选择
### --- 哨兵leader根据以下规则从客观下线的主服务器的从服务器中选择出新的主服务器。
~~~ 过滤掉主观下线的节点
~~~ 选择slave-priority最高的节点,如果由则返回没有就继续选择
~~~ 选择出复制偏移量最大的系节点,因为复制偏移量越大则数据复制的越完整,如果由就返回了,没有就继续
~~~ 选择run_id最小的节点,因为run_id越小说明重启次数越少
Walter Savage Landor:strove with none,for none was worth my strife.Nature I loved and, next to Nature, Art:I warm'd both hands before the fire of life.It sinks, and I am ready to depart
——W.S.Landor
分类:
bdv012-redis
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通