可用性有限:当Master
宕机后,此时写操作都失败,直到实例重启。
为解决Master
到实例重启所丢失的数据量,提出了哨兵架构。
哨兵架构示意图如下:
优点
可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主服务器进人下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器,然后由新的主服务器代替已下线的主服务器继续处理命令请求。
这样就不需要等待运维人员重启实例,而是自动的进行选举,只不过是在选举的时刻不能进行写操作,可用性极大的提高了。
当主服务的server1
的下线时长超过用户设定的下线时长上限时,Sentinel
系统就会对server1
执行故障转移操作:
Sentinel
系统会挑选 server1
属下的其中一个从服务器,并将这个被选中的从服务器升级为新的主服务器。Sentinel
系统会向 server
1属下的所有从服务器发送新的复制指令,让它们成为新的主服务器的从服务器,当所有从服务器都开始复制新的主服务器时,故障转移操作执行完毕。Sentinel
还会继续监视已下线的server1
,并在它重新上线时,将它设置为新的主服务器的从服务器。 Sentinel 默认以每10秒一次的频率,向被监视的主服务器发送INFO
命令,通过其回复来获取主服务器的当前信息。
通过分析主服务器返回的INFO
命令回复,Sentinel
可以获取以下两方面的信息:
ID
以及服务器的角色IP
、端口,所以 Sentinel
无须用户提供从服务器地址信息就可以自动发现从服务器。 当 Sentinel
发现主服务器有新的从服务器时,Sentinel
除了为该从服务器创建相应的实例,还会创建连接向从服务器的命令连接和频道连接。
当创建命令连接后,Sentinel 默认会以每10秒一次的频率通过命令连接向从服务器发送 INFO 命令。
根据INFO
命令的回复,Sentinel
会提取出以下信息:
在默认情况下,Sentinel
会以每两秒一次的频率。 通过命令连接向所有被监视的主服务器和从服务器发送以下格式的命令:
PUBLISH __sentinel:he11o ",,,,,, , "
s_
开头的参数为Sentinel
本身的信息。
m_
开头的参数为Master
本身的信息。
当Sentinel
与一个主服务器或者从服务器建立起订阅连接之后,Sentinel
就会通过订阅连接,向服务器发送以下命令:
SUBSCRIBE __sentinel___ : hel1o
Sentinel
对sentinel__ :hello
频道的订阅会一直持续到Sentinel
与服务器的连接断开为止。
Sentinel
会从频道中获取到的信息,对对应主服务器的实例结构进行更新。
默认情况下,Sentinel
会以每秒一次的频率向所有与他创建了命令连接的实例(包括主服务器、从服务器、其他Sentinel
)发送 PING
命令,并通过实例返回的信息判断实例是否在线。
如果有一个实例在 down-after-millisecond
毫秒内,连续向 Sentinel
返回无效回复,那么 Sentinel
会修改这个实例所对应的实例结构,在结构的flags
属性中打开 SRI_S_DOWN
标识,以此标识该实例已经进入主观下线状态。
当 Sentinel
将一个主服务器判断为主观下线后,为了确保该主服务器真的下线,还需要进行客观下线判断。
当 Sentinel
从其他 Sentinel
那里接收到足够数量的下线判断后,Sentinel
就会将主服务器判定为客观下线,并对服务器进行故障转移操作。
当一个主服务器被判断为客观下线时,监视这个下线主服务器的各个Sentinel
会进行协商,选举出一个领头Sentinel, 并由领头
Sentinel `对下线主服务器执行故障转移操作。
领头 Sentinel
将进行故障转移时,需执行以下3
个步骤:
选举规则
领头服务器将所有从服务器保存到一个列表中,然后进行过滤。
Sentinel
的INFO
命令的从服务器down-after-miliseconds * 10
的从服务器offset
最大的,保证数据尽可能一致offset
相同,则出run ID
最小的从服务器 当新的主服务器出现之后,领头 Sentinel
下一步要做的就是,让已下线主服务器属下的所有从服务器去复制新的主服务器,这一动作可以通过向从服务器发送 SLAVEOF
命令来实现。
故障转移操作最后要做的是,将已下线的主服务器设置为新的主服务器的从服务器。
脑裂,也就是说,某个master
所在机器突然脱离了正常的网络,跟其他slave
机器不能连接,但是实际上master
还运行着。
此时哨兵可能就会认为master
宕机了,然后开启选举,将其他slave
切换成了master
。
这个时候,集群里就会有两个·master
,也就是所谓的脑裂。
这会造成客户端还没有反应过来,数据没有被写入到新的master
中,从而造成数据不一致。
解决方案
min-slaves-to-write 1
min-slaves-max-lag 10
第一个参数表示连接到master
的最少slave数量为 1
第二个参数表示slave
连接到master
的最大延迟时间为 10 秒
如果说一旦所有的slave
,数据复制和同步的延迟都超过了10
秒钟,那么这个时候,master
就不会再接收任何请求了。
该方案同样是解决异步同步数据丢失的解决方案。