前文:
2、Linux 安装 Redis(二)主从复制,分析流程和原理,详细图解
本文大致会说到的一些内容:
- redis哨兵模式的部署
- 模拟故障转移
- 查看详细日志信息
- 关于一些问题的思考
- 关于哨兵模式的运行流程详解
- 哨兵模式选举原理
哨兵模式
哨兵就如这个名词一般,就是负责监控和巡查~,哨兵会监控master主机是否故障,如果故障了根据投票数自动将某一个从库转换为新主库,继续对外服务,也就是能够弥补上我们之前谈到的主从复制中需要人工干预的缺点。
哨兵模式的优点:
1、主从监控,监控主从redis库运行是否正常
2、消息通知,哨兵可以将故障转移的结果发送给客户端,
3、故障转移,如果master宕机,哨兵会主动进行主从切换,在其中的slaves中选择一个slave成为新的master。
4、配置中心,客户端通过连接哨兵来获得当前redis服务的主节点地址(应用程序端不再直接连接redis主从节点,而是连接哨兵集群)。
一、部署架构图
三个哨兵,自动监控和维护集群,不存放数据,只做监控;一主二从:用户存放数据和读取数据的redis.
哨兵本质上也是一个redis服务,只不过它不再直接存放数据了~
应用程序不再直接连接redis主从服务,而是转而直接连接哨兵集群,以达到无感知的主从切换。
二、开始部署
1、备份 sentinel.conf
在我们原本解压的目录下,可以看到有一个默认的sentinel.conf 文件,我们copy一份到我自己定义的/myredis目录下
2、常见和重点配置项
记得看看默认的sentinel的文件有那些内容,不然只光会部署,意义好像也不太大~
此处只贴出了一些常见参数的说明和一些重点配置项
bind 服务监听地址,用户客户端连接,默认本机地址 daemonize 是否以后台daemonize 方式运行 protected-mode 安全保护模式 port 端口 logfile 日志文件路径 pidfile pid文件路径 dir 工作目录
哨兵模式需要配置的几个重要参数:
sentinel monitor <master-name> <ip> <redis-port> <quorum> #设置要监控的master 服务器,quorum 表示最少有几个哨兵认可客观下线,同意故障迁移的法定票数 sentinel auth-pass <master-name> <password> # master 设置了密码,连接master服务的密码
上述命令中的 quorum
就是表示最少有几个哨兵认可客观下线,同意故障迁移的法定票数。后续在运行流程会再谈到
我们知道,网络是不可靠的,有时候一个sentinel
会因为网络堵塞而误以为一个master redis
已经挂掉了,在sentinel
集群环境下需要多给sentinel
互相沟通来确认某个master
是否真的死了,quorum
这个参数是进行客观下线一个依据,意思是至少有quorum
个sentinel
认为这个master
有故障,才会对这个master
进行下线以及故障转移。
通俗点说,你一个人认为它挂了,这是不准确的,哪里能这么霸道呢,要公平的询问大家的信息,如果达到指定票数的sentinel
都认为该master
有问题,才会进行下一步操作。
另外这还有几个进阶的参数,后续用到了再说吧,本文没有过多涉及。
sentinel down-after-milliseconds <master-name> <milliseconds> 指定多少毫秒之后,主节点没有应答哨兵,此时哨兵主观上认为该主节点下线(这也是后续会说到的主观下线,默认是30000毫秒) sentinel parallel-syncs <master-name> <nums> 表示允许并行同步的 salve 个数,当master挂了后,哨兵会选出新的master,此时,剩余的slave会跟随新的matser,重新开始复制数据 sentinel failover-timeout <master-name> <milliseconds> 故障转移的超时时间,进行故障转移时,如果超过设置的毫秒,表示故障转移失败 sentinel notification-script <master-name> <script-path> 配置当某一事件发生时所需要执行的脚本 sentinel client-reconfig-scipr <master-name> <script-path> 客户端重新配置主节点参数脚本
3、本次案例哨兵sentinel文件配置
为了更好的观察配置文件的变化,我这边是将配置文件中所有无关的文字都删除掉了。
默认配置文件总共为 342行,删除无关注释后的默认配置如下:
protected-mode no port 26379 daemonize no pidfile /var/run/redis-sentinel.pid logfile "" dir /tmp sentinel monitor mymaster 127.0.0.1 6379 2 sentinel down-after-milliseconds mymaster 30000 acllog-max-len 128 sentinel parallel-syncs mymaster 1 sentinel failover-timeout mymaster 180000 sentinel deny-scripts-reconfig yes SENTINEL resolve-hostnames no SENTINEL announce-hostnames no SENTINEL master-reboot-down-after-period mymaster 0
我这三台sentinel的通用配置文件如下:# 三台的端口分别是 26379、26380、26381,相关的文件名称也改一下,我这不赘述了。
protected-mode no port 26379 daemonize yes pidfile /var/run/redis-sentinel26379.pid logfile "/myredis/sentinel26379.log" dir /myredis sentinel monitor mymaster 192.168.208.128 6379 2 sentinel auth-pass mymaster 123456 sentinel down-after-milliseconds mymaster 30000 acllog-max-len 128 sentinel parallel-syncs mymaster 1 sentinel failover-timeout mymaster 180000 sentinel deny-scripts-reconfig yes SENTINEL resolve-hostnames no SENTINEL announce-hostnames no SENTINEL master-reboot-down-after-period mymaster 0
我这里是做的是简单的测试,其他相关的配置,是需要根据生产环境,业务大小来设置,光说没啥用~ 详情还是需要看redis官方文档
三份配置文件配完就是如下:
4、启动一主二从redis,测试
启动一主二从,进行测试
在主机的配置中也要加上:masterauth "123456"
因为如果主机宕机后,再次恢复上线可能会变成从机,所以需要配置上密码。
我们在启动观察一下配置文件的最末端是什么内容,稍后会有新的发现哦
主从测试:
查看三台机器目前的状态信息
info replication
假如我们现在手动模拟主机宕机,关停 master 主机,他们会自动切换吗?答案是并不会,感兴趣的同学可以自己试一下~
在确定正常后,我现在直接启动哨兵集群啦~
5、启动主从后,启动哨兵集群做测试
启动哨兵集群
redis-sentinel sentinel26379.conf --sentinel redis-sentinel sentinel26380.conf --sentinel redis-sentinel sentinel26381.conf --sentinel
通过ps -ef | grep redis
的结果可以看到,我们已经成功启动了哨兵集群,接下来,我们再进行一遍redis的主从测试。
另外我们查看一下三台sentinel的日志信息
也没标记啥啦,后期拿来对比会看的更明显
6、模拟 master 挂了后的场景,查看相关日志信息
现在我们手动模拟master主机宕机,看看会出现什么样的情况?
从上面的结果中,我们可以看到,在哨兵模式下,我们已经成功的实现主从机之间故障转移,并且无需我们人工干预。
7、哨兵到底做了什么?
那哨兵到底做了一些什么呢?怎么就达到了主从机之间故障转移呢?
我们来看看哨兵的日志信息:
其他两台也是类似的~ 就不重复贴出来啦~
刚刚我在上图中谈到了重写覆盖配置,我们一起来看看到底发生了什么吧
对比配置文件
在 129 的从机上(已成为主机),我们会看到在配置文件末尾添加了一段新的配置
并且我们之前配置的跟随主机的那段配置也被删除了
我们可以看到哨兵模式在故障转移的时候,帮助我们重写了覆盖配置文件。
那么自然另外一个从机的配置文件也大差不差啦~
跟随的主机的配置,变成了 129 机器
同样在最后也添加了一些配置~
8、宕机的master恢复了,会发生什么?
假如我之前宕机的master,在一段时间被恢复了,那么它还会是主机吗??
答案肯定是不会啦,因为你想想啊,原来从机中的配置文件都已经被改了,它怎么可能还会是主机呢?
再想想,我们没有修改挂掉的主机的配置文件(即没有添加 replicaof 主机IP、主机port
),它重启还会加入到这个主从集群中吗?
想不如做,自己亲自动手去看看,远比看到我这个答案有趣的多。
答案是会,会变成当前主机下的从机。
问题又来啦,难道哨兵模式在我重启之后,帮助我们重写了配置文件吗?
恭喜你,答对啦
这个过程是在重新启动之前就指定了的,只不过可能我们看日志看的没有那么仔细。
我把之前那张故障切换的截图拿过来你们就懂了。
看到这里,我再提个小问题?你觉得哨兵的配置文件被覆盖重写了吗?
我们直接打开看一看你就知道
9、一些思考
诸如上述问题,在看完下一章节,便会一一了解。
我们通过上面观察到的信息,可以看出哨兵模式下redis集群,它是会被sentinel
进行动态更改的。
哨兵如何知道所有从库地址呢?
哨兵是如何帮助我们更改配置的呢?
哨兵也是实例,如果挂了怎么办?
先思考思考吧,有些后面有答案,有些没写,可以自己去看看其他文章。
三、哨兵的运行流程和选举原理
当一个主从配置中的master故障宕机之后,sentinel可以选举出一个新的master出来,自动接替原master的工作,即我们常说的自动实现主从切换,故障转移。主从配置中的其他redis服务器自动指向新的master同步数据。
一般建议sentinel部署奇数台,方便投票,哈哈,同时也是防止某一台sentinel无法连接到master导致误切换。
先说说大概的故障转移流程
3.1、主观下线
SDowm(主观不可用)是单个sentinel自己主观下检测到的关于Master的状态,从sentinel的角度来看,如果发送了 PING 心跳后,在一定时候内没有收到合法的回复,那么这个Sentinel会主观的(单方面的)认为这个Master不可用了。
Sentinel配置文件中的 down-after-milliseconds
设置了判断主观下线的时间长度,默认是 30000 毫秒
sentinel down-after-milliseconds mymaster 30000
3.2、客观下线
客观下线,就是集群中的多个sentinel都判定该master出现故障了,这里的多个就是我们上文谈到过的 quorum
,
sentinel monitor <master-name> <ip> <redis-port> <quorum> #设置要监控的master 服务器,quorum 表示最少有几个哨兵认可客观下线,同意故障迁移的法定票数
上述命令中的 quorum
就是表示最少有几个哨兵认可客观下线,同意故障迁移的法定票数。
通俗点说,你一个人认为它挂了,这是不准确的,哪里能这么霸道呢,要公平的询问大家的信息,如果达到指定票数的sentinel
都认为该master
有问题,才会进行下一步操作。
思考一下:如果是哨兵集群中的哨兵数量为1,而此处的
quorum
的值为2,还能够正常进行故障转移吗?那如果哨兵集群是两台呢?可以吗?答案见文末,先想想吧。
3.3、选择哨兵Leader:
当主节点被判断客观下线之后,各个哨兵节点会进行协商,先选举出一个领导者哨兵节点(Leader)并由该领导者节点,也即被选举出来的Leader 节点来进行 failover(故障转移,从存活中的节点中选一个来转变为主服务)。
又回到之前谈到的问题,那哨兵领导者(Leader)是如何被选出来的呢?
这牵扯到 Raft 算法,一个分布式协议算法,详细的可以看看这篇文章:深度解析 Raft 分布式一致性协议
监视该主节点的所有哨兵节点都有可能被选为领导者,选举使用的算法是 Raft 算法: Raft 算法的基本思路是先到先得:
即在一轮选举中,哨兵A向B发送成为领导者的申请,如果B没有同意过其他哨兵,则会同意A成为领导者。
3.4、选择新Master
选出新master的规则,剩余slave节点健康前提下:
- redis.conf文件中,优先级 replica-priority 最高的从节点(数字越小,优先级越高,默认是100)
- 复制偏移量位置offset最大的从节点
- 最小的Run ID 的从节点
3.5、小结
故障恢复:
1、从下线的主服务器下的所有从机里挑选一个从服务,将其转为主机。
选择条件依次为:
- 选择优先级靠前的,优先级在redis.conf中的
salve-priority 100
- 选择偏移量最大的,偏移量是指获得原主数据最多的
- 选择runid最小的,每个redis实例启动后都会获得一个随机生成的40位的runid,越小的启动的越早。
2、挑选出新的主服务后,sentinel向原主服务的从服务发送slaveof新主服务命令,复制新的master。
- 执行
slaveof no one
命令让选出来的从节点成为新的主节点,并通过slave of
命令让其他节点成为其从节点, sentinel leader
会对选举出的新master执行slave no one
操作,将其提升为 master 节点sentinel leader
向其他 slave 发送命令,让剩下的 slave节点成为新的master节点的从节点。
3、当已下线的服务重新上线时,sentinel会向其发送slave的命令,让其成为新主的从服务。
注意点
- 哨兵节点的数量应为多个(奇数更佳),哨兵本身也应为集群,保证高可用。
- 各个哨兵节点的配置应为一致(这在诸多集群服务中都是如此)
- 在本地虚拟机自己玩的时候,一定要记得关闭防火墙或者是开放使用的端口。
- 哨兵集群+主从复制,并不能保证数据零丢失(比如主机接收到了命令还没同步到从机就挂了,还有主从切换期间,服务的不可用)
之前思考的答案:一台机器是不可以的,两台机器是可以的。
简单说一下原因:哨兵集群中机器数量为3时,quorum设置为2,这肯定是可行的,因为会有2票的产生。当机器为2时,quorum设置为2时,也是可以进行故障转移的。一台机器时设置quorum 为2,那自然是不行的哈。
后文
其实在蛮久以前,就知道这些了,但是太久不用,没去搭建,很多东西都给忘记了。
很多事情,想不如做,就像一些问题的答案,都是自己一步一步尝试出来的。
在此之前,你要是来问我哨兵集群中只有一台机器或两台机器,quorum设置为2,可不可以进行故障转移,我肯定会迟疑,因为我没有试过,所以我不确定。
想要得到一个确切的答案,那么就只能是亲自去躺坑。
谢谢阅读,希望看完的你有所收获,祝你生活愉快!
参考文章
zhuanlan.zhihu.com/p/296271483