查看原文
其他

干货 | 携程网基于应用的自动化容量管理与评估

2017-02-16 陈剑明 携程技术中心
作者简介
 

陈剑明,携程技术中心网站运营中心数据分析高级经理,负责运维数据分析团队,着重业务订单预测和基础架构容量管理。本文来自陈剑明在GOPS 2016全球运维大会上的分享,首发于高效运维。


一、前言


今天跟大家分享的题目是基于应用的自动化容量管理与评估,简单解释下。容量管理与评估相信很多同学都涉及过,根据开发人员的项目需求描述,或者压测数据,估计一个合适的服务器资源需求。


自动化就是将这类评估决策做成一个自动化的进程不需要人为干预。而基于应用,是指我们所有的容量评估最终目的是对应用的支持,而不是服务器本身是否健康,服务器本身很健康,而上面跑的应用不健康,其实不算是好的容量管理。


上图背景中的很多问题是我们在日常工作会经常自省的一些疑问,在下面的讨论中我也会和大家聊到这方面的一些思考。

二、如何提升资源的使用率?

对运营一个网站来说,业务规模会不断地增长,服务器数量会随之同步增长,然而资源的使用率则会逐步下降。

因为一开始考虑的是生存,能实现功能,不至于频繁宕机就好,慢慢地随着业务增长会逐步开始关心性能,可用性,稳定性,考虑冗余/灾备等等方案,随之而来的,就是服务器数量会增加,使用率逐步下降。

这就带来了一个疑惑,我们所采购的计算资源中,只有一小部分是真正地在帮我们做计算,剩下的都是在凭空消耗。为什么会造成这样的情况呢?

究其原因,主要在于几个方面:

  • 首先,追求应用的响应速度。像前一位演讲的同学提到的 CDN 会非常依赖响应速度,经常有很多分析指出响应时间每提升1ms,网站收入就能增加多少,所以就采用过量提供资源的方式,哪怕是牺牲资源利用率。但是不是每一个应用都要无限追求响应速度呢?这里我们要打一个问号。

  • 其次,夸大资源需求。开发人员倾向于多申请一些资源以应对未来并不确定的变化。比如开发需求的变更,或者对未来的业务量估计不足等等,需要给自己留一些 buffer。

  • 最后,资源到位周期长。从提出资源请求,到最终拿到并发布好应用,这个过程需要等待多长时间?2h?2d?2w?还是更长?等待的时间越长,开发就越是倾向于一次性多申请一些资源。

这些都是可以理解的,但却既费钱又不环保。IT系统一向被认为是高效清洁的技术,但我们却深知 IDC 其实是个耗能大户。

所以各大公司一方面通过 IDC 技术创新和服务器定制来降低能耗,另一方面通过提高利用率来增加单位成本的效益。而我们今天要聊的就是后者,探讨如何在确保服务稳定的前提下安全地提升利用率。

既要保障应用的服务质量,又要提高资源利用率,平衡好这两者的关系,是我们运维团队面临的永恒的课题。

各位有没有大致统计过自家服务器的平均使用率?去年中科院计算所的一份研究报告指出,IT公司的服务器平均使用率大概是在12%。
也就是说每投入100块钱在服务器和机房上,却只有12块是真正用在需要的地方。

这么高的冗余程度究竟有没有必要?

以前我们在面对新业务对系统资源的需求时,因为潜在的风险厌恶,习惯性的思维总是倾向于加机器,而另一方面,当我们可以把风险控制在一定范围之内时,适当提高现有资源的利用率所带来的成本节省将是巨大的。

初步估算一下,以目前携程的体量,CPU 平均使用率每提高1%,节省下来的能耗和计算资源,足以提供 13000 人一年的生活用电。携程目前的体量还不算特别的大,如果换成 BAT,他们只要稍作提高,就可以节省很多能源。

所以,不管从经济效益还是社会效益来看,提高资源使用率这件事情都是有意义的。

显而易见,提高使用率也不是越高越好,那我们的度在什么地方?作为运维来说,我们的度就在于满足上层服务的稳定性、可靠性的要求,这是我们的底线。只有在这条底线之上,我们才可以去进一步考虑怎么来提高它的使用率。

理论上讲,对于双 IDC 互为 DR 的系统来说,原则上使用率不超过40%,即确保在任何情况下,一旦某个 IDC 宕了,另外一个必须能够承担所有访问流量来支持应用的请求,这样才能随时确保容灾。


三、提升资源使用率的度在哪里

基于这个前提以及业界同行的一些数据,我们认为实际使用率25%以下为安全,超过30%需警惕,达到40%则很危险,不管怎样都需及时扩容。而使用率不足20%则是对资源和电力的浪费。

所以我们试图提升整个网站资源的平均使用率。这里一个关键的前提是:控制风险。那怎么来控制风险?

首先我们承认一点,资源使用率并不简单地等于 CPU 利用率,也包括内存、I/O、参数配置不当造成的软瓶颈等等。

而我们从另一个角度来看,所有这些资源的瓶颈最终都会表现为响应时间和出错率的增加,所以不论系统有多少资源,我们总是希望能找到一个触及系统资源瓶颈的临界点,在这个点之前,应用的性能表现和访问量是呈线性关系的,一旦访问量超过这个临界点,应用的性能就会明显下降。

我们需要在确保不影响应用性能的前提下,最大程度地利用系统的各项资源。当我们找到拐点之后,再来理性地选择是性能调优还是扩容。这就是我们做基于应用的容量管理的初衷。

这是一个逻辑架构图画的比较简单,大概解释一下,就是在生产环境上,通过控制前端负载均衡器上的权重,来控制流量分配,用生产环境的流量对集群中某一台服务器上的应用进行压测,并在后台实时监控应用性能指标,任何一个系统资源到达瓶颈。

比如 CPU 连续几分钟超过一定的值,或者应用响应时间连续几分钟超过设定的时间,产生性能拐点后立即恢复正常权重,整个过程除了被测应用各项资源使用率上升之外,其余影响极小。

测试过程结束之后会自动搜集测试期间的性能数据进行分析,找到资源瓶颈,并计算被测应用在当前资源条件下最大所能承载的访问量,以及整个应用集群所能承受的最大访问量。

这个是一个非常定制化的结果,因为不同的应用在不同的服务器上能跑出什么样的结果是完全不一样的,所以我们会在内部所有的应用上跑到这样的测试,可以保证所有的应用在不同服务器上它的极限值到底在什么地方,最后通过一些报表来展现。

这个是一个例子,我们在测试的时候会在同一个集群中随机选取两台服务器,其中一台作为测试机,一台作为参考机,这里蓝色是测试机,红色是参考机。

我们会把流量往测试机上导,这里可以看到大概导5倍流量过去,随之而来的可以看到 CPU 的变化,测试机和应用机的对比,测试机从20%上升到60%左右,其实并没有达到瓶颈。

下面两个指标是应用非常关心的指标,一个是响应时间,我们可以看到响应时间在这样的压力下其实两条线几乎是交错重合的,响应时间没有变化,所以这个应用在5倍访问量请求下是完全可以承受的,包括后面出错率也基本上是零。

基于这样的结果开发人员可以非常明确地知道,我这个应用在5倍压力下是安全的,会有一个靠谱的心理预期。其实从这个结果来看,5倍、6倍甚至7倍都是有可能的。

压测过程中的所有性能数据我们拿到后台还要进行进一步加工和分析。比如这个图上,横坐标是访问量 TPS,纵坐标是系统各项性能指标,我们给每个资源都设置一个阈值,当访问量不断增加时,必然会有某一项资源最先达到瓶颈,我们用整个过程中的监控数据给 APP1 建立一个回归模型,而这条回归线和阈值线的交叉点,就是此应用的最大访问量。

其实在携程很多情况是多应用混合部署,我相信在座的各位公司里面很多也有这样的情况,一个服务器上不光有一个应用,可能有两三个应用,如果有其他应用其实也可以测到这样的结果。同样的方式也可以给 APP2 建立一个回归模型。

多个应用之间的关系无非是相关或者不相关。所谓相关是一个应用访问量有波动,另外一个应用也会跟着波动。无关是说一个应用波动不会随着另外一个应用波动而波动。

所以我们先看两个应用无关的情况,这种的情况很容易解决,把无关因素当成随即误差就好。那如果相关的也是可以,我们分析这两个应用的相关程度,如果是高度相关的,那我们可以用其中一个应用的访问量表示另外一个应用,同样可以做一个回归线。

现实情况是,CPU使用率,或者说资源的使用率,往往同时取决于在服务器上跑的所有应用,所以我们在这里就不能只用一个一次的回归模型做这个事情,我们需要用一个多元回归模型拟合这样一个情况,解释每个应用对于资源的影响程度。

并且通过对单一应用和多应用同时压测的方式,拓展自变量的取值范围,增加模型的精确程度。

那对开发人员有什么帮助?其实我们服务对象就是开发人员研发人员,最大的帮助是可以帮他们回答几个问题:

1. 他们会关心我的应用在生产环境上最大可以支持多少访问请求?

这个在我刚才的描述里面大家可以有这个答案了,就是我们用一个TPS的指标,来替换掉传统概念中的 CPU 的指标,另外 TPS 这个指标背后已经隐含了各项资源的信息在里面,所以他们只需要知道这个应用最多可以承受多少访问量就可以了。

2. 我的生产环境上了一些新的版本之后性能变好了还是差了?

对于当前版本代码在生产上的性能瓶颈一目了然,而且通过一次次的周期性压测结果,可以看到整个代码版本推进过程中的性能变化。比如前一个版本应用的最大请求支持每分钟200个,而新版本上去后变成了最大150个,虽然功能上没有问题,但我们知道性能是下降了,由此而来的,就是我们需要为此应用扩容以保持原有的容量不变,或者代码调优以恢复到原有性能。

3. 业务说搞一些活动会带来多少倍的流量,我们系统能不能承受?

如果承受不住需要加多少服务器。这也是一个很常见的问题,我们做容量规划的时候,如果有最大能承载流量的数值,回答这个问题就会非常的胸有成竹。不管业务上是需要支持多少的访问量,我们都可以计算出一个既准确又能满足性能需要的资源需求。

4. 开发人员非常关心当前这样一个应用集群的容量使用是什么样的情况?

建立了模型,就可以随时反应容量的使用情况。应用的管理者可以随时掌握。

四、开发和运维的协作关系


这里是我要跟大家聊的一个事情,开发和运维之间的协作关系。当我们对每台服务器上的每个应用能承载多少访问量有了可靠的数据,并且结合当前和历史访问量进行分析的时候,我们就可以判断一个应用集群什么时候需要扩容,除了提前扩容以应对自然增长的请求量之外,突发请求量也能被捕捉到。

这时,当前容量够不够,不足的话需要增加多少台服务器,都可以马上决定,结合后续的 VM 自动上线流程和应用自动发布流程,就可以做到自动化的弹性缩扩容,大大缩短资源申请到应用上线的速度。

我们当前的平均上线速度是一个多小时,而目前也正在优化各个环节,目标是做到10分钟以内。也就是说,从开始申请服务器到新的资源投产正式分担流量控制在10分钟以内。

这样一来,容量管理就会变得自动而且高效,在提高资源利用率的同时,也让开发人员对自己应用在生产环境的表现和瓶颈了然于胸。一旦对资源的保障也没有了后顾之忧,那之前提到的导致使用率降低的核心因素也就解决了,形成了一个正向的反馈机制。整体运维成本也自然就能随之降低。

那可能有些同学会有担心,我们没有给开发人员做任何的资源使用限制,会不会最后导致开发不重视代码性能,资源被滥用?

从我们运维的角度来讲,开发人员就是我们的客户,他们需要资源,我们实际上是没有理由驳回的,只能全力支持。那是不是意味着会被任意挥霍呢?其实不会,我们限制不了,但有一双无形的手可以限制,对,就是财务。

大家可以注意到从我们反馈到开发的最后一步是成本分摊,使用的资源越多,运营成本也就越高,除非对成本没有要求,否则开发人员自己就会在代码性能和资源成本之间做取舍,这也是个正反馈。没有理由说一个嵌套循环明明可以优化降低 CPU 的,却非要多申请一些资源。

所以,我们通过这样一种方式进行资源的容量管理,可以逐步地将利用率提高到一个合理的水平,并且保证应用不出问题,而且也可以对未来的容量需求有提前的预判和准备。

当然这一切的前提是你需要有足够的系统及应用监控能力,要达到自动化的容量评估,如果有一点是必须要先做的,那就是系统层和应用层的性能数据监控和搜集。 否则以上的一切都是空中楼阁,没有数据,所有都是空的。

所以,当我们在迎接智能运维时代到来的时候,要先想一想,数据是不是真的已经在搜集起来了?我们的数据是不是足够大足够全,足以支撑起我们拥抱智能化的运维时代?

推荐阅读:



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

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