本文转自:高可用架构
高并发、高可用、高性能、高可扩展是什么关系?
产品、市场、运营的成功,带来了同时段大量用户对系统的访问,这就是高并发。
高并发本身并不是一种技术的方法,它是系统要面临的一种有技术挑战的场景。
在这个场景下,(工程)技术的核心价值,是确保高并发时的用户体验,具体而言,就是系统不应该发生错误,并且以极快的速度给用户响应。
上面是对问题的定性分析,但定性分析不能帮助我们开展工作,所以还需要能够对问题进行定量分析。
可用性、性能、扩展性就是用于定量分析的三个视角。
可用性的目标,是为了让系统尽可能不发生错误,或者将发生错误后的损失降到最低。
性能的目标,是为了让尽可能多的用户,用尽可能少的时间得到系统的响应。
扩展性的目标,是为了支撑可用性和性能,在一些特殊情况下,不得不对系统结构做出调整时,尽可能以低成本的方式完成。
可用性的度量与拆解
可用性的指标,是系统可用时间在系统运行时间中的占比,业内通常喜欢用N个9的方式描述。但N个9对我们的工作开展没有帮助,因此需要对这个指标进行拆解,便于针对具体场景开展工作。
上图公式中,运行时间是定量,不可用时间是变量,因此只需要对不可用时间进行拆解。
感知变化的发生
如果此刻时间停止,一切都不发生变化,那么系统就不存在不可用问题。因此,不可用的第一个因子就是变化,我们需要能够感知到变化的发生。
第一类变化,是与人相关的,最典型的就是运营市场的活动与技术没有联动,活动带来的瞬间流量增加会让技术的应对非常被动。
第二类变化,是与上下游相关的,比如上游系统对我们的访问量突然提高一个数量级,或者下游系统的失败率突然增高,都会对自己的系统产生比较大的影响。
第三类变化,是与运行环境相关的,硬件的维保信息,健康度指标,软件系统的CPU、网络、IO等资源的使用情况,如果发生突然的变化,也会让系统的可用性面临风险。
第四类变化,是与时间相关的,比如int型时间戳快用完了,证书等资源会有时效,时间分表的表创建等,这一类变化容易被忽视,但一旦发生问题往往影响很大。
第五类变化,自身系统的迭代相关,这个角度的变化,感知是自然的过程。
通过预判降低故障比例
当我们知道变化的发生,下一步,就是根据变化的特征,结合经验,预判变化可能引发的故障,来降低故障发生的比例。
比如常见的CodeReview机制、上线评审机制、CaseStudy机制,就是对经验的复用,QA测试和验证,则是用专业的方法去发现潜在的问题。
降低故障的影响
无论你如何努力,只要时间没有停止,故障就不可避免。
所以,下一个视角就是正视故障,通过提前的架构设计,让故障发生后产生的影响尽可能小。
比如资源隔离,就是希望A业务坏了之后,B业务还能正常运行,对用户而言,这比都坏了好。
读写分离,站在用户的视角,不能发帖子了,但还能看帖子总还是相对好的结果。
数据隔离适用于一些特定场景,比如游戏往往会做区服的数据隔离,这个区的资源故障,其他区的用户还可以正常使用。
滚动发布的思路,是先在小范围用户中发布,验证新引入的变化是否存在问题。
限流、熔断是应对极端情况的保守策略,比如为了不让全部用户都不可用,在达到系统容量上限后不再为更多用户提供服务。
提高故障的恢复速度
故障发生了,我们总是要让他尽快的恢复正常。
但故障的发生究竟是源自什么变化,很多时候是未知的,因此,首先需要的是值班制度,人必须在第一时间介入。
对于我们主动发布的变化,则应该事先准备好快速回滚的方案,以备不时之需。
另外,对于一些相对常规的,可预判的故障点,则可以使用自动化的技术,进行故障转移或扩容。
性能的度量与拆解
性能的度量,主要是考虑完成特定任务目标所需的耗时。任务目标是定量,任务完成耗时是变量。
业内对性能的主要度量指标有平均响应时间、分位值响应时间、QPS、TPS,这是不同角度的观测方法,不影响我们对性能这个目标的拆解。
任务完成的耗时,通常由内存IO时间、网络IO时间、CPU时间、磁盘IO时间、等待时间等组成。前四者是使用某个计算机资源的时间,最后一个是等待某个计算机资源的时间。
对于资源的使用时间,通常可以从下面三个角度进行性能的优化:
1)提高对资源的利用率:一般指自身程序逻辑的优化,或者通过提高并行度压榨更多的CPU资源。
2)用过去或未来换现在的时间:页面静态化,池化技术,预编译等都是提前做一些事情,用过去的时间,来降低用户在线服务的响应时间;另外对于一些在线服务非必须的计算、存储的耗时操作,也可以异步化延后进行处理,这就是用未来的时间换现在的时间。
3)用高速资源换低速资源:常见的是对磁盘数据的缓存,以及对大计算量计算结果的缓存。(参考不同资源的访问速度:https://gist.github.com/jboner/2841832)
最后一个,关于资源等待时间,主要是从不同任务的资源协调角度进行思考。举一个简单的例子,一个多进程方式的php-fpm,如果上传文件的业务和Feed刷新的业务在一起,那么发生比较多文件上传访问时,刷新Feed的用户可能就需要等待空闲的fpm进程。
高性能接入层也是类似的角度,将用户流量接入的工作,从业务上剥离出来,这样接入工作就不需要等待业务处理的耗时。
扩展性的度量与拆解
扩展性的核心,是投入产出比的权衡。
上边是它的价值,高可用和高性能在面对特定场景时,都需要扩展性的良好支撑,它的价值相对而言是个定量。
下边是需要投入的成本,一旦一个系统已经决定让它具备良好的扩展性,那从依赖人工的程序改造方法,发展到自动化的部署改造,是自然而然的过程,所以我认为扩展的成本,相对来说是一个定量。
在扩展性的话题中,我觉得最为困难的是时机的选择,最好能够把扩展性带来的价值,与需要引入的复杂性带来的成本,拉到同一个维度上进行度量与比较,比如用财务指标。
总结
做个简短的总结:
1)高并发是我们要面临的场景
2)用户体验是我们要解决的问题:系统没有错误,系统响应极快
3)可用性、性能、可扩展性是为了解决上述用户体验问题,进行量化分析的几个视角
4)可用性量化拆解:变化数量* 变化产生故障的比例* 故障的影响* 故障持续的时间
5)性能量化拆解:资源使用时间 + 资源等待时间
5.1)资源使用时间优化:提高利用率、过去或未来换现在,高速资源换低速资源
6)扩展性:量化分析投入产出比选择合适的时机