乐趣区

关于后端:系统复杂度之高可用

接着,咱们聊聊复杂度的第二个要求高可用。

参考维基百科,先来看看高可用的定义。

零碎无中断地执行其性能的能力,代表零碎的可用性水平,是进行零碎设计时的准则之一。

这个定义的关键在于“ 无中断 ”,但恰好难点也在“无中断”下面,因为无论是单个硬件还是单个软件,都不可能做到无中断,硬件会出故障,软件会有 bug;硬件会逐步老化,软件会越来越简单和宏大……

除了硬件和软件实质上无奈做到“无中断”,外部环境导致的不可用更加不可避免、不受管制。例如,断电、旱灾、地震,这些事变或者劫难也会导致系统不可用,而且影响水平更加重大,更加难以预测和躲避。

高可用性是指零碎在没有中断的状况下可能继续执行其性能的能力,是进行零碎设计时的重要准则之一。然而,要实现无中断是十分艰难的,因为单个硬件或软件都有可能呈现故障或谬误,且硬件随着工夫的推移会逐步老化,软件也会变得越来越简单和宏大。此外,外部环境因素如断电、旱灾、地震等劫难也可能导致系统不可用,而且其影响水平更加重大,更难以预测和躲避。

因而,实现高可用性的计划是通过减少冗余性来进步零碎的可用性。简略来说,就是减少更多的机器或部署多个机房来解决单点故障问题。这样做的目标是为了加强零碎的冗余性,从而实现高可用性。须要留神的是,实现高性能和高可用性都须要减少机器,但它们的目标不同,前者是为了“扩大”解决性能,而后者是为了“冗余”处理单元。

尽管通过冗余加强了零碎的可用性,但同时也带来了复杂性。因而,在理论利用中须要依据不同的场景逐个剖析,采取不同的高可用计划。

计算高可用

在这里,“计算”指的是业务逻辑解决。与计算相干的高可用性的复杂性在于,无论在哪台机器上执行计算,只有算法和输出数据雷同,计算结果就应该是雷同的。因而,将计算从一台机器转移到另一台机器,对业务逻辑没有任何影响。

以最简略的单机变双机架构为例,咱们能够看到以下几个方面的复杂性:先来看一个单机变双机的简略架构示意图。

你可能会发现,这个双机的架构图和上期“高性能”讲到的双机架构图是一样的,因而复杂度也是相似的,具体表现为:

  • 须要减少工作分配器,抉择适合的工作分配器也是一个简单的过程,须要思考各种因素,例如性能、老本、可维护性和可用性等等。
  • 工作分配器与真正的业务服务器之间须要进行连贯和交互。因而,须要抉择适合的连贯形式,并且对连贯进行治理。例如,建设连贯、检测连贯、解决连贯中断等等。
  • 工作分配器须要减少调配算法。常见的双机算法有主备、主主,主备计划又能够细分为冷备、温备、热备等等。

下面这个示意图只是简略的双机架构,咱们再看一个简单一点的高可用集群架构。

下面这个示意图只是一个简略的双机架构,而复杂度会随着集群的规模和构造的变动而减少。例如,上图展现了一个更为简单的高可用集群架构。这种状况下,调配算法的抉择更加简单,能够是 1 主 3 备、2 主 2 备、3 主 1 备、4 主 0 备等等。具体应该采纳哪种形式,须要依据理论业务需要进行剖析和判断,不存在一种算法肯定比其余算法更优。例如,ZooKeeper 采纳的是 1 主多备,而 Memcached 则采纳全主 0 备。

存储高可用

对于须要存储数据的零碎来说,整个零碎的高可用设计的关键点和难点在于“存储高可用”。与计算相比,存储有一个实质的不同点:将数据从一台机器搬到另一台机器须要通过线路传输。线路传输的速度是毫秒级别,同一机房外部能够做到几毫秒,但散布在不同中央的机房,传输耗时须要几十甚至上百毫秒。例如,从广州机房到北京机房,稳固状况下 ping 延时大概是 50ms,不稳固状况下可能达到 1 秒甚至更长。

尽管对人类来说,毫秒简直没有什么感觉,但对于高可用零碎来说,这是实质的不同之处。这意味着在某个工夫点上,整个零碎中的数据必定是不统一的。依照“ 数据 + 逻辑 = 业务 ”这个公式来看,数据不统一即便逻辑统一,最终的业务体现也会不同。以银行储蓄业务为例,假如用户的数据存在北京机房,用户存入 1 万块钱,而后查问时被路由到了上海机房,而北京机房的数据没有同步到上海机房。用户会发现他的余额并没有减少 1 万块。设想一下,此时用户必定会感到不安,会狐疑本人的钱被盗了,连忙打客服电话投诉,甚至可能打 110 报警。即便最终发现只是因为传输提早导致的问题,从用户的角度来看,这个过程的体验必定很不好。

除了物理传输速度限度,传输线路自身也可能呈现可用性问题。传输线路可能会中断、拥塞、异样(如错包、丢包),并且线路故障的复原工夫通常较长,可能继续几分钟甚至几小时。例如,2015 年支付宝因为光缆被挖断,业务受到了超过 4 个小时的影响;2016 年中美海底光缆中断 3 小时等。线路中断意味着存储无奈同步,这段时间内整个零碎的数据将不统一。

综合思考,在失常状况下的传输提早和异常情况下的传输中断都会导致系统在某个工夫点或时间段内的数据不统一,从而影响业务。然而,如果齐全不做冗余,整个零碎的高可用性就无奈保障。因而, 存储高可用的难点不在于如何备份数据,而在于如何缩小或躲避数据不统一对业务造成的影响

在分布式系统畛域,有一个驰名的 CAP 定理,从实践上证实了存储高可用的复杂度。也就是说,存储高可用不可能同时满足“一致性、可用性、分区容错性”,最多只能满足其中两个。因而,在架构设计时,须要依据理论业务需要进行取舍。

高可用状态决策

无论是计算高可用还是存储高可用,其根底都是“ 状态决策 ”,即零碎须要可能判断以后的状态是失常还是异样,如果出现异常就须要采取行动来保障高可用。如果状态决策自身存在谬误或偏差,那么后续的任何口头和解决都将失去意义和价值。然而,在具体实际中,存在一个实质的矛盾:通过冗余实现的高可用零碎,状态决策实质上不可能做到完全正确。以下是对几种常见的决策形式的详细分析:

1. 独裁式

独裁式决策指的是存在一个独立的决策主体,咱们称之为“决策者”,其负责收集信息并做出决策。所有冗余的个体,咱们称之为“上报者”,将状态信息发送给决策者。

独裁式的决策形式不会呈现决策凌乱的问题,因为只有一个决策者,但问题也正是在于只有一个决策者。当决策者自身故障时,整个零碎就无奈实现精确的状态决策。如果决策者自身又做一套状态决策,那就陷入一个递归的死循环了。

2. 协商式

协商式决策指的是两个独立的个体通过交流信息,而后依据规定进行决策, 最罕用的协商式决策就是主备决策

这个架构的根本协商规定能够设计成:

  • 2 台服务器启动时都是备机。
  • 2 台服务器建设连贯。
  • 2 台服务器替换状态信息。
  • 某 1 台服务器做出决策,成为主机;另一台服务器持续放弃备机身份。

协商式决策的架构不简单,规定也不简单,其难点在于,如果两者的信息替换呈现问题(比方主备连贯中断),此时状态决策应该怎么做。

  • 如果备机在连贯中断的状况下认为主机故障,那么备机须要降级为主机,但实际上此时主机并没有故障,那么零碎就呈现了两个主机,这与设计初衷(1 主 1 备)是不合乎的。
  • 如果备机在连贯中断的状况下不认为主机故障,则此时如果主机真的产生故障,那么零碎就没有主机了,这同样与设计初衷(1 主 1 备)是不合乎的。
  • 如果为了躲避连贯中断对状态决策带来的影响,能够减少更多的连贯。例如,双连贯、三连贯。这样尽管可能升高连贯中断对状态带来的影响(留神:只能升高,不能彻底解决),但同时又引入了这几条连贯之间信息取舍的问题,即如果不同连贯传递的信息不同,应该以哪个连贯为准?实际上这也是一个无解的答案,无论以哪个连贯为准,在特定场景下都可能存在问题。

综合剖析,协商式状态决策在某些场景总是存在一些问题的。

3. 专制式

专制式决策指的是多个独立的个体通过投票的形式来进行状态决策。例如,ZooKeeper 集群在选举 leader 时就是采纳这种形式。

专制式决策和协商式决策比拟相似,其根底都是独立的个体之间替换信息,每个个体做出本人的决策,而后依照“ 少数取胜 ”的规定来确定最终的状态。不同点在于专制式决策比协商式决策要简单得多,ZooKeeper 的选举算法 ZAB,绝大部分人都看得云里雾里,更不用说用代码来实现这套算法了。

除了算法简单,专制式决策还有一个固有的缺点:脑裂。这个词来源于医学,指人体左右大脑半球的连贯被切断后,左右脑因为无奈替换信息,导致各自做出决策,而后身材受到两个大脑别离管制,会做出各种奇怪的动作。例如:当一个脑裂患者更衣时,他有时会一只手将裤子拉起,另一只手却将裤子往下脱。脑裂的根本原因是,原来对立的集群因为连贯中断,造成了两个独立分隔的子集群,每个子集群独自进行选举,于是选出了 2 个主机,相当于人体有两个大脑了。

从图中能够看到,失常状态的时候,节点 5 作为主节点,其余节点作为备节点;当连贯产生故障时,节点 1、节点 2、节点 3 造成了一个子集群,节点 4、节点 5 造成了另外一个子集群,这两个子集群的连贯曾经中断,无奈进行信息替换。依照民主决策的规定和算法,两个子集群别离选出了节点 2 和节点 5 作为主节点,此时整个零碎就呈现了两个主节点。这个状态违反了零碎设计的初衷,两个主节点会各自做出本人的决策,整个零碎的状态就凌乱了。

为了解决脑裂问题,专制式决策的零碎个别都采纳“投票节点数必须超过零碎总节点数一半”规定来解决。如图中那种状况,节点 4 和节点 5 造成的子集群总节点数只有 2 个,没有达到总节点数 5 个的一半,因而这个子集群不会进行选举。这种形式尽管解决了脑裂问题,但同时升高了零碎整体的可用性,即如果零碎不是因为脑裂问题导致投票节点数过少,而真的是因为节点故障(例如,节点 1、节点 2、节点 3 真的产生了故障),此时零碎也不会选出主节点,整个零碎就相当于宕机了,只管此时还有节点 4 和节点 5 是失常的。

综合剖析,无论采取什么样的计划,状态决策都不可能做到任何场景下都没有问题,但齐全不做高可用计划又会产生更大的问题,如何选取适宜零碎的高可用计划,也是一个简单的剖析、判断和抉择的过程。

小结

综上所述,我向你剖析了复杂度之高可用,剖析了计算高可用和存储高可用两个场景,给出了几种高可用状态决策形式,心愿对你有帮忙

本文由 mdnice 多平台公布

退出移动版