当我们在聊高可用时,我们其实在聊什么?
高可用可以说是分布式系统中最常谈到的词之一,那么我们在聊高可用时,我们其实在聊什么?本文将通过问答的形式抛砖引玉,其中不会涉及过多的技术细节,旨在为企业的系统高可用建设提供一些参考思路和启发。
概念篇
什么是高可用性
什么是高可用性?可能要先定义什么是可用性。维基百科中的定义: 可用性是指一个系统处在可工作状态的时间的比例。简单讲,在一个给定的时间间隔内,对于一个功能个体来讲,总的可用时间所占的比例。
那么,很明显的,高可用性指系统通过高可用设计,趋近于 100%的保证系统的高度可用。其中,无论用于描述和统计系统当前的高可用程度,还是用于设计未来的理论状况,高可用性的评价都需具备时间维度,否则没有约束意义。
可用性设计的对象
那么可用性设计的对象是谁?有的同学认为是服务,因为向用户交付的永远是服务,服务高可用才具备价值;也有同学说是系统,因为最终要将高可用设计落地到整体系统中;还有同学认为是架构,因为合理的架构是保障高可用的基础,高可用设计本身也常以架构的形式讨论。此处仁者见仁,不过架构师通常会通过整体架构,提纲挈领的将应用、组件、平台等进行高可用方面的组织和规划。
高可用指标
云厂商最常用的对服务高可用性进行约束和描述的是 SLA(Service-level Agreement),它是服务供应商将一系列约定的高可用指标放入合同中,与客户达成的正式(具有法律约束力)或非正式的协议。其中包含服务类型、性能水平、可靠性、响应性,以及故障发生的解决方案和其它规定等。
常见的可用性评价指标:
MTBF:Mean Time Between Failure,平均故障间隔时间。
MTTR:Mean Time To Repair,平均恢复前时间。
MTTF:Mean Time To Failure,修复前平均时间。
SA:Service Available,如下图所示,列出了“N 个 9”各代表的故障时间。每多一个 9,都代表着落地难度指数级增长,同时可用此公式计算:SA = MTBF/(MTBF + MTTR)。
RPO:Recovery Point Objective,恢复点目标。
RTO:Recovery Time Objective,恢复时间目标。
国家《信息安全技术-信息系统灾难恢复规范》也对信息系统的 RPO 和 RTO 做出要求:
高可用设计理论
CAP:Consistency、Availability、Partition tolerance,此理论人尽皆知,最终会在 CP 和 AP 中权衡,找到满足 BASE(Basically Available、Soft state、Eventually consistent)的平衡结果。
高可用设计要素
冗余:确保对系统操作至关重要的任何元素都有一个额外的冗余组件,这些组件可以在发生故障时接管。
监控:从正在运行的系统中收集数据,并检测组件何时发生故障或停止响应。
故障转移:一种手动或自动机制。如果监控显示活动组件发生故障,该机制可以从当前活动的组件切换到冗余组件。
上述三要素逻辑也很清晰:要实现高可用,不管是否存在状态,要先有冗余或备份;当真正出现故障的时候,要有监控手段监控到故障发生;故障发生后,可以通过故障转移组件快速转移到之前的冗余组件中,保证服务不中断。
问答篇
以上简单介绍了可用性相关概念,下面通过问答形式进行探讨,供大家发散思考。
Q: 高可用做起来成本大、难度高,到底值不值得?
A: 我们在做高可用建设时,其实就像在给系统买“保险”。买了不一定用的上,有时候可能还不希望用上,但是不买自己又不放心。对于大型系统,动辄上百、千万的资产投入,其实为的只是保障那千分之一,甚至万分之一的故障几率。
但保险也有“贵贱”,就像社保和重疾险,除了价格不同,应用场景和起到的作用也不同。在做高可用设计时也是同理,核心系统或组件往往需要更多的冗余、更全面的监控、更自动化的故障切换做保障。如对订单系统的用户数据的保障就需要买“重疾险”,因为一旦出了问题可能丢掉身家性命。而对管理运营端的系统日志,买“社保”更合适一些,即使数据丢失,影响也是可控的。
另外关注一点,高可用建设是系统性工程,整体高可用保障水平取决于功能单元链条中水平最低的那个,比如微服务网关如果欠缺弹性伸缩和限流能力,那未知流量洪峰到来后网关已经挂掉了,之后的核心服务做再多的弹性和限流都无济于事。
对于值得不值得,公司不仅花钱买到了一堆资产,还买到了安全感,更买到了用户对公司无价的信任,只要规划在合理范围内,这笔买卖的性价比就非常高。
Q: 可用性与分布式架构其它四个要素(高性能、可扩展、可伸缩、安全性)以及业务之间是什么关系?
A: 分布式架构设计的五要素之间是互相关联的,在整体架构设计中,应该且需要一起讨论。以高可用为例,冗余不仅为架构内功能单元提供备份,辅以负载均衡也会提高功能单元的访问性能,同时也满足了 AKF 扩展立方体(Scalability Cube)中水平扩展的要求。
另外,五要素能力建设是随着架构演进一步步增强的。从单服务+单体应用的强耦合开始,将应用、数据库、文件服务器等拆分到独立服务器,保证了各自的高可用和性能;通过集群、负载均衡、无状态既解决了高并发的问题,又满足了架构的可伸缩、高性能、高可用的需求;将数据库、文件系统、缓存、大数据、搜索引擎等改造为分布式架构,又进一步提高了整体架构的高性能、高可用、可扩展水平。最后随着容灾和业务拆分的需求,逐渐演化为多地多中心及单元化架构,高可用、可扩展水平又一次提升。
可以看到业务的发展是架构演进的重要驱动力之一,它一步步推动着分布式架构各要素水平不断提升。高可用在每次架构锐变都是必须考量的,同时成本也是比较大的。那么,企业上云,将最大的成本交给云厂商,也是一个不错的选择。
Q: 容错、高可用、灾难恢复有什么区别?
A: 容错指系统运行过程中,即使某部分功能单元故障,也可以继续运行,关键在“容忍”部分故障。高可用指系统在故障发生时可以用极少的时间恢复业务运行,需要的中断时间越短高可用性等级越高,其关键在“快速”的恢复能力。灾难恢复指当灾难发生时,可以切换业务、数据到其它地域进行恢复,关键在通过“切换”实现恢复,这里注意灾难恢复不是为了挽救基础设施,而是为了挽救业务或数据。此处可参考下图中业务连续性管理的国际标准 PDCA 循环模型:
Q: 高可用方案设计需要从哪些角度讨论和思考?
A: 首先,应用侧、支撑侧、运维侧的设计方式方法不同。应用侧高可用除了可以通过上述提到的冗余、集群、负载均衡等做到快速的故障转移,还包括熔断、限流、容错、降级、应急等保障手段,框架组件的超时及重试策略、异步调用、幂等性设计来补充。支撑侧(或称基础设施平台)需要一整套高可用相关的监控指标,满足故障的提前预警、快速报警、可视化监控和分析。常见指标包括请求量、请求错误率、平均延时、HTTP 状态,以及系统资源消耗相关指标等。
另外支撑侧自身组件本质上也是应用,所以也需要上述应用侧的方法保证自身高可用,尤其在多地多中心架构中,支撑侧要配合应用侧做整体高可用适配。运维侧中关键一点是 DevOps,自动化发布、灰度发布、优雅发布、版本控制、健康检查等能力,可以在业务发生故障前和发生故障时,帮助应用最大程度减小服务不可用时长。
其次,公有云与私有云的高可用方案差异很大。公有云落地过程中,主要由云厂商提供基础设施高可用保障和最佳实践。私有云落地场景有较大差异,确定高可用方案时各干系人(客户侧、云厂商侧、开发商侧各角色)是有各自诉求的,那么高可用方案本身就可能因非技术原因变更。
客户希望云厂商根据高可用要求提供合适的可落地执行的高可用方案建议,ISV 希望高可用方案尽量少的影响当前业务开发和后续变更,云厂商希望尽量基于产品现有能力扩展,减少定制化开发。所以,沟通的过程中往往会出现僵持,比如云厂商经常成为客户需求和疑难问题的兜底人,给云厂商带来不小的成本。所以,方案沟通过程就可能演变成多方利益权衡妥协的过程,高可用方案也会在互相妥协中不断变化,直到各方达成统一。
最后,高可用方案中应当包含应用相关内容。有部分同学认为高可用方案只跟架构部门有关,应用的代码质量、技术选型等不重要,甚至有时在激烈讨论时可能听到“这种非功能性需求不应该全部由架构部解决吗”“代码的问题不需要基础支撑部门过多参与”。原因可能是基础架构师在一些团队中,并不像研发经理一样对应用直接管理。
举几个例子:开发人员上传 excel 没有做文件大小检查,当用户上传过大 excel 文件就会导致前台应用 OOM;操作数据库时 SQL 没有加 limit 限制,当搜索时间过长时,数据库会一次性返回几十万条数据;由于开发人员比较熟悉 Struts 而未选用 SpringMVC,导致 Struts 安全漏洞被利用;虽然上述神操作可能都是低级错误,但管中窥豹,在高可用建设的过程中,应用的整体质量会对整体高可用产生直接影响,基础支撑组件可以帮助应用发现问题,但不能避免问题产生。要想真正保证高可用,势必要在应用质量等相关联的部分多下功夫。
Q: 业务应用开发中有没有一些通用的方法提高应用自身的质量和高可用水平?
A: 此处略过测试向的质量保证方法和编码技能提升这类需要建设时间的方面,主要几点拿来即用的建议。
第一,应用系统最主要的敌人之一是复杂性,那么使复杂性增强的主要原因呢?是耦合,尤其是内容耦合(业务逻辑)、数据耦合(参数和数据库)、外部耦合(外部依赖)。面对耦合其实有一项利器——消息队列,通过消息队列可以让同步变异步,减少业务逻辑之间的耦合度,让数据拆分更容易实现,标准化外部依赖的通讯接口。
第二,如果不能了解、分析应用目前和过去的运行状况,我们就很难预防未来未知问题的发生。这就需要我们建立功能完备、高度可视化的监控平台,帮助开发及运维人员及时发现和快速定位问题。
第三,基础支撑组件可以支撑应用版本化、配置版本化、SQL 版本化、服务优雅上下线等能力,一旦生产环境出现问题可以及时的回滚到原先版本。
第四,基础支撑平台应具备鉴权、路由、限流、熔断、容错等服务治理能力,这些能力可帮助应用的高可用水平上升一个台阶。没有服务鉴权,就可能被非法服务内部攻击;没有服务限流,就可能在流量浪涌中瞬间宕机;没有服务路由,就很难做到灰度发布、A/B 测试等;没有服务熔断,一旦上游服务出现问题,下游服务就可能产生连锁反应。
Q: 如何检测高可用方案落地是否达到预期?
A: 全链路故障演练,是一种检测高可用方案是否符合预期的常用方法。其本身可能还包括一些细分部分,如应急方案、降级方案、演练人员安排、演练场景及用例、演练环境准备、演练结果复盘等,通过多次演练锻炼团队的处理故障能力并检验相关流程。另外,实际落地故障演练会消耗大量人力、物力,这对高可用要求不高的中小企业很不友好。但并不能因为成本高就放弃演练,做不到故障对用户完全无感知,至少保证核心链路可用,最差也要保证持久化数据完整一致。同时,可通过监控平台对各功能单元的监控数据,分析链路中可能存在的隐患。
结语
在架构演进过程中,高可用是一个始终绕不开的话题,本文对高可用建设的部分问题进行了片面的讨论。尤其近些年云原生趋势明显,又会给高可用设计带来哪些机遇与挑战?我们需不断迎难而上,进行突破和创新,持续探索更优秀的高可用设计方案。
评论