当前位置: 首页 > 科技观察

终于有人把“高可用”说清楚了!

时间:2023-03-17 21:22:46 科技观察

图片来自Pexels无论是domain、BG、site,虽然范围有大有小,对象不同,但高可用的概念是一样的。今天,我将一点关于高可用的思考和总结的“nPRT公式”分享给大家。本文采用“什么是高可用,为什么是高可用,怎么做高可用,为什么要做,软件风险在哪里”的逻辑进行介绍。高可用性是控制风险的能力。高可用性是一种面向风险的设计,使系统具有控制风险的能力,提供更高的可用性。WhyHighAvailability对于一个公司来说,“WhyHighAvailability”完全可以理解为“公司为什么要(系统)HighAvailability”。以公司为对象,从内部来说,包括:人、软件(物)、硬件(物);从外部看,包括:客户、股东、社会;从自身来看,包括:公司。高可用的前提,并不是一切都100%可靠:一切都在变化(唯一不变的就是变化)。并非所有变体都是100%可靠的。结论:并非一切都是100%可靠的。内在因素,人和事都不是100%可靠的:从人的层面来说:人很可能会犯错误。从软件层面:软件可能有bug。从硬件层面:硬件很可能坏了。从概率分析的角度来看,只要变化足够多,出错的概率就会无限趋向于1。外部因素,没有高可用,对外界影响很大:从客户的角度:没有高可用,客户服务可能会中断。从股东层面:没有高可用,股价可能会下跌。从社会的角度来看:没有高可用性,社会秩序可能会受到影响。根本原因(本质):控制风险。从公司自身角度:控制风险,保护公司价值,避免损害基本面。如何做高可用如何做高可用本质上就是:如何控制风险。风险相关概念风险:指危害在未来发生,但实际上并未发生的可能性,记为r。故障:指危险已经发生或正在发生,是风险变为现实的结果。风险概率:指风险变为失败的概率。用于表示风险触发失败的难易程度,记为P(r)。故障影响范围:指单位时间内故障造成的有害影响,记为R(r)。故障影响持续时间:指故障的持续时间,记为T(r)。故障影响面:指一次故障影响范围乘以故障影响持续时间的总和。这里用断层冲击面表示断层的总破坏程度,记为F(r)。风险预期:是指每个风险成为失败的概率乘以每个风险成为失败后的失败影响面的总和。这里用风险期望来表示风险的潜在危害程度,记为E(r)。风险预期公式根据上一节的定义,可以推导出风险预期公式如下:r代表风险,风险预期会随着风险数量n和P、R、T的增加而递减每种风险的计算,称为nPRT公式。(注:如需引用此公式,请注明出处。)风控4大因素(nPRT)①减少风险数量,n远离风险源头,使其无与风险承担者有联系且与其无关;则风险概率为0,不关心风险发生后的失效影响区域是大还是小,根本不关心。例如:如果实施重大节日活动,整个站点都被屏蔽,则更改次数将大大减少,这是典型的风险减少次数。例如:A系统完全不依赖Oracle,那么A系统就不需要关心Oracle的任何风险,即使美国总统突然紧急宣布立即禁止Oracle在中国使用,系统A无所谓。例如:在最近的COVID-19大流行中,人与人之间的传播非常可怕。如果你今天选择不去上班,那么你今天就不用担心被外面的行人和同事传染了。②降低风险转化为失败的概率(即增加风险转化为失败的难度)。P把风险当成一个对象,为它层层设牌,提高风险转化为失败的门槛和难度。一个空格或一个字符,系统就会挂掉。”这种悲剧很容易发生。例如:B人要对C系统进行改动,可以给B人增加一个变更认证考试,要求离线(或模拟))测试修改的内容,并对修改后的内容进行CR,系统C提供预览修改效果的能力(类似试运行),万一B想恶意修改造成破坏,非粉丝可以加review,C系统可以加防错设计保护等等。比如:以新冠为例,戴口罩,勤洗手,多通风,可以降低感染新冠的概率③为减少故障范围,将R分为大和小,将一个整体分为N个小个体,每个个体相互隔离,单个个体出现问题只影响单个个体,实现小而美。对于例子:分布式架构就是这样的一个模型,中心化的全输,分布式的输n分之一。例如:以新冠为例,网格化管理,限制跨省市流动,跨省必须核酸+隔离14天,有效控制新冠传播。④缩短故障影响的持续时间。故障影响的持续时间由故障发现时间和故障止血时间决定,因此需要早发现、早止血。发现方式分为:事前预警和事后预警。尽最大努力提前预警,为止血争取时间,甚至将风险扼杀在萌芽状态。止血方法分为:切换、回滚、扩容、降级或限流、BUG修复等,当出现故障时,第一要务是快速止血(如切换、回滚、扩容),并且是严禁追根究底;当不能快速止血时,第二要务是减少出血,比如降级、限流。止血效率:自动与手动;一键式与多步操作。尽可能用自动化代替人工操作。如果进行手动操作,尽量做到一键式操作,提高止血速度。例如:对于容量水位,可以在警戒线前画一条警戒线,做到提前预警,从容应对。例如:在分布式应用集群中,当任何一个应用服务器出现问题时,负载均衡器会通过心跳检查自动移除有问题的应用服务器,并将请求转发给其他(热)备份的冗余服务器。举个例子:以新冠为例,但由于每个生命都是独一无二的,没有办法切换,没有办法回滚,也没有办法降级(涉及人道主义),只能慢慢治疗对的药。高可用架构设计的7个核心原则根据nPRT公式,高可用架构设计有7个核心原则:①少依赖原则:尽可能不依赖,越少越好(n)因为所有的事情都不是100%可靠的。当两件事发生关系时,它们就会相互影响,成为彼此的风险。一个问题可能会影响另一个。我们用依赖来指代这里的“关系”。例如:某系统同时依赖Oracle、MySQL、OB三种关系型数据库。少依赖的原则就是改成只依赖最成熟稳定的OB,不依赖Oracle和MySQL。什么场景适合多重依赖?当引入依赖关系(n变大)时,可以减少一个或多个PRT,从而降低整体的E(r)。比如:为了解决DB风险,引入了分布式缓存,只要两者不同时挂了,还是可用的。②弱依赖原则:必须依赖,尽可能弱依赖,越弱越好(P)事物a强依赖事物b,一旦b有问题,那么a也会有问题,两者都会受损。因此,任何强依赖都应该尽可能转化为弱依赖,这样可以直接降低出现问题的概率。例如:交易成功后,交易核心环节需要给用户发放积分;交易核心系统需要依赖积分系统。不会影响交易核心环节。③去中心化原则:鸡蛋不要放在一个篮子里,分散风险(R),拆分成N股;切忌只有一份顾全大局,否则一旦出现问题,影响范围将是100%。例如:所有的交易数据都放在同一个库的同一张表中,万一库宕机,此时所有的交易都会受到影响。举个例子:如果你把所有的钱都买同一只股票,如果这只股票是乐视网就惨了。④均衡原则:平均分散风险,避免失衡(R)。N股最好每股都是平衡的;避免某个份额过大,否则一旦份额过大出现问题,影响范围会过大。例如:有1000个xx应用集群,但是由于引流组件的一个bug,导致所有流量都分流到其中100个,导致负载严重不平衡,最后因为负载无法承受而彻底崩溃。类似的重大故障已经发生过多次。例如:我用全部的钱买了10只股票,其中一只占了99%。如果这只股票是乐视网,那就惨了。⑤隔离原则:控制风险不扩散,不放大(R)每个副本相互隔离;避免影响一个副本的问题和其他问题,传播和传播影响范围。例如:交易数据被拆分成10个数据库和100张表,但它们都部署在同一台物理机上;如果一个表有一个大的SQL填满了网卡,那么10个数据库和100个表都会受到影响。举个例子:我把所有的钱平分买了10只股票,每只占10%,但是这10只股票都是乐视网。比如:上古赤壁之战就是一个典型的反面例子。铁链船引灭隔绝,一场大火烧八十万大军。有隔离级别。隔离级别越高,风险越难扩散,容灾能力越强。例如:一个应用集群由N台服务器组成,部署在同一台物理机上,或者部署在同一机房的不同物理机上,或者部署在同城的不同机房,或者部署在不同的城市,不同的部署代表不同的容灾能力。例如:人类由无数人组成,生活在同一个地球的不同大陆上,这意味着人类不具备行星级别的隔离能力,当地球受到毁灭性影响时,人类不具备灾难恢复能力。隔离原则是一个极其重要的原则,是前面4个原则的前提。如果隔离做得不好,前四项原则是脆弱的,风险很容易扩散,破坏前四项原则的效果。大量真实的系统故障是隔离性差导致的,比如:下线影响线上,下线影响线上,预发布影响生产,一个坏的SQL影响整个数据库(或者整个集群)等等。去中心化、平衡和隔离是控制风险影响范围的三个核心原则。打散拆分成N股,每股平衡,相互隔离。如果一股有问题,影响范围是1/N。⑥无单点原则:必须有冗余或其他版本,有退路(T)。快速止血的方法有换位、回滚、扩张等;rollback和expand是特殊开关,rollback是指切换到某个版本,expansion是指将流量切换到新扩容的机器上。必须要有切换的地方,不能有单点(这里特指强依赖的单点,弱依赖可以降级),必须有冗余备份或者其他版本;单点会限制整体可靠性。假设单点的可靠性假设是99.99%,想提高到99.999%是非常困难的,但是如果没有单点而是靠两个(一个失效没关系,只要不失效就行)同时挂起),则整体可靠性为99.999999%会有质的提升。单点故障会导致无法快速止血,延长整个止血时间。去单点很重要。这里的单点不仅仅指系统节点,还包括人员,比如订阅告警的人,应急人员等等。对于(重要的)数据节点,必须满足无单点原则,否则极端情况下数据可能永久丢失,永远无法恢复;在(重要的)数据节点满足无单点原则后,保证数据一致性比可用性要求更重要。例如:一个商户只支持一个支付通道,就是典型的单点。如果支付通道被暂停,则无法支付。例如:一个家庭的所有收入仅取决于父亲的工资收入。如果父亲生病了,就没有收入。无单点原则与去中心化原则的区别:节点无状态时,打散分成N份,各份功能相同,互为冗余,即当节点是stateless,去中心化原则和等价的单点原则,满足一个就行。当节点有状态时,被分成N份,每一份都不一样,每一份都没有冗余。每个share都需要做冗余,即节点有状态时,既满足去中心化原则,也必须满足单点原则。⑦自保原则:少流血,牺牲一部分,保护另一部分(P&R&T)。外部输入并不是100%可靠的,有时是无意的失误,有时甚至是恶意破坏,所以对于外部输入一定要有防错设计,给自己更多的保护。在极端情况下,可能无法(快速)止血。您可以考虑减少出血并牺牲一部分以保护另一部分。例如:限流、降级等例如:大促高峰期,会提前降级很多功能,同时限流,主要是为了保障交易和支付体验大多数人在高峰期。例如:人体在失血过多或疼痛过大时会触发休克,这也是一种典型的自我保护机制。软件风险在哪里?之前介绍过风险控制的方法。回到软件系统领域,它的风险在哪里?以软件系统为对象,从内部包括:计算系统和存储系统;从外部看,包括:人员、硬件、上游系统、下游系统;和(隐含地)时间。由于每个对象都是由其他对象组成的,所以每个对象都可以进一步分解(理论上可以无限分解)。上面的分解方法主要是为了简化理解。软件系统风险的来源风险来自于(危险的)变化,一个对象的风险来自于与其相关的所有对象的(危险的)变化。因此,软件系统风险的来源分为以下七类:①计算系统变化:运行缓慢、运行错误服务器资源(如CPU、MEM、IO等)、应用资源(RPC线程数、DB连接数等),业务资源的负载(业务ID全,余额不足,业务配额不足等)会影响系统运行的风险预期。②存储系统变化:变慢、运行错误、数据错误服务器资源(如CPU、MEM、IO等)、存储资源(并发数等)、数据资源(单库容量、单表容量等))系统所依赖的)负载和数据一致性会影响存储系统运行的风险预期。③人员变更:变更出错人数、安全生产意识、熟练程度、变更次数、变更方式等都会影响变更的风险预期。由于改的人多,改的次数多,所以改成了Ant所有故障的TOP1源,这也是“改三招”名声在外的原因。“三轴变革”的正确顺序应该是“灰度化、可监控化、应急化”;grayscale是R,monitorable和emergency是T。思考:如果改变三个trick让你又增加一个trick,你觉得应该是什么?④硬件变更:硬件损坏的数量、质量、使用寿命、维护等会影响硬件的风险预期,硬件损坏会影响上层软件系统。使用。⑤上游变化:请求变大请求分为三个维度:网络流量(由无数API组成)、API(由无数KEY请求组成)、KEY。网络流量过大会造成网络拥塞,影响网络通道中的所有网络流量请求。过多的API请求会使相应的服务集群不堪重负,影响整个服务机器上的所有API请求,甚至向外扩散。过多的KEY请求(俗称“热KEY”)会造成单机超载,影响单机所有KEY请求,甚至向外扩散。因此,在提升安全性时,不仅要关注核心API的容量保障,还需要考虑网络流量和热点key。⑥下游变化:反应迟缓、反应错误下游服务的数量、服务水平、服务可用性等影响下游服务的风险预期。下游响应慢会拖慢上游,下游响应错误会影响上游运行。⑦时间变化:时间到期时间到期往往被人们忽略,但它往往是突然的,具有全局破坏性。一旦时间到期触发故障,会导致非常被动,所以需要提前识别并预警,如:秘钥到达周期,证书到期,费用到期,时区,年份,月、日等。例如:2019年日本运营商软银因证书过期导致3000w用户通信中断长达4小时。以上每一大类风险都可以根据nPRT公式一一分析。险数:人生三合一,人生三件事,任何一件事都是由其他事物组成,又是其他事物的一部分,无限循环下去;三合一人生,人生三事,数不胜数。向内看,可以无限小;当原子粒度问题扩散开来,也可能会影响软件系统的可用性,就像100纳米的新冠病毒会影响人体的可用性一样。向外看,有外面,可以无穷无尽;当太阳系毁灭,软件系统的可用性自然也就不复存在了。风险虽然层出不穷,但只要我们对风险有更好的认识,就可以根据一些风险控制的理念和原则,更好地降低风险预期。再说敬畏:我们对世界的认识是有限的,这也让我们不那么害怕,也让我们不那么敬畏。我们真正要敬畏的不是处罚条例,而是我们不知道的,不知道的不知道。结论总结如下:万物皆变。并非一切都是100%可靠的。所以才会有风险,风险是看不见的,失败是看得见的。风险无法消除,但可以远离和降低。失败是不可避免的,但可以推迟,可以缩小影响范围,缩短影响时间。nPRT公式不仅适用于软件系统风险,也适用于其他风险领域。希望对大家有用。作者:乐洋编辑:陶佳龙来源:转载自公众号阿里科技(ID:ali_tech)