当软件需要支持高可用,此时需要对计算单元进行冗余,对系统的高可用复杂度进行处理,演化出各种对复杂度的处理方式。
0. 起点:从单机到双机-决策者引入
当场景如下:无论在哪台机器上进行计算,同样的算法和输入数据,产出的结果都是一样的,所以将计算从一台机器迁移到另外一台机器,对业务并没有什么影响。以最简单的单机变双机为例进行分析。先来看一个单机变双机的简单架构示意图。 如图所示:
- 需要增加一个任务分配器,选择合适的任务分配器也是一件复杂的事情,需要综合考虑性能、成本、可维护性、可用性等各方面因素。
- 任务分配器和真正的业务服务器之间有连接和交互,需要选择合适的连接方式,并且对连接进行管理。例如,连接建立、连接检测、连接中断后如何处理等。
- 任务分配器需要增加分配算法。例如,常见的双机算法有主备、主主,主备方案又可以细分为冷备、温备、热备。
任务分配器需要保证高可用,通过备份手段达到系统的高可用。
1. 高可用状态决策
状态决策主要分为以下方式:
1.1 独裁式
独裁式决策指的是存在一个独立的决策主体,称它为“决策者”,负责收集信息然后进行决策;所有冗余的个体,称它为“上报者”,都将状态信息发送给决策者。
独裁式的决策方式不会出现决策混乱的问题,因为只有一个决策者,但问题也正是在于只有一个决策者。当决策者本身故障时,整个系统就无法实现准确的状态决策。如果决策者本身又做一套状态决策,那就陷入一个递归的死循环了。 缺点:显而易见,单机问题无法做决策。
1.2 协商式
协商式决策指的是两个独立的个体通过交流信息,然后根据规则进行决策,最常用的协商式决策就是主备决策。 这个架构的基本协商规则可以设计成:
- 2 台服务器启动时都是备机。
- 2 台服务器建立连接。
- 2 台服务器交换状态信息。
- 某 1 台服务器做出决策,成为主机;另一台服务器继续保持备机身份。
协商式决策的架构不复杂,规则也不复杂,其难点在于,如果两者的信息交换出现问题(比如主备连接中断),此时状态决策应该怎么做。
缺点:
- 链接断开产生两个主。
- 如果断开链接备不认为主挂了,导致没有主。
1.3 民主式
民主式决策指的是多个独立的个体通过投票的方式来进行状态决策。例如,ZooKeeper 集群在选举 leader 时就是采用这种方式。
民主式决策和协商式决策比较类似,其基础都是独立的个体之间交换信息,每个个体做出自己的决策,然后按照“多数取胜”的规则来确定最终的状态。
缺点:
2. 解决脑裂
通过zookeeper进行高可用决策会遇到脑裂问题,主要有以下解决方式。
2.1 基于kill进程的方式实现一致性
当老主由于GC或其他原因超时,备master尝试切换主时,先去登录到老主机器kill掉相关进程,只有成功kill,才去切换状态。 缺点:有可能无法登录到老机器上,为了一致性牺牲部分可用性,降低了系统可用性
2.2 基于DB实现一致性
通过数据库实现一个masterID,每次竞争都去更新ID。实际上是有了一个中间件。 这种方式无需两个master联通,提升了一致性。 缺点:每次需要数据更新,校验ID,有一定开销。
|