查看原文
其他

高并发系统概念梳理

雷果国 高可用架构 2022-08-25

最近梳理了高并发系统相关的概念与技术,写此文目的是做一个系统性的总结,一方面惠及他人,另一方面希望有兴趣的同学可以一起交流(微信号:selfimpr)。

 

高并发、高可用、高性能、高可扩展是什么关系?


 


 

产品、市场、运营的成功,带来了同时段大量用户对系统的访问,这就是高并发。

 

高并发本身并不是一种技术的方法,它是系统要面临的一种有技术挑战的场景。

 

在这个场景下,(工程)技术的核心价值,是确保高并发时的用户体验,具体而言,就是系统不应该发生错误,并且以极快的速度给用户响应。

 

上面是对问题的定性分析,但定性分析不能帮助我们开展工作,所以还需要能够对问题进行定量分析。

 

可用性、性能、扩展性就是用于定量分析的三个视角。

 

可用性的目标,是为了让系统尽可能不发生错误,或者将发生错误后的损失降到最低。

 

性能的目标,是为了让尽可能多的用户,用尽可能少的时间得到系统的响应。

 

扩展性的目标,是为了支撑可用性和性能,在一些特殊情况下,不得不对系统结构做出调整时,尽可能以低成本的方式完成。

 

可用性的度量与拆解


 


可用性的指标,是系统可用时间在系统运行时间中的占比,业内通常喜欢用N9的方式描述。但N9对我们的工作开展没有帮助,因此需要对这个指标进行拆解,便于针对具体场景开展工作。

 

上图公式中,运行时间是定量,不可用时间是变量,因此只需要对不可用时间进行拆解。

 

感知变化的发生

 

如果此刻时间停止,一切都不发生变化,那么系统就不存在不可用问题。因此,不可用的第一个因子就是变化,我们需要能够感知到变化的发生。

 

第一类变化,是与人相关的,最典型的就是运营市场的活动与技术没有联动,活动带来的瞬间流量增加会让技术的应对非常被动。

 

第二类变化,是与上下游相关的,比如上游系统对我们的访问量突然提高一个数量级,或者下游系统的失败率突然增高,都会对自己的系统产生比较大的影响。

 

第三类变化,是与运行环境相关的,硬件的维保信息,健康度指标,软件系统的CPU、网络、IO等资源的使用情况,如果发生突然的变化,也会让系统的可用性面临风险。

 

第四类变化,是与时间相关的,比如int型时间戳快用完了,证书等资源会有时效,时间分表的表创建等,这一类变化容易被忽视,但一旦发生问题往往影响很大。

 

第五类变化,自身系统的迭代相关,这个角度的变化,感知是自然的过程。

 

通过预判降低故障比例

 

当我们知道变化的发生,下一步,就是根据变化的特征,结合经验,预判变化可能引发的故障,来降低故障发生的比例。

 

比如常见的CodeReview机制、上线评审机制、CaseStudy机制,就是对经验的复用,QA测试和验证,则是用专业的方法去发现潜在的问题。

 

降低故障的影响

 

无论你如何努力,只要时间没有停止,故障就不可避免。

 

所以,下一个视角就是正视故障,通过提前的架构设计,让故障发生后产生的影响尽可能小。

 

比如资源隔离,就是希望A业务坏了之后,B业务还能正常运行,对用户而言,这比都坏了好。

读写分离,站在用户的视角,不能发帖子了,但还能看帖子总还是相对好的结果。

 

数据隔离适用于一些特定场景,比如游戏往往会做区服的数据隔离,这个区的资源故障,其他区的用户还可以正常使用。

 

滚动发布的思路,是先在小范围用户中发布,验证新引入的变化是否存在问题。

 

限流、熔断是应对极端情况的保守策略,比如为了不让全部用户都不可用,在达到系统容量上限后不再为更多用户提供服务。

 

提高故障的恢复速度

 

故障发生了,我们总是要让他尽快的恢复正常。

 

但故障的发生究竟是源自什么变化,很多时候是未知的,因此,首先需要的是值班制度,人必须在第一时间介入。

 

对于我们主动发布的变化,则应该事先准备好快速回滚的方案,以备不时之需。

 

另外,对于一些相对常规的,可预判的故障点,则可以使用自动化的技术,进行故障转移或扩容。

 

性能的度量与拆解 


 


性能的度量,主要是考虑完成特定任务目标所需的耗时。任务目标是定量,任务完成耗时是变量。

 

业内对性能的主要度量指标有平均响应时间、分位值响应时间、QPSTPS,这是不同角度的观测方法,不影响我们对性能这个目标的拆解。

 

任务完成的耗时,通常由内存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)扩展性:量化分析投入产出比选择合适的时机

 

最后,本文主要目的是理清概念,系统性的总结自己的认识,具体技术方面的讨论需要结合具体场景来看,希望你有所收获,欢迎加微信交流(微信号:selfimpr


参考阅读:


本文由高可用架构翻译。技术原创及架构实践文章,欢迎通过公众号菜单「联系我们」进行投稿。


高可用架构
改变互联网的构建方式

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存