容量管理是系统可用性运维的重要环节之一。通常来说,容量管理包含容量度量、容量规划和过载保护三个过程。容量度量首先要确定系统容量的衡量标准,通过一定方法得到各模块的流量承载能力(包括额定负载、极限负载和冗余度),从而得到系统整体容量。容量规划是基于 SLA 可用性要求,确定资源在时间上的需求规划。过载保护是根据容量衡量和规划结果进行的外围系统设计,以保障业务在满足 SLA 的前提下,稳定处理高于额定负载的请求。
百度 Noah 平台的时序数据存储系统(TSDB),承载了百度诸多核心业务的监控数据存储与查询需求,日均写入点数以万亿记,查询请求高达数十亿次。在如此大的请求场景下,建设一套完善的容量管理机制,有效的度量 TSDB 系统的容量能力,合理规划系统容量发展,及时发现系统的容量风险,有效应对容量过载场景,是非常困难又非常重要的。本文主要介绍 TSDB 系统容量度量、容量规划方面的内容。在接下来的后续文章中会详细介绍过载保护方面的一些实践。
容量度量–容量管理的基础
1 设定容量指标
容量是系统对业务承载能力的量化,一般我们使用可量化的性能指标来衡量系统的容量。通常来说有下面三种:
1.吞吐量(Throughput):指系统单位时间内处理的请求总数。请求可以是读写请求,也可以是数据处理请求,对应着 QPS(Query Per Second)和 RPS(Request Per Second)两类;
2.并发数(Concurrency):同一时间内能够处理的请求数目;
3。系统延迟(Latency):指系统完成一个请求所花费的时间。
在多并发系统中,可以把这三者的关系简化为:吞吐量=并发数/系统延迟。对于单并发系统,吞吐量就是系统延迟的倒数。
至于具体使用哪一个性能指标来衡量系统容量能力,需要根据不同的业务场景来判断。在多数场景下,我们考量的都是吞吐量(QPS 或 RPS),当然对于实际的业务场景,QPS、RPS 的定义会略有区别。在 Noah 监控场景下,主要是监控数据(时序数据)的写入和查询,每个请求会对应多个 itemCollection,而一个 itemCollection 中带有多个监控数据点。因此,我们使用 PPS(Point Per Second)作为 TSDB 系统的 QPS 指标来衡量系统的容量能力。
2 获取容量数据
获取容量数据的方法有容量估算和压测两种。容量估算指通过各子模块的运行指标,使用资源建模计算的方式汇聚计算出全系统的容量数据。例如下图,模块 A 为整个系统的入口模块,入流量为 x,他有两个下游 B 和 C,分别承载 y 和 z 的流量。首先,通过资源消耗(瓶颈资源)与流量的折算关系估算出每个模块的容量分为 X,Y,Z,例如在资源消耗 50%的时候,流量是 1KQPS,可以预测系统达到极限负载的情况下容量为 2KQPS(只考虑系统为线性系统)。接着通过假设流量在各个模块的等比例放大/缩减,计算出整个系统的容量为 min(X,xY/y,xZ/z),即整个系统的容量由子模块的最小容量决定。这种计算方式存在两个误差来源,一是资源消耗与流量增长并非完全线性,二是各模块间未必完全解耦导致模块之间的流量增长并非等比例。
实际应用上更广泛的做法是通过压测来获取相对准确的容量数据。压测方法一般分为线上压测和线下压测。线上压测是直接对线上服务进行真实流量的压力测试以获得整个系统的容量,精度较高,但成本较大,且可能会对线上服务的稳定性造成影响。线下压测首先需要部署与线上环境完全一致或等比例缩放的系统,再通过压测得到线下系统的容量,最后通过等比例折算的方式获得线上实际生产环境的全系统容量。搭建一套与线上完全一致的线下系统用于压测,投入的成本过大。如果仅仅是线上集群的等比例小规模集群,压测的数据准确性又无法保证。
我们在对监控的计算-存储(Astream-TSDB)系统实施压测时采取了折中的方案,虽然是线上压测,但压测的对象是线上规模相近的热备集群。监控系统计算存储集群的示意图如下所示。Agent 将同样的两份数据发往跨地域的两个计算集群,由计算集群计算后分别发往同地域的 TSDB 集群,查询端通过流量切换可选择在两个集群进行数据查询。两个集群在物理上隔离,所以对备集群的压测带来线上系统可用性风险的概率大大降低。
具体的压测方案,我们还需要考虑以下三个方面:发压端,压测预案,数据污染。
1.发压端主要考虑的是如何构造流量压力的问题。一方面,我们希望发压端有足够大的并发,能模拟系统在超高压力下的性能表现;另一方面,我们希望压测的压力能真实模拟线上实际的流量。为了完美解决这两个问题,我们的压测平台 LTP 使用流量回放来构造发压数据。其基本原理是对服务的流量进行拷贝,并以实时或离线的方式将流量的副本分发到发压机上。同时流量回放也支持比例加压,或者流量成分的过滤和修改操作。
2.在压测方案的设计中,应尽量保证压测子系统与线上系统的隔离,以减少对线上的影响。压测预案考虑的是当压测造成系统故障时,我们需要具备有效的止损预案,比如中断发压预案、流量切换预案和集群恢复预案等等。
3.对于存储系统来说,不得不面对的一个问题是写入的脏数据问题。这部分压测的脏数据是不希望被用户获取的。解决的办法还是尽量从业务上隔离压测系统,具体采用的方法可以是给发压的数据单独打上压测的标签,压测结束后单独删除;也可以在查询端做压测数据的区分。
3 容量建模–建立容量水位机制
上述我们所说的系统容量值其实指的是系统所能承受住的极限负载,是不带任何冗余的。这个值无法保证系统的高可用性,因为线上稍有退化,甚至是计算的误差,都会导致基于这个值做的一切预警无效。为了避免各种因素的影响,我们可以给容量加上冗余,这部分冗余容量用来抵御系统的流量突增、性能退化、容量计算误差等等场景。所以我们可以认为极限容量*(1-Buffer)才是系统的容量,也叫额定容量。我们建立的容量报表,也是基于该值。建立系统及子模块的容量水位报表,可以定期巡检线上服务容量状态,及时发现容量瓶颈。并且,我们还对核心服务的容量水位设置阈值报警,一旦系统容量到达容量水位预警值将自动执行服务弹性扩容,保障系统稳定运行。
容量规划
随着业务量的快速增长,我们不得不考虑的问题是未来整个集群的容量需求为多少,当前集群距离目标容量还需扩容多少。有了容量数据后,我们就可以通过下面的计算回答这个问题。
假设线上服务流量历史上月增幅 X,冗余度要求为 R,当前极限容量为 C,线上有 M 个实例,则 N 个月后容量需求为,需求的实例数目为。其中,实际的流量增长并非线性,更科学的计算可以通过非线性的流量曲线去拟合。
总结
容量管理是系统运维不可或缺的部分,而建立容量数据是容量管理中最为基础、重要的一环。基于准确的容量数据有利于更有效的做容量规划和优化分析。以上是 Noah 在容量管理方面落地的一些粗浅经验,如有不当之处,欢迎指正。
作者介绍:
姜泽,百度高级运维工程师,负责百度智能运维产品(Noah)的运维工作,在可用性建设,容量管理方面有着丰富的实践经验。
本文转载自公众号 AIOps 智能运维(ID:AI_Ops)。
原文链接:
https://mp.weixin.qq.com/s/yrBVLEWvgYZHz6tTSifehw
评论