1.1.哨兵工作原理
Redis通过提供哨兵
(Sentinel
)机制来监控主从集群的监控状态,确保集群的高可用性。
1.1.1.哨兵作用
哨兵集群作用原理图如下:
哨兵的作业:
-
1. 状态监控:
Sentinel
会不断检查您的master
和slave
是否按预期工作 -
2. 故障恢复(failover):如果
master
故障,Sentinel
会将一个slave
提升为master
。当故障实例恢复后会成为slave
-
3. 状态通知:
Sentinel
充当Redis
客户端的服务发现来源,当集群发生failover
时,会将最新集群信息推送给Redis
的客户端
哨兵是怎么知道redis节点是否宕机?
1.1.2.状态监控
Sentinel
基于心跳机制监测服务状态,每隔1秒向集群的每个节点发送ping命令,并通过实例的响应结果来做出判断:
-
主观下线(sdown):如果某sentinel节点发现某Redis节点未在规定时间响应,则认为该节点主观下线。
-
客观下线(odown):若超过指定数量(通过
quorum
设置)的sentinel都认为该节点主观下线,则该节点客观下线。quorum值最好超过Sentinel节点数量的一半,Sentinel节点数量至少3台。
一旦发现master故障,sentinel需要在salve中选择一个作为新的master,选择依据是这样的:
-
首先会判断slave节点与master节点断开时间长短,如果超过
down-after-milliseconds * 10
则会排除该slave节点 -
然后判断slave节点的
slave-priority
值,越小优先级越高,如果是0则永不参与选举(默认都是1)。 -
如果
slave-prority
一样,则判断slave节点的offset
值,越大说明数据越新,优先级越高 -
最后是判断slave节点的
run_id
大小,越小优先级越高(通过info server可以查看run_id
)。
当选出一个新的master后,身份切换有两种方式:
-
在多个
sentinel
中选举一个leader
-
由
leader
执行failover
1.1.3.选举leader
首先,Sentinel集群要选出一个执行failover
的Sentinel节点,可以成为leader
。要成为leader
要满足两个条件:
-
最先获得超过半数的投票
-
获得的投票数不小于
quorum
值
而sentinel投票的原则有两条:
-
优先投票给目前得票最多的
-
如果目前没有任何节点的票,就投给自己
比如有3个sentinel节点,s1
、s2
、s3
,假如s2
先投票:
-
此时发现没有任何人在投票,那就投给自己。
s2
得1票 -
接着
s1
和s3
开始投票,发现目前s2
票最多,于是也投给s2
,s2
得3票 -
s2
称为leader
,开始故障转移
不难看出,谁先投票,谁就会称为leader,那什么时候会触发投票呢?
答案是第一个确认master客观下线的人会立刻发起投票,一定会成为leader。
1.1.4.failove
我们举个例子,有一个集群,初始状态下7001为master
,7002和7003为
slave
:
假如master发生故障,slave1当选。则故障转移的流程如下:
1)sentinel
给备选的slave1
节点发送slaveof no one
命令,让该节点成为master
2)sentinel
给所有其它slave
发送slaveof 192.168.150.101 7002
命令,让这些节点成为新master
,也就是7002
的slave
节点,开始从新的master
上同步数据。
3)最后,当故障节点恢复后会接收到哨兵信号,执行slaveof 192.168.150.101 7002
命令,成为slave
2.1.搭建哨兵集群
首先,我们停掉之前的redis集群::
老版本DockerCompose docker-compose down
新版本Docker docker compose down
创建一个新的config文件,内容如下:
sentinel announce-ip "***.***.***.***"(这里填你的ip)
sentinel monitor hmaster ***.***.***.*** 9001 2
sentinel down-after-milliseconds hmaster 5000
sentinel failover-timeout hmaster 60000
说明:
-
sentinel announce-ip "***.***.***.***"
:声明当前sentinel的ip -
sentinel monitor hmaster ***.***.***.*** 9001 2
:指定集群的主节点信息-
hmaster
:主节点名称,自定义,任意写 -
***.***.***.*** 9001
:主节点的ip和端口 -
2
:认定master
下线时的quorum
值
-
-
sentinel down-after-milliseconds hmaster 5000
:声明master节点超时多久后被标记下线 -
sentinel failover-timeout hmaster 60000
:在第一次故障转移失败后多久再次重试
在虚拟机的/root/redis
目录下新建3个文件夹:s1
、s2
、s3
:
将课前资料提供的sentinel.conf
文件分别拷贝一份到3个文件夹中。
接着修改docker-compose.yaml
文件,内容如下:
直接运行命令,启动集群:
docker-compose up -d
运行结果:
3.1.演示failover
接下来,我们演示一下当主节点故障时,哨兵是如何完成集群故障恢复(failover)的。
我们连接7001
这个master
节点,然后通过命令让其休眠60秒,模拟宕机:
连接7001这个master节点,通过sleep模拟服务宕机,60秒后自动恢复
docker exec -it r1 redis-cli -p 7001 DEBUG sleep 60
稍微等待一段时间后,会发现sentinel节点触发了failover
:
4.1.总结
Sentinel的三个作用是什么?
-
集群监控
-
故障恢复
-
状态通知
Sentinel如何判断一个redis实例是否健康?
-
每隔1秒发送一次ping命令,如果超过一定时间没有相向则认为是主观下线(
sdown
) -
如果大多数sentinel都认为实例主观下线,则判定服务客观下线(
odown
)
故障转移步骤有哪些?
-
首先要在
sentinel
中选出一个leader
,由leader执行failover
-
选定一个
slave
作为新的master
,执行slaveof noone
,切换到master模式 -
然后让所有节点都执行
slaveof
新master -
修改故障节点配置,添加
slaveof
新master
sentinel选举leader的依据是什么?
-
票数超过sentinel节点数量1半
-
票数超过quorum数量
-
一般情况下最先发起failover的节点会当选
sentinel从slave中选取master的依据是什么?
-
首先会判断slave节点与master节点断开时间长短,如果超过
down-after-milliseconds
* 10
则会排除该slave节点 -
然后判断slave节点的
slave-priority
值,越小优先级越高,如果是0则永不参与选举(默认都是1)。 -
如果
slave-prority
一样,则判断slave节点的offset
值,越大说明数据越新,优先级越高 -
最后是判断slave节点的
run_id
大小,越小优先级越高(通过info server可以查看run_id
)。
目录