02 | 系统可用性:没有故障,系统就一定是稳定的吗?

你好,我是赵成,欢迎回来。

我们先来复习一下上一讲的内容,总结下来就是,SRE是个体系化工程,我们通过构建SRE这样一套体系来保证系统稳定性,具体来说就是“提升MTBF,降低MTTR”。有了这样一个激动人心的目标,你是不是想着那咱还等什么,赶快、立马就入手建设SRE体系吧!

嗯,好想法,我也很想咱就直接“撸起袖子加油干”。不过今天我们要先缓一缓,在正式进入SRE落地细节之前,我们得先讨论一下目前业界常用的“系统可用性(Availability)”这个概念,也就是我们常常听到的“3个9”(99.9%或99.95%)、“4个9”(99.99%或99.995%)。

为什么要先来讨论“系统可用性”这个大家已经很熟悉的概念呢?

一方面,系统可用性和我们建设SRE的目标强相关,SRE的稳定性目标其实就是尽量减少系统故障或异常运行状态的发生,提升系统可用的运行时间占比。很明显,这个可用时长就非常关键了。

另一方面,系统可用性这个概念看似简单,但我发现真的深入进去,大家的理解其实有很多不一致的地方,比如到底怎样才算是可用时长,怎样算是不可用时长呢?这个标准是怎么定义的?除了从时间维度来衡量可用性,还有其它的衡量方式吗?“3个9”、“4个9”听起来都很好,那具体来说我们的系统要达到“几个9”才算是稳定的呢?

所以,今天我们先慢下来,花时间把上面这些问题都彻底搞清楚,达成共识,打好基础,咱后面的SRE学习才能事半功倍。

衡量系统可用性的2种方式

那我就直接给答案了,目前业界有两种衡量系统可用性的方式,一个是时间维度,一个是请求维度,我们先来看这两个维度的计算公式。

  • 时间维度:Availability = Uptime / (Uptime + Downtime)
  • 请求维度:Availability = Successful request / Total request

这两个公式很简单,我们得深入进去,一一来看。

我们先来看时间维度的系统可用性。用一句话来概括:时长维度,是从故障角度出发对系统稳定性进行评估

这类计算方式我们最常见,毕竟你的系统在一段时间里不出现故障,就说明它很稳定嘛!不过,在真实的使用场景中,怎么样才算是可用时长,什么情况下又是不可用时长,这个是怎么定义的呢?

细想一下这个问题,你会发现还真有点复杂,那我就举个发烧生病的例子来说明一下。

我们知道,一个人如果发烧了,体温一般会超过37.5度,那如果这个人的体温正好达到这个温度,是不是代表他一定是生病了呢?依据生活经验,我们知道不一定。为什么呢?因为我们判断一个人是否发烧生病,不是只看这一次、一时的体温,还要看他体温是不是持续超过37.5度。

所以,这里就涉及到一个测量方法和判定方法的问题,包含三个要素:一个是衡量指标,比如体温就是衡量指标;第二个是衡量目标,达到什么目标是正常,达不到就是异常,低于37.5度算正常,超过37.5度就是异常,但是单次测量不能说明问题,我们可以多次测量,比如6次中有至少4次低于37.5度才算正常,转化成比例的话就是67%;第三个是影响时长,比如持续超过12小时。

对应到系统上,我们也会用一系列的标准和判定逻辑来说明系统是否正常。比如,系统请求状态码为非5xx的比例,也就是请求成功率低于95%,已经连续超过10分钟,这时就要算作故障,那么10分钟就要纳入Downtime(宕机时间),如果达不到这个标准,就不算作故障,只是算作一般或偶然的异常问题。

这里同样有三个要素:衡量指标,系统请求状态码;衡量目标,非5xx占比,也就是成功率达到95%;影响时长,持续10分钟。

因此,只有当问题达到一定影响程度才会算作故障,这时才会计算不可用时长,也就是上面公式中的Downtime。同时,我们还要求一个周期内,允许的Downtime,或者说是系统的“生病时间”是有限的,用这个有限时间来约束系统稳定性。

下面是我们常见的按时长维度统计的可用性对照表,也就是我们前面提到的几个9:

讲到这里,针对时长维度的稳定性计算方式就比较清楚了,但是从这种计算方式中,你有没有看出一些问题呢?

我想你肯定看出来了,这里最显著的问题就是,稳定性只与故障发生挂钩。

我们来想一想,这样做会带来哪些问题?比如有一个系统,因为网络抖动,有短暂的几秒、十几秒,或者几分钟异常,但是后来系统自己恢复了,业务并没有中断,这时我们按照时长维度来判断,这肯定不会算作系统故障。但是如果这种短暂的影响频度非常高,一天来个5、6次,持续一两周,我们应该可以判定系统运行状况也是不正常的,可能不是故障,但肯定是不稳定了。

所以这种用时长维度来衡量系统稳定性的方式,其主要缺点就是粒度不够精细。这些小的异常问题和它们的影响,如果从更长的周期来看,也是有一定参考价值的。那怎样才能衡量得更精细些呢?

这就需要第二种衡量方式了,也就是从请求维度来衡量系统可用性。

用一句话来说,请求维度,是从成功请求占比的角度出发,对系统的稳定性进行评估

假定我们的系统一天内有100,000次请求,我们期望的成功率至少是95%,如果有5001次请求失败了,也就是成功率低于95%了,我们就认为系统运行状态是不正常的。

请求维度的系统可用性同样包含三个关键要素,第一个衡量指标,请求成功率;第二个衡量目标,成功率达到95%才算系统运行正常;第三个是统计周期,比如一天、一周、一个月等等,我们是在一个统计周期内计算整体状况,而不是看单次的。

你看,这种方式对系统运行状况是否稳定监管得更为严格,不会漏掉任何一次问题的影响,因为它对系统整体运行的稳定性判定,不仅仅会通过单次的异常影响进行评估,还会累计叠加进行周期性的评估。

到这里,我们就总结出一条至关重要的经验了:故障一定意味着不稳定,但是不稳定,并不意味着一定有故障发生

到这里,我们掌握了衡量系统可用性的两个维度、两种算法,它们都包含三个关键要素:衡量指标、衡量目标、影响时长/统计周期。这两种算法最后都会落脚到“几个9”上,那系统到底定“几个9”才算是稳定的呢?接下来,我们就来回答这个问题。

设定系统稳定性目标要考虑的3个因素

这个问题其实并没有标准答案,从我的经验来看,到底定“几个9”主要取决于以下三个因素。

第一个,成本因素。

从理论上来说,肯定是9越多稳定性越好,但是相应付出的成本和代价也会更高。比如为了更高的可用性,要有更多的冗余资源投入,甚至要做主备、双活甚至是多活。如果一家公司的业务量和影响力都发展到一定程度,那这个成本不管多高都是必须要付出的。但是,肯定不是所有的公司都需要付出这么高的成本,而是要先考虑ROI(回报率)。这时候就要看企业自身对成本压力的承担情况了。

第二个,业务容忍度。

稳定性怎么设定,很大程度上还要取决于业务上的容忍度。对于核心业务或核心应用,比如电商的交易和支付系统,我们当然是希望成功率越高越好,一般对系统稳定性要求是“3个9”或“4个9”。因为这些系统一旦出问题,就会直接影响整个网站和公司的收益,这些都是钱,所以对稳定性要求必然就会提高。

但是,对于非核心业务或应用,比如商品评论,商品评分等,或许“2个9”也能容忍。因为短时间的评论看不到,并不会对业务收入和用户体验造成太大的影响。

第三个,系统当前的稳定性状况。

结合系统的实际情况,定一个合理的标准比定一个更高的标准会更重要。这个合理的值应该怎么来定呢?

我个人的建议是从系统现状入手,比如,如果系统可用性是低于99%的,那首先第一步是不是可以做到99%,然后再争取做到99.5%,再到99.9%,一步一步朝着更高的标准迈进。同时,这样做也会更容易落地,因为你如果定一个太高的目标,又始终达不成,反而会打击到团队的自信心和积极性。

结合上面这三个因素,对于到底应该定“几个9”这个问题,你应该有了一个更清晰的认识了。

总结

好了,到这里,今天我们要讨论的系统可用性就讲完了。关于系统可用性,业界有两种计算方式,一种是时长维度,另一种是请求维度,这两种方式各有优劣。在SRE的实践中,应该选择哪一个呢?很明显,SRE会更多采用请求维度的统计方式,因为SRE关注的稳定性是系统的整体运行状态,而不仅仅只关注故障状态下的稳定性,在系统运行过程中的任何异常,都会被纳入稳定性的评估范畴中。

这个知识点要拿一整节课来讲,是因为接下来我们就要讨论SRE的稳定性指标和目标了,理解了今天的内容,你才能更好地理解SRE体系中的指标(SLI)和目标(SLO)。今天我先把SLI和SLO这两个概念抛出来,如果你觉得有点陌生,没有关系,准备好下节课和我一起掌握它们。

思考题

对于系统可用性的描述,今天我们仅用了“状态码”这一个指标来示例,但是在实际情况下,我们还会有其它多个指标来同时标识一个系统的稳定性,你能想到还有哪些指标?欢迎你在留言区写下自己的思考。

考虑这些指标的时候,不妨想想你是怎么选择的,你的判断标准是什么?这些也将是我们下节课程的重点内容。

如果今天的内容对你有帮助,也欢迎你分享给身边的朋友,和他一起精进。

我是赵成,我们下节课见。

精选留言

  • 春来草自青

    2020-03-19 08:26:54

    从业务部门的视角来看,状态码是多少他们是不关心的,他们关心的是业务是否真正的可用。比如,极端一点,状态码正常,但返回的内容不是预期的。

    另外,如果业务不是需要7*24的,可用性指标应该是仅限定在业务开展期间。

    有点扯远了……
    作者回复

    很好的问题。从两个方面来看:

    1、返回的业务内容不是预期的,这一点应该更多的是要QA来解决,这个本质是是功能问题,其实SRE是不需要关注这样的异常的。

    2、如果可以做到内容不同,返回码不同,也可以做到稳定性的监控。比如对于一个用户登录应用,如果登录成功是200ok,验证码错误是1001,密码错误是1002,如果总是提示验证码错误,这种也是可以纳入到稳定性的监控指标中的。

    关于第二个问题,7*24小时值守,这个看业务特点,比如对于证券类的应用,每天就是几个固定时段,所以没必要7*24小时。

    2020-03-20 09:19:08

  • 于加硕

    2020-04-03 16:59:13

    “标识系统稳定性指标”
    我将这里的系统理解为一个服务,例如order这个服务,用于标识它稳定行指标有如下

    基础设施层:物理设备,操作系统

    应用层:全链路监控针对服务功能埋点监控

    服务层:服务提供的rpc,http服务的表现

    用户层:APM将从外部因素(用户视角)检测业务功能,收集各个区域/设备对业务的稳定性的表现

    说到这里,我又感觉有点像立体化监控似的。

    选择这些指标的判断标准是:
    为什么我不能只关注http的状态呢?
    举个我自己例子,公司order.xx.com出现了问题,5xx超过2000次,这样的告警其实只是将故障的表象层告出来,业务不可用,一定会有5xx,但哪里引起的5xx?哪些告警是故障的表象层,哪些是故障点的告警,一时间难以区分,如果有一个自上而下的汇聚指标供我查看,我也许就能及时的定位到原因。在上面几个层级的指标中,经常是相互作用的,例如基础设施层宕机,会引起上面多个层级指标波动;用户层的流量激增又会带来下层的指标波动;APM中的外部因素——区域网络波动又会引起内部服务层指标499波动等。所以我个人觉得稳定性讲的是一整条请求链(从用户设备到IDC)的事,要解决稳定性就必须清楚的看到整个链路的情况,所以“标识系统稳定性指标”我选择这样几个层级。这是我的观点,希望老师指正。
    作者回复

    感谢你的非常详细地分析,你这里其实是针对我们可用性的内容又向下深入了一层,已经深入到了定位系统不问题的根因是什么。

    关注系统可用性,我们通过几个关键指标就可以,但是深入定位根因,就像你说的,我们需要更加立体化的监控,甚至是AIOps的手段。

    非常棒的分享。

    2020-04-04 17:59:55

  • leslie

    2020-03-18 20:34:09

    就像老师课程中所提及的三要素”成本因素、业务容忍度、系统当前的稳定性状况“。这三点无一不需要综合考虑,甚至有时都得考虑三者之间的比例。
    个人在此之外会考虑”离散度“:确实有时觉得好像还稳定,可是离散度是否正常。记得老师的推荐的书籍中就提及过,"系统正常是系统异常的特殊情况";有故障才是是常态。没有故障且稳定说明大家都在做机械化重复操作,如何从故障和不稳定中找出问题才是根源。
    老师在上一堂课中给出"建设演练/oncall->应急响应->复盘改进/oncall”我觉得就非常好的体现了SRE的理念。谢谢老师今天的分享,让我又享受在学习的过程之中。
    作者回复

    你的分享也非常用心,总能抓住很多关键点,很赞!

    2020-03-20 09:21:07

  • OlafOO

    2020-03-20 12:32:55

    机器性能指标
    应用层级指标
    服务质量指标
    作者回复

    赞!

    2020-03-20 17:07:17

  • 大尾巴老猫

    2020-03-21 16:46:07

    请教一下,老师怎么看AIOPS,AIOPS对线上的业务来说,真的有(真实的)价值吗?
    作者回复

    要清楚,AIOps对业务本身是没有价值的,它是为运维服务的,所以它的价值更多的体现在运维层面。

    体现在运维层面的哪里呢?就是问题发生前的预判、以及根因分析这些,因为在大规模分布式系统下,没有这个手段就没法处理问题。

    但是AI要有两个要素,一个是算法,一个是数据,算法是靠数据训练的,这里算法不是问题,但是数据量是不是足够大就是问题,所以一定要业务体量足够大,资源规模足够大,产生的日志信息足够丰富,这时AIOps才有意义,如果只有几十几百台服务器的规模,业务体量也没有那么大的情况下,AIOps的作用是不大的。

    2020-03-21 19:55:17

  • 寞月

    2020-06-21 18:00:09

    对于CS类应用,想到的指标有:
    ## 服务端监控指标
    ### 业务维度
    - 业务服务健康检查:业务服务、DB、缓存组件
    - 上下游依赖服务健康检查
    - 请求状态码(错误请求百分比)
    - 响应时间(慢请求百分比)
    ### 基础设施维度
    - 服务器uptime:服务器可以是物理机、虚机、容器,cpu内存磁盘问题都会影响uptime
    - 服务健康检查:基础组件服务、ops服务等健康状态检查
    - 网络指标
    ## 客户端上报指标
    同样是请求状态码和请求响应时间,但体现的是用户端的感受,可以与服务端数据对比来评估问题出在服务端还是用户端网络或cdn等。

  • 爱吃鱼的猫

    2020-04-09 08:53:30

    稳定性还是要看应用的等级,核心应用可能会投入更多的资源和成本,从架构等多个方面做到更好的高可用,没必要为一个非核心业务投入太多资源
    作者回复

    非常正确!

    2020-04-09 09:58:26

  • Warm

    2020-03-22 14:59:02

    可用性指标,我觉得还需要区分下
    1. 业务可用性,可以称之为“源站””,这里的统计指标最好给业务提供最大的灵活性,授权rd自身配置uei,请求方法,以及正常状态码。这里需要注意一个问题,有时候301/302/499也是错误码(比如为了友好提示5xx内部跳转,触发请求限流503),所以最好将body自定义内容作为判断指标。
    2. 网络(用户)可用性。源站可用,不意味着用户也可用。可以通过监控班类的APM统计可用行指标和响应延迟(比如大于5s以上且5个节点,某某运营商线路丢包或者抖动等等)
    作者回复

    感谢你提供了用户可用性这个维度,从SRE角度,离用户越近的指标,越有价值。

    2020-03-23 09:00:40

  • foxracle

    2020-03-19 14:52:17

    系统可用性从用户角度来评价最直接,至少包括
    1:能否访问到。这应该包括从用户操作到收到响应整个端到端的是否可用,对于用户最后一公里的不可控段也需要能感知和预警。
    2:访问是否顺畅。响应时间是否异常
    作者回复

    从用户角度来评价,这个点把握的非常准确。

    2020-03-20 09:18:33

  • H.Z

    2020-03-25 16:30:44

    1. 系统层面:CPU、内存、磁盘IO、网络IO
    2. 业务层面:网站返回状态码、接口返回时间
    就想到这些
    作者回复

    总结地很好。可以看看后面两篇文章,看看有没有进一步的启发和思考。

    2020-03-26 11:12:47

  • 小圣

    2020-03-19 10:39:30

    简洁,清晰
    作者回复

    谢谢!看看能不能用简介清晰的几句话表达出来呢^_^

    2020-03-20 09:20:14

  • Browser

    2020-10-19 22:16:45

    面向领导的运维😁
    作者回复

    很多企业往往就是这样的

    2020-11-18 09:55:11

  • Zachary

    2020-09-09 23:18:07

    感觉两个维度并不是都适用于任何情况. 比如外部网络异常中断的情况下, 没有任何请求可以到达就没法从请求维度来考虑.
  • 方勇(gopher)

    2020-05-20 09:20:54

    应用可用性指标,请求耗时,成功率都是基于日志的能很好的分析出来,中间件是为应用服务的,单个节点有异常,集群其实还是可用的,到节点切换的时候,可能有慢sql,应用异常不太和中间件关联上,一般都是事后人为分析
  • Donald

    2020-04-14 20:09:49

    我其实还是不太明白,应该是先明确故障的定义,还是先明确不可用时长的定义?
    先定义故障?似乎不太合理。
    先明确不可用时长?比如,影响了不可用时长,就算做一个故障?-似乎合理。

    那么,是不是可以这样理解?
    比如,如果按照时长维度来定义,会出现一种情况,就是没有达到不可用的定义,但是频繁发生,比如持续发生但是未超过10min。
    而另一种衡量方式,通过请求比例,比如,每发生一次,不管持续多久,都算作1。那么,每一次不稳定的发生,都会计算进不可用。-所以也是这个原因,才说是通过请求比例的定义会更合理?
    作者回复

    理解基本正确。

    2020-04-16 13:52:05

  • jenven

    2020-03-21 15:48:00

    系统的稳定性的衡量指标最关键要与业务结合一起。
    我认为最重要的是要引入服务的健康检查机制,具体说明:
    如A服务依赖诸多中间件例如数据库、消息队列等,也依赖其他B、C等服务。A服务对检查的服务所依赖的不同的中间件或服务定义为HealthCheck的最终结果为true或false,任何一个HealthCheck的healthy结果为false,那么最终状态就会是false。{
    "healthcheck":[
    { "status": "true|false"
    }
    ]
    "rds":[
    {
    "name":"实例1 " ,
    "status": "http_code_status",
    },
    {
    "name":"实例2" ,
    "status": "http_code_status"
    },
    ]
    "redis":[
    {
    "name":"实例1 " ,
    "status": "http_code_status"
    },
    {
    "name":"实例2" ,
    "status": "http_code_status"
    }
    ]
    "mongodb":[
    {
    "name":"实例1 " ,
    "status": "http_code_status"
    },
    {
    "name":"实例2" ,
    "status": "http_code_status"
    }
    ]
    "app":[
    {
    "name":"domainB" ,
    "status": "http_code_status"
    },
    {
    "name":"donmainC" ,
    "status": "http_code_status"
    }
    ]
    }
    上面是个比较简单的服务健康检查,可以应用到部署检查和服务可用性探测。
    这里,也可以再完善,可以对调用的服务或组件进行优先级划分,比如调用数据库1是核心库(高优先级服务),那么服务A调用数据库1返回状态为非200(自行根据业务场景设置请求次数),那么服务A就不可用(可以标记为“紧急“),调用其他数据库2或服务B为非核心库或非核心服务(低优先级服务),这里服务并不影响核心功能,可以认为此服务可用,那么这里调用返回结果可标记为“警告”。
    作者回复

    你提供了一个很好的案例。你提到的是针对单次请求的成功与否,但是如果要判断服务是不是正常,单次判断是不是够?如果不够,那应该采取什么样的判断方式呢?

    可以尝试思考下这两个问题。

    2020-03-21 19:30:39

  • 张无忌

    2023-12-06 16:08:21

    老师,这儿有一个问题,就是前端的故障怎么算?如果按照请求维度去算,会有请求成功率很高,但是纯粹是前端造成的问题,导致系统的不可用,毕竟任何系统都要通过用户界面把价值呈给用户的。有两个例子:

    1. 前端造成的bug,比如类似于服务端的空指针异常导致的不可用;
    2. 不是前端的bug,但是由于前端加载了资源,比如各种js代码文件,加载资源出现了异常,导致的不可用;

    如果把前端因素加上,似乎只能用时间维度衡量可用性了吗?
  • hanson

    2023-04-19 02:16:43

    我们系统使用的是Nagios监控平台对主机、核心服务器、关键应用程序进行周期性监控
    如CPU、Memory、IO, heartbeat status, MQ queue,Oracle session numbers等等。
    系统可用性方面,我们既需要时间维度的指标,又需要请求维度指标。
  • BertGeek

    2022-10-25 17:56:54

    系统稳定性,需要提前规划定义标准值范围和方法
    综合多方因素和现有储备,适合项目在线需求,达到业务稳定标准。
  • 训虎

    2022-09-02 09:46:53

    SRE是一个方法论,一个工程方法