高性能网站高可用架构-设计基础及FMEA简介

不要尝试着去避免故障,而是要把处理故障的代码当成正常的功能做在架构里写在代码里。

高可用是一种面向风险设计,使系统具备控制风险,提供更高的可用性的能力。网站页面能完整呈现在最终用户面前,需要经历很多环节,任何一个环节出现了问题出了问题,都可能导致网站页面不可访问,所以在架构设计的时候很可能遗漏某个环节的高可用设计,这也就让那个高可用变成了最为复杂的架构设计点。

架构的高可用,就意味着实现系统中所有元素、连接的高可用。在用户眼里,业务永远是正常(或基本正常)对外提供服务的。在物理实例层面主要表现为冗余和集群设计,在代码逻辑层面,方法则多种多样。当资源和精力不足以实现全链路高可用时,提供“降级服务”和“熔断服务”,优先保证高可用,其次保证高可靠。企业里面有些核心服务是不能降级的,对于这类服务,就一定要通过研发流程管理,确保服务的高可用、高可靠。

1.高可用简介

(1)为什么要做高可用

高可用的大前提:所有事物都不是100%可靠的

  • 从人的层面:人都是有可能犯错的。
  • 从软件层面:软件都是有可能有BUG的。
  • 从硬件层面:硬件都是有可能会坏的。
  • 不可抗力:地震,水灾,火灾


 

(2)高可用影响计算公式

E(r)=nPRT

  • 风险:指未来会发生危害的一种可能性,但实际未发生,记为r。
  • 风险概率:指一个风险变故障的概率。用它来表示风险触发为故障的难易程度,记为P(r)。
  • 故障影响范围:指在单位时间内,一个故障造成的危害影响,记为R(r)。
  • 故障影响时长:指一个故障持续的时间,记为T(r)。
  • 风险期望:指每个风险变故障的概率乘以每个风险变故障后的故障影响面的总和。这里用风险期望来表示风险的潜在危害程度,记为E(r)。

①减少风险数量,n

从源头远离风险,做到与风险载体无连接,无关系;那么该风险概率就是0,也不关心该风险发生后的故障影响面是大是小,完全不关心。

  • 例如:重大节日活动,施行全站封网,变更的数量就会得到一个明显的下降,就是典型的减少风险数量。
  • 例如:系统A完全不依赖Oracle,那系统A就不用关心Oracle的任何风险,哪怕美国突然紧急宣布Oracle立即立刻禁止在中国使用,系统A也无所谓。
②降低风险变故障的概率(即:增加风险变故障的难度),P

把风险当成一个对象看待,给它层层设卡,增加风险变故障的门槛和难度,不要再让“不小心多了一个空格或字符,系统就挂了”这种惨案轻易出现。

例如:人员B要对系统C进行变更,可以对人员B增加变更认证考试,对变更内容要求线下(或仿真)测试,对变更内容进行CR,系统C提供变更效果预览能力(类似监控模式或试运行),万一人员B想恶意变更搞破坏,还可以增加非同人复核,系统C可以增加防错设计进行保护等等。

③减小故障影响范围,R

以大拆小,将一个整体拆分成N个小的个体,每个个体之间进行相互隔离,单个个体出问题仅影响单个个体,实现小而美。例如:分布式架构就是这个的典范,集中式一损俱损,分布式一损即N分之一损。

④缩短故障影响时长,T

故障影响时长由故障发现时间和故障止血时间决定,所以要早发现早止血。发现方式分为:事前的预警,事后的告警。尽可能朝事前预警去做,给止血争取时间甚至将风险扼杀在摇篮中。

止血方式分为:切换,回滚,扩容,降级 or 限流,BUG修复等。故障出现时第一优先原则为快速止血(如切换、回滚、扩容),严禁去定位根因;当无法快速止血时以少流血为第二优先原则,如降级、限流。

止血效率:自动 vs 人工 ;一键化 vs 多步操作。尽可能用自动化去代替人工操作,若人工操作时尽量实现一键化,提升止血速度。

  • 例如:对于容量水位,可以在警戒线之前划一条预警线,提前预警,从容应对。
  • 例如:分布式应用集群,任何一台应用服务器有问题时,负载均衡会通过心跳检查自动把有问题的应用服务器剔除,将请求转发给其他(热)备份冗余的服务器上。


 

(3)可用性风险

  • 计算系统变化:运行变慢,运行错误。系统运行所依赖的服务器资源(如CPU,MEM,IO等),应用资源(RPC线程数,DB连接数等),业务资源(业务ID满了,余额不足,业务额度不够等)的负载等都会影响系统运行的风险期望。
  • 存储系统变化:运行变慢,运行错误,数据错误。系统运行所依赖的服务器资源(如CPU,MEM,IO等),存储资源(并发数等),数据资源(单库容量,单表容量等)的负载和数据一致性等都会影响存储系统运行的风险期望。
  • 程序、人的变化:变更出错。线上系统最容易出现问题的原因就是程序的变更,这里程序的变更包括需求的变更和bug的修复。bug修复有20%——50%引入新的bug,因为往往修复局部问题的时候很难考虑到修复该问题是否会对其它功能产生影响,所以回归测试很重要。这也是为什么“变更三板斧”这么出名的原因,“变更三板斧”正确的排序应该是“可灰度,可监控,可应急”;可灰度代表的是R,可监控和可应急代表的是T。
    • 没有按照既定流程操作:比如一个同学在封网期间,由于自信而跳过审批环节进行变更,最终引发线上故障。
    • 忽略测试环节:一个同学感觉代码的变化很小就省略线下环境测试,直接在生产环境部署了新代码,最终恰恰是这个很小的变更引发了故障。
    • 没有关注监控:在小流量测试阶段忽视了对关键指标的观察,未能及时发现指标变化,可能导致全面部署后故障大规模爆发。
    • 变更比较随意:团队成员可以在任何时间进行变更,这不仅增加了变更的频率,而且由于变更时间的分散,难以确保所有相关人员都能及时响应,从而可能加剧了系统故障的风险。
  • 硬件变化:损坏。硬件的数量,质量,使用年限,保养等都会影响硬件的风险期望,硬件损坏会影响上层软件系统不可用。
  • 上游变化:请求变大。请求分为3个维度:(由无数API汇集而成的)网络流量,(由无数KEY请求组成的)API,KEY。网络流量过大会造成网络堵塞,影响网络通道中的所有网络流量请求。API请求过大会造成对应服务集群过载,影响整个服务机器上的所有API请求,甚至往外传播。以大促保障的时候,不仅仅是关注核心API的容量保障,还需要考虑网络流量和热点KEY。
  • 下游变化:响应变慢,响应错误。下游服务的数量,服务等级,服务可用率等影响下游服务的风险期望。下游响应变慢可能会拖慢上游,下游响应错误可能会影响上游运行结果。
  • 时间变化:时间到期。时间到期往往被人忽视,但它往往具有突然性和全局破坏性,一旦时间到期触发故障会导致非常被动,所以要提前识别,尽早预警,如:秘钥到期,证书到期,费用到期,跨时区,跨年,跨月,跨日等。

2.网站可用性度量

网站不可用也被称为网站故障,业界通常用多少个9来衡量网站的可用性,如qq的可用性是4个9,即qq服务为99.99%可用,这意味QQ服务要保证其在所运行时间中,只有0.01%的时间不可用。

对于大多数网站而言,2个9是基本可用,3个9是较高可用,4个9是具有自动恢复能力的高可用,5个9是级高可用,所以对于大多数网站达到2个9也就基本可以。

到达五个九之后,故障就不能靠人力恢复了。想象一下,从故障发生到你接收报警,再到你 打开电脑登录服务器处理问题,时间可能早就过了十分钟了。所以这个级别的可用性考察的 是系统的容灾和自动恢复的能力,让机器来处理故障,才会让可用性指标提升一个档次。
 

(1)可用性测量

①探针模拟

从客户端侧,模拟用户的调用行为。

  • 优点:数据真实(客户端角度)
  • 缺点:数据不全面(单一客户数据)

②服务端采集

从服务端侧,直接分析日志和数据。

  • 优点:覆盖所有调用数据。
  • 缺点:缺失客户端链路数据。

对可用性数据要求较高的系统,也可以同时运用上述两种方式,建议结合你的业务场景综合评估选择。

(2)可用原则

应该关注 RT 的数据分布(如:p50/p99/p999 分位点),而不是平均值(mean) —— 平均值并没有太大意义,更应该去关注你那 1%、0.1% 用户的准确感受。不要尝试承诺和优化可用性到 100% —— 一方面是无法实现,存在太多客观不可控因素;另一方面也没有意义,客户几乎关注不到 0.001% 的可用性差别。

3.系统故障点

客户端在远程发起请求,经过接入系统处理后,请求被转发给应用系统;应用系统调 用服务完成具体的功能;在这个过程中,应用和服务还会访问各种资源,比如数据库和缓 存。这里用红色部分,标识出了整个处理过程中可能出现的故障点

  • 资源不可用,包括网络和服务器出故障,网络出故障表明节点连接不上,服务器出故障 表明该节点本身不能正常工作。
  • 资源不足,常规的流量进来,节点能正常工作,但在高并发的情况下,节点无法正常工 作,对外表现为响应超时。
  • 节点的功能有问题,这个主要体现在我们开发的代码上,比如它的内部业务逻辑有问 题,或者是接口不兼容导致客户端调用出了问题;另外有些不够成熟的中间件,有时也 会有功能性问题。

4.保证系统可用性根本策略

  • 冗余备份。任何程序、任何数据,都至少要有一个备份,也就是说程序至少要部署到两台服务器,数据至少要备份到另一台服务器上。此外,稍有规模的互联网企业都会建设多个数据中心,数据中心之间互相进行备份,用户请求可能会被分发到任何一个数据中心,即所谓的异地多活,在遭遇地域性的重大故障和自然灾害的时候,依然保证应用的高可用。
  • 失效转移。当要访问的程序或者数据无法访问时,需要将访问请求转移到备份的程序或者数据所在的服务器上,这也就是失效转移。失效转移最重要的就是失效的鉴定。
  • 限流和降级。可以拒绝部分请求,即进行限流;也可以关闭部分功能,降低资源消耗,即进行降级。

5.高可用设计方向

  • 架构阶段:架构阶段主要考虑系统的可扩展性和容错性,要避免系统出现单点问题。例 如多机房单元化部署,即使某个城市的某个机房出现整体故障,仍然不会影响整体网站 的运转。
  • 编码阶段:编码最重要的是保证代码的健壮性,例如涉及远程调用问题时,要设置合理 的超时退出机制,防止被其他系统拖垮,也要对调用的返回结果集有预期,防止返回的 结果超出程序处理范围,最常见的做法就是对错误异常进行捕获,对无法预料的错误要 有默认处理结果。
  • 测试阶段:测试主要是保证测试用例的覆盖度,保证最坏情况发生时,也有相应的 处理流程。
  • 发布阶段:发布时也有一些地方需要注意,因为发布时最容易出现错误,因此要有紧急 的回滚机制。并且发布过程成一定要保证无流量进入,否则和宕机没有任何区别。
  • 运行阶段:运行时是系统的常态,系统大部分时间都会处于运行态,运行态最重要的是 对系统的监控要准确及时,发现问题能够准确报警并且报警数据要准确详细,以便于排 查问题。
  • 故障发生:故障发生时首先最重要的就是及时止损,例如由于程序问题导致商品价格错 误,那就要及时下架商品或者关闭购买链接,防止造成重大资产损失。然后就是要能够 及时恢复服务,并定位原因解决问题。

6.FMEA简介

1.FMEA简介

FMEA(Failure mode and effects analysis,故障模式与影响分析)又称为失效模式与后果分析、失效模式与效应分析、故障模式与后果分析等,专栏采用“故障模式与影响分析”,因为这个中文翻译更加符合可用性的语境。FMEA 是一种在各行各业都有广泛应用的可用性分析方法,通过对系统范围内潜在的故障模式加以分析,并按照严重程度进行分类,以确定失效对于系统的最终影响。FMEA 并不能指导我们如何做架构设计,而是当我们设计出一个架构后,再使用 FMEA 对这个架构进行分析,看看架构是否还存在某些可用性的隐患。

在架构设计领域,FMEA 的具体分析方法是:

  • 给出初始的架构设计图。
  • 假设架构中某个部件发生故障。
  • 分析此故障对系统功能造成的影响。
  • 根据分析结果,判断架构是否需要进行优化。

FMEA 分析的方法其实很简单,就是一个 FMEA 分析表,常见的 FMEA 分析表格包含下面部分。

(1)功能点

当前的 FMEA 分析涉及的功能点,注意这里的“功能点”指的是从用户角度来看的,而不是从系统各个模块功能点划分来看的。例如,对于一个用户管理系统,使用 FMEA 分析时 “登录”“注册”才是功能点,而用户管理系统中的数据库存储功能、Redis 缓存功能不能作为 FMEA 分析的功能点。

(2)故障模式

故障模式指的是系统会出现什么样的故障,包括故障点和故障形式。需要特别注意的是,这里的故障模式并不需要给出真正的故障原因,我们只需要假设出现某种故障现象即可,例如 MySQL 响应时间达到 3 秒。造成 MySQL 响应时间达到 3 秒可能的原因很多:磁盘坏道、慢查询、服务器到 MySQL 的连接网络故障、MySQL bug 等,我们并不需要在故障模式中一一列出来,而是在后面的“故障原因”一节中列出来。因为在实际应用过程中,不管哪种原因,只要现象是一样的,对业务的影响就是一样的。

此外,故障模式的描述要尽量精确,多使用量化描述,避免使用泛化的描述。例如,推荐使用“MySQL 响应时间达到 3 秒”,而不是“MySQL 响应慢”。

(3)故障影响

当发生故障模式中描述的故障时,功能点具体会受到什么影响。常见的影响有:功能点偶尔不可用、功能点完全不可用、部分用户功能点不可用、功能点响应缓慢、功能点出错等。

故障影响也需要尽量准确描述。例如,推荐使用“20% 的用户无法登录”,而不是“大部分用户无法登录”。要注意这里的数字不需要完全精确,比如 21.25% 这样的数据其实是没有必要的,我们只需要预估影响是 20% 还是 40%。

(4)严重程度

严重程度指站在业务的角度故障的影响程度,一般分为“致命 / 高 / 中 / 低 / 无”五个档次。严重程度按照这个公式进行评估:严重程度 = 功能点重要程度 × 故障影响范围 × 功能点受损程度。同样以用户管理系统为例:登录功能比修改用户资料要重要得多,80% 的用户比 20% 的用户范围更大,完全无法登录比登录缓慢要更严重。因此我们可以得出如下故障模式的严重程度:

致命:超过 70% 用户无法登录。

高:超过 30% 的用户无法登录。

中:所有用户登录时间超过 5 秒。

低:10% 的用户登录时间超过 5 秒。

中:所有用户都无法修改资料。

低:20% 的用户无法修改头像。

(5)故障原因

“故障模式”中只描述了故障的现象,并没有单独列出故障原因。主要原因在于不管什么故障原因,故障现象相同,对功能点的影响就相同。那为何这里还要单独将故障原因列出来呢?主要原因有这几个:

①不同的故障原因发生概率不相同

例如,导致 MySQL 查询响应慢的原因可能是 MySQL bug,也可能是没有索引。很明显“MySQL bug”的概率要远远低于“没有索引”;而不同的概率又会影响我们具体如何应对这个故障。

②不同的故障原因检测手段不一样

例如,磁盘坏道导致 MySQL 响应慢,那我们需要增加机器的磁盘坏道检查,这个检查很可能不是当前系统本身去做,而是另外运维专门的系统;如果是慢查询导致 MySQL 慢,那我们只需要配置 MySQL 的慢查询日志即可。

③不同的故障原因的处理措施不一样

例如,如果是 MySQL bug,我们的应对措施只能是升级 MySQL 版本;如果是没有索引,我们的应对措施就是增加索引。

(6)故障概率

这里的概率就是指某个具体故障原因发生的概率。例如,磁盘坏道的概率、MySQL bug 的概率、没有索引的概率。一般分为“高 / 中 / 低”三档即可,具体评估的时候需要有以下几点需要重点关注。

①硬件

硬件随着使用时间推移,故障概率会越来越高。例如,新的硬盘坏道几率很低,但使用了 3 年的硬盘,坏道几率就会高很多。

②开源系统

成熟的开源系统 bug 率低,刚发布的开源系统 bug 率相比会高一些;自己已经有使用经验的开源系统 bug 率会低,刚开始尝试使用的开源系统 bug 率会高。

③自研系统

和开源系统类似,成熟的自研系统故障概率会低,而新开发的系统故障概率会高。

高中低是相对的,只是为了确定优先级以决定后续的资源投入,没有必要绝对量化,因为绝对量化是需要成本的,而且很多时候都没法量化。例如,XX 开源系统是 3 个月故障一次,还是 6 个月才故障一次,是无法评估的。

(7)风险程度

风险程度就是综合严重程度和故障概率来一起判断某个故障的最终等级,风险程度 = 严重程度 × 故障概率。因此可能出现某个故障影响非常严重,但其概率很低,最终来看风险程度就低。“某个机房业务瘫痪”对业务影响是致命的,但如果故障原因是“地震”,那概率就很低。例如,广州的地震概率就很低,5 级以上地震的 20 世纪才 1 次(1940 年);如果故障的原因是“机房空调烧坏”,则概率就比地震高很多了,可能是 2 年 1 次;如果故障的原因是“系统所在机架掉电”,这个概率比机房空调又要高了,可能是 1 年 1 次。同样的故障影响,不同的故障原因有不同的概率,最终得到的风险级别就是不同的。

(8)已有措施

针对具体的故障原因,系统现在是否提供了某些措施来应对,包括:检测告警、容错、自恢复等。

①检测告警

最简单的措施就是检测故障,然后告警,系统自己不针对故障进行处理,需要人工干预。

②容错

检测到故障后,系统能够通过备份手段应对。例如,MySQL 主备机,当业务服务器检测到主机无法连接后,自动连接备机读取数据。

③自恢复

检测到故障后,系统能够自己恢复。例如,Hadoop 检测到某台机器故障后,能够将存储在这台机器的副本重新分配到其他机器。当然,这里的恢复主要还是指“业务”上的恢复,一般不太可能将真正的故障恢复。例如,Hadoop 不可能将产生了磁盘坏道的磁盘修复成没有坏道的磁盘。

(9)规避措施

规避措施指为了降低故障发生概率而做的一些事情,可以是技术手段,也可以是管理手段。例如:

  • 技术手段:为了避免新引入的 MongoDB 丢失数据,在 MySQL 中冗余一份。
  • 管理手段:为了降低磁盘坏道的概率,强制统一更换服务时间超过 2 年的磁盘。
(10)解决措施

解决措施指为了能够解决问题而做的一些事情,一般都是技术手段。例如:

  • 为了解决密码暴力破解,增加密码重试次数限制。
  • 为了解决拖库导致数据泄露,将数据库中的敏感数据加密保存。
  • 为了解决非法访问,增加白名单控制。

一般来说,如果某个故障既可以采取规避措施,又可以采取解决措施,那么我们会优先选择解决措施,毕竟能解决问题当然是最好的。但很多时候有些问题是系统自己无法解决的,例如磁盘坏道、开源系统 bug,这类故障只能采取规避措施;系统能够自己解决的故障,大部分是和系统本身功能相关的。

(11)后续规划

综合前面的分析,就可以看出哪些故障我们目前还缺乏对应的措施,哪些已有措施还不够,针对这些不足的地方,再结合风险程度进行排序,给出后续的改进规划。这些规划既可以是技术手段,也可以是管理手段;可以是规避措施,也可以是解决措施。同时需要考虑资源的投入情况,优先将风险程度高的系统隐患解决。

例如:

地震导致机房业务中断:这个故障模式就无法解决,只能通过备份中心规避,尽量减少影响;而机柜断电导致机房业务中断:可以通过将业务机器分散在不同机柜来规避。

敏感数据泄露:这个故障模式可以通过数据库加密的技术手段来解决。

MongoDB 断电丢数据:这个故障模式可以通过将数据冗余一份在 MySQL 中,在故障情况下重建数据来规避影响。

2.FMEA 实战

下面以一个简单的样例来模拟一次 FMEA 分析。假设设计一个最简单的用户管理系统,包含登录和注册两个功能,其初始架构是:

初始架构很简单:MySQL 负责存储,Memcache(以下简称 MC)负责缓存,Server 负责业务处理。我们来看看这个架构通过 FMEA 分析后,能够有什么样的发现,下表是分析的样例(注意,这个样例并不完整,感兴趣的同学可以自行尝试将这个案例补充完整)。
 

经过上表的 FMEA 分析,将“后续规划”列的内容汇总一下,最终得到了下面几条需要改进的措施:

MySQL 增加备机。

MC 从单机扩展为集群。

MySQL 双网卡连接。

改进后的架构如下:


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值