Redis探秘Sentinel(岗兵形式)
概述
Redis的高可用机制有耐久化、仿制、岗兵和集群。其首要的效果和处理的问题分别是:
- 耐久化:耐久化是最简略的高可用办法(有时乃至不被归为高可用的手法),首要效果是数据备份,行将数据存储在硬盘,确保数据不会因进程退出而丢掉。
- 仿制:仿制是高可用Redis的根底,岗兵和集群都是在仿制根底上完结高可用的。仿制首要完结了数据的多机备份,以及关于读操作的负载均衡和简略的毛病康复。缺点:毛病康复无法主动化;写操作无法负载均衡;存储才干遭到单机的约束。
- 岗兵:岗兵完结了主从仿制中毛病的主动化康复。缺点:写操作无法负载均衡;存储才干遭到单机的约束。
- 集群:经过集群,处理了写操作无法负载均衡,以及存储才干遭到单机约束的问题,完结了较为完善的高可用计划。
本文这儿将介绍Redis的岗兵机制。
为什么要有岗兵
Redis的主从形式要点在于处理全体的承压才干,运用从节点分管读取操作的压力。可是其在容错康复等可靠性层面短缺显着,不具备主动的毛病搬运与康复才干:
- 假如slave从节点宕机,整个redis仍旧能够正常供给服务,待slave节点从头发动后,能够康复从master节点的数据同步、然后持续供给服务。
- 假如master主节点宕机,则redis功用受损,无法持续供给写服务,直到手动修正master节点方可康复。
当然,master节点毛病后,也能够手动将其中一个从节点切换为新的master节点来康复毛病。而原先的master节点康复后,需求手动将其降级为slave节点,对外供给只读服务。
实践运用的时分,手动毛病康复的时效无法得到确保,为了支撑主动的毛病搬运与康复才干,Redis在主从形式的根底上进行优化增强,供给了岗兵(Sentinel)架构形式。
那么就需求有一个机制,能够监测主节点是否存活,假如发现主节点挂了,就推举一个从节点切换为主节点,而且把新主节点的相关信息告诉给从节点和客户端。
那么就有以下三个问题需求处理:
- 主库真的挂了吗?
- 挑选哪个从库作为主库?
- 怎样把新主库相关信息告诉给从库和客户端
岗兵机制流程
Redis的岗兵形式,便是在主从形式的根底上,额定布置若干独立的岗兵进程,经过岗兵进程去监督者Redis主从节点的状况,一旦发现主节点宕机,则岗兵能够从头从剩下slave节点中推选一个新的节点并将其晋级为master节点,以此确保整个体系功用能够正常运用。
岗兵担任三个使命:监控,选主(挑选主库)和告诉。
- 监控:监控是指岗兵进程运转时,周期性(默许1秒)给一切主从节点发送 PING 指令,当主从节点收到 PING 指令后,会发送一个呼应指令给岗兵,这样就能够检测他们是否依然在线运转。
- 从库没有在规则时刻内呼应岗兵的PING指令,岗兵就会把它符号为"下线状况";
- 主库没有在规则时刻呢呼应岗兵的PING指令,岗兵就会断定主库下线发动选主流程。
- 选主:岗兵在主库挂了今后,依照必定规则从从库中选出作为新的主库。
- 告诉:岗兵将选出的新主库衔接信息发给其他从库,从库和新主库树立衔接,履行replicaof指令,仿制数据。一同,岗兵会把新主库的衔接信息告诉给客户端,让它们将操作恳求发送给新主库上。
监控:怎样判别主库是否真的挂了
岗兵进程会运用PING指令检测主和从库的衔接状况,用来判别实例状况;
假如岗兵发现主库或许从库对PING指令呼应超时,那么岗兵就会把它符号为"片面下线"。
- 关于从库,岗兵能够简略符号为"片面下线",因为从库下线影响不大,集群对外服务不会中止。
- 关于主库,岗兵不能简略符号为"片面下线",敞开主从切换。因为或许存在一种状况:岗兵误判,主库没有毛病,可是一旦发动选主和告诉操作后续的选主和告诉操作都会带来额定的核算和通讯开支。还或许发生脑裂。
承认主库下线了,主库才干被符号为客观下线。需求留意的是客观下线是主节点才有的概念;假如从节点和岗兵节点发生毛病,被岗兵片面下线后,不会再有后续的客观下线和毛病搬运操作。
什么是误判?
主库实践没有下线,可是岗兵以为它下线了。误判发生原因:比方集群网络压力较大,呈现网络拥塞,或许主库本身压力较大,导致主节点没有在规则时刻内呼应岗兵的 PING 指令。
因而,这儿有两个问题:
- 需求尽量防止误判 - 少数服从多数
- 有两个岗兵都判别主库是客观下线了,那么由哪个岗兵进行主从毛病搬运
少数服从多数机制
岗兵集群:岗兵以多实例组成的集群形式进行布置(最少需求三台机器来布置岗兵集群)。经过多个岗兵节点一同判别,就能够就能够防止单个岗兵因为本身网络状况欠好,而误判主节点下线的状况。一同,多个岗兵网络一同不稳定的概率较小,让它们一同决议计划让误判率下降。
当一个岗兵判别主库为片面下线后就会向其它岗兵主张洽谈,其它岗兵就会依据本身与主库的网络状况,做出拥护或回绝投票的呼应。
而只需大多数岗兵实例判别主库都现已"片面下线",主库才会被符号"客观下线",——— 即少数服从多数机制
当这个岗兵的附和票数到达岗兵装备文件中的 quorum
装备项设定的值后,这时主节点就会被该岗兵符号为客观下线。
"客观下线":N个岗兵实例,最好要有N/2+1个实例判别主库为"片面下线",才干判别为"客观下线"。
由哪个岗兵进行主从毛病搬运
为了削减误判概率,所以岗兵是以岗兵集群的方法存在的,以少数服从多数的机制来判别主库是否真的挂了。
那么既然是集群,由岗兵集群中的哪个节点进行主从毛病搬运呢?
所以这时分,还需求在岗兵集群中选出一个 leader,让 leader 来履行主从切换。
leader是从候选者中发生的,哪个岗兵节点判别主节点为 客观下线 ,这个岗兵节点便是leader的候选者。
假设有三个岗兵。当岗兵 B 先判别到主节点片面下线后,就会给其他实例发送 is-master-down-by-addr 指令。接着,其他岗兵会依据自己和主节点的网络衔接状况,做出拥护投票或许回绝投票的呼应。当岗兵 B 收到拥护票数到达岗兵装备文件中的 quorum 装备项设定的值后,就会将主节点符号为 客观下线,此刻的岗兵 B 便是一个Leader 的候选者。
判别主库客观下线后仅仅Leader 的候选者,还不是Leader
因为quorum 装备问题,有或许判别主库客观下线的岗兵有多个
。比方有3个岗兵,quorum为2,AB都以为主库片面下线,C以为主库还在线,因而此刻岗兵A收到片面下线的值为2,另一个岗兵B收到的片面下线值也为2,因为这两个值都大于等于quorum,因而岗兵A和岗兵B都会将主库符号为客观下线。但不能让岗兵A和岗兵B一同履行主从切换。因而需求从岗兵A和岗兵B中选出一个Leader来履行主从切换
此刻Leader候选者会向其他岗兵发送指令,标明期望成为 Leader 来履行主从切换,并让一切其他岗兵对它进行投票。
每个岗兵只需一次投票时机,假如用完后就不能参加投票了,能够投给自己或投给他人,可是只需Leader候选者才干把票投给自己。
那么只需 Leader候选者 一同满意以下两个条件,就能够成为Leader:
- 拿到半数以上的拥护票;
- 拿到的票数还要大于等于岗兵装备文件中的 quorum 值。
也便是说,推举的票数大于等于num(sentinel)/2+1时,Leader候选者 将成为 Leader,假如没有超越持续推举
所以,quorum 的值主张设置为岗兵个数的二分之一加1,例如 3 个岗兵就设置 2,5 个岗兵设置为 3,而且岗兵节点的数量应该是奇数
岗兵判别主节点客观下线后,岗兵就要开端在从节点中选出一个从节点来做新主节点
这儿咱们是不是和我相同有个疑问?假如三个岗兵一同判别为片面下线,那么就有或许一同判别为客观下线,那么就都是leader候选者了,那么在投票时也都投给了自己,那么leader不就永久选不出来了吗?
首要,岗兵对主从库进行的在线状况查看的操作,是归于一种时刻事情,用一个定时器来完结,一般来说每100ms履行一次这些事情。实践上每个岗兵的定时器履行周期都会加上一个小小的随机时刻偏移,意图是让每个岗兵履行上述操作的时刻能略微错开些,也是为了防止它们都一同断定主库片面下线。
其次,实践上不同岗兵的网络状况、体系的压力一般不完全相同,接收到片面下线洽谈音讯的时刻也就或许不同,所以,它们一同做出主库客观下线断定的概率较小,一般也就有个先后联系。
终究,即便呈现了都投给自己一票的状况,导致无法选出Leader,岗兵会停一段时刻(一般是毛病搬运超时时刻failover_timeout的2倍),然后再能够进行下一轮投票。
选定新主库
选定新主库是 挑选 ➕ 打分的进程
挑选条件:
首要要把网络状况欠好的从节点给过滤掉。首要把现已下线的从节点过滤掉,然后把以往网络衔接状况欠好的从节点也给过滤掉。
- 查看从库的当时在线状况,判别他之前的网络衔接状况
- 假如从库总是和主库断连,断连次数超越必定阈值,该从库网络状况欠好。
判别方法:
运用装备项down-after-milliseconds*10。down-after-milliseconds是主从节点断连的最大衔接超时时刻。假如在 down-after-milliseconds 毫秒内,主从节点都没有经过网络联系上,咱们就能够以为主从节点断连了。假如这个断连次数超越10次,阐明从库网络状况欠好,不适合作为新主库。
打分:
优先级、仿制进展、ID 号
- 第一轮:优先级最高的从节点胜出
经过装备slave-priority装备项,给不同从库设置不同优先级。比方两个从库内存巨细不相同,能够手动设置内存大的实例设置为一个高优先级。选主时分岗兵会选出优先级最高的打高分作为新主库,假如得分相同,那就开端第二轮打分。 - 第二轮:和旧主库同步程度最接近的从库得分高
假如挑选与旧主库同步最接近的从库作为主库,那么新主库上就有最新的数据。假如两个从库的slave_repl_offset值巨细相同,那么就需求进入第三轮打分了
怎样判别从库和旧主库间的同步进展?
从库的slave_repl_offset最接近旧主库的master_repl_offset,那么它的得分最高,能够作为新主库。
- 第三轮:ID 号小的从节点胜出
每个从节点都有一个编号,这个编号便是 ID 号,是用来仅有标识从节点的。
告诉
将推举出的从节点免除从节点身份,晋级为主节点
在推举出从节点为新主节点后后,岗兵 leader 向被选中的从节点发送 SLAVEOF no one 指令,让这个从节点免除从节点的身份,将其变为新主节点。
将从节点指向新的主节点
岗兵 leader 下一步要做的便是,让已下线主节点属下的一切从节点指向新主节点,这一动作能够经过向从节点发送 SLAVEOF 指令来完结。
告诉客户端主节点现已替换
这首要经过 Redis 的发布者/订阅者机制来完结的。每个岗兵节点供给发布者/订阅者机制,客户端能够从岗兵订阅音讯。
岗兵供给的音讯订阅频道有许多,不同频道包含了主从节点切换进程中的不同要害事情,几个常见的事情如下:
客户端和岗兵树立衔接后,客户端会订阅岗兵供给的频道。主从切换完结后,岗兵就会向 +switch-master 频道发布新主节点的 IP 地址和端口的音讯,这个时分客户端就能够收到这条信息,然后用这儿面的新主节点的 IP 地址和端口进行通讯了。
将原主节点变为从节点,指向新的主节点
持续监督旧主节点,当旧主节点从头上线时,岗兵集群就会向它发送 SLAVEOF 指令,让它成为新主节点的从节点
频频主从切换
因为redis是单线程运转的,假如有指令超越3秒,岗兵心跳查看就会失利,终究导致频频切换主从和脑裂状况
总结
本文首要介绍了岗兵的效果:监控、选主、告诉;首要是完结主从节点毛病搬运。岗兵集群会监测主节点是否存活,假如发现主节点挂了,它就会推举一个从节点切换为主节点,而且把新主节点的相关信息告诉给从节点和客户端。
岗兵机制具体步骤如下:
- 第一轮投票:判别主节点客观下线
- 第二轮投票:选出岗兵leader,决议由哪个岗兵履行主从切换
- 由岗兵 leader 进行选主
- 由岗兵 leader 进行告诉,完结主从毛病搬运
在主从仿制的根底上,岗兵引入了主节点的主动毛病搬运,进一步提高了Redis的高可用性;可是岗兵的缺点相同很显着:岗兵无法对从节点进行主动毛病搬运,在读写别离场景下,从节点毛病会导致读服务不可用,这就需求对从节点做额定的监控、切换操作。 此外,岗兵依然没有处理写操作无法负载均衡、存储才干遭到单机约束的问题;这些问题的处理需求运用集群,有时刻再学习集群方面的常识~
面试题专栏
Java面试题专栏已上线,欢迎拜访。
- 假如你不知道简历怎样写,简历项目不知道怎样包装;
- 假如简历中有些内容你不知道该不该写上去;
- 假如有些归纳性问题你不知道怎样答;
那么能够私信我,我会尽我所能协助你。