维护众多服务需要巨大的努力,手动操作已不再可行。以微博的动态推送功能为例,仅远程过程调用(RPC)服务就接近40种。这些服务接口的性能和需求各不相同,一些接口虽然处理请求量大,但响应迅速,称为轻量级接口;另一些接口处理的请求量较少,但响应时间较长,称为重量级接口。
例如,在微博的动态推送中,计数接口的响应时间极短,仅需2至3毫秒,而动态获取接口的响应时间则超过200毫秒。服务集群的规模差别明显,扩展所需的服务器数量也大相径庭。比如微博的A/B测试服务可能只需增加几台服务器即可应对增长,而动态推送服务可能需要增加上百台服务器。另外,在扩展服务时,还需注意服务间的相互依赖性,确保所有依赖的服务都有足够的处理能力。例如,微博的动态推送业务在扩展时不仅依赖于现有的服务器容量,还依赖于用户关系和卡片服务的容量是否充足。
容量规划系统的作用是根据各个微服务部署集群的最大容量和线上实际运行的负荷,来决定各个微服务是否需要弹性扩缩容,以及需要扩缩容多少台机器。
容量评估一般集群的容量评估都是通过线上实际压测来确定的,那么该如何进行线上压测呢?都需要注意哪些关键点呢?
1. 选择合适的压测指标
在进行性能测试时,我们通常关注两大类指标:系统指标和服务指标。系统指标包括CPU使用率、内存使用量、磁盘I/O和网络带宽等,而服务指标涉及到接口的平均响应时间、P999延迟(即99.9%的请求在这个时间内得到响应)和错误率。然而,这些指标并不总是能够准确地反映系统在负载下的表现。例如,低CPU使用率不一定意味着接口响应时间就是健康的,而高CPU使用率也不一定导致接口性能不佳。同样,服务指标如平均响应时间也可能掩盖实际问题,比如在压测中即使只有少量的请求响应时间延长,平均值也可能看起来不变。
基于我的经验,除了监控上述指标之外,还应该检查接口的慢请求比例,即超过特定响应时间阈值的请求占总请求的比例。例如,在对微博的动态推送接口进行压测时,我们关注的是响应时间超过1秒的请求的比例,如果这一比例超过1%,则应停止压测。这是因为如果99%的请求能在1秒内完成,用户体验通常不会受到太大影响。对大多数在线服务而言,保持慢请求比例在1%以下是服务质量的基本标准,因此这个指标可以作为一个有效的压测性能指标。
2. 压测获取单机的最大容量
要确定一个服务器集群能处理的最大负载,我们首先需要知道单个服务器能承受的最大负载,然后这个数值乘以集群中服务器的总数。获取单台服务器最大负载的方法通常分为两种:单机压测和集群压测。单机压测可以通过复现实际流量的日志或复制实时流量到一个服务器上来进行。而集群压测则是通过逐步减少集群中的服务器数量来增加单个服务器上的负载,从而测试每台服务器的极限。
根据我的经验,集群压测更为可靠,因为它利用真实的线上流量进行测试,可以得到更准确的单台服务器负载极限。但是,集群压测可能会对实际运行中的服务造成影响,因此通常在流量较低的时段进行。此外,为了便于及时应对可能出现的问题,这类压测一般安排在工作日进行。
在集群压测中,我们会监控慢请求的比例,并在这一比例达到1%时停止压测。此时,我们可以用停止压测时的每台服务器平均每秒查询数(QPS)作为单台服务器的最大容量指标。但是,仅仅使用QPS作为衡量标准并不总是准确的,因为它不一定能完全反映服务器的真实负载情况。例如,如果有两个服务器,其QPS相同,但一个主要处理响应时间低于100毫秒的请求,另一个处理的请求响应时间都超过50毫秒,则后者对服务器的负载更重。即使两台服务器的QPS都是100,处理更多慢请求的服务器可能已经无法处理更高的QPS,而另一台则可能还有余力。
图片
因此,一种更为精确的方法来衡量单个服务器的容量是通过对不同响应时间段的请求赋予加权值,这种方法称为区间加权。每个时间段的请求都有不同的权重,反映了它们对服务器负载的实际影响:更长的响应时间获得更高的权重。例如,响应时间在0到10毫秒之间的请求权重为1,10到50毫秒为2,50到100毫秒为4,100到200毫秒为8,200到500毫秒为16,超过500毫秒的为32。根据这种加权方法,前述两种情况下服务器的容量可以计算为第一种情况的请求(8个请求×权重1)+(50个请求×权重2)+(30个请求×权重4)+(10个请求×权重8)+(2个请求×权重16)等于340,而第二种情况下的计算为(2个请求×权重2)+(10个请求×权重4)+(50个请求×权重8)+(20个请求×权重16)+(8个请求×权重32)等于1020。通过这种方式,我们可以得到在压测终止时刻,经过区间加权计算得到的单个服务器的最大容量。
3. 实时获取集群的运行负荷
为了估算集群的总负荷,首先,我们需要通过压力测试确定单个服务器的最大处理能力。将这个数值乘以集群中服务器的数量,就能得出整个集群的最大处理能力。接下来,为了判断是否需要对集群进行扩展,关键在于准确估算当前集群的实际运行负载。
由于直接计算每个服务器的负载并将它们加总的方法在大规模集群(例如超过千台服务器)中效率低下,因此采用了一种更高效的方法。这种方法涉及收集每台服务器在不同响应时间区间的请求数量,然后将这些数据发送到一个中心处理点进行整合。在这个中心点,对同一集群中不同服务器在各个响应时间区间的请求数据进行汇总,从而得到整个集群在各个时间区间的请求分布情况。利用这些分布数据并结合区间加权的计算方法,就能有效估算出集群的整体运行负荷。
调度决策
在容量评估过程中,了解集群的最大容量与实际运行负载是关键。这两个数据点可用于形成有效的调度策略。类似于监控水库的水位,这种策略涉及实时监测集群的资源利用情况。如果集群的负载超过了预设的警戒线,类似于水库的水位过高,就需要采取措施来减轻负担,比如通过扩容或重新分配资源。
相反,如果负载低于某个阈值,像是水库水位过低,那么可以选择减少资源,以优化成本和效率。这样的方法确保集群负载始终保持在理想状态,既不过载也不闲置。通过将集群的最大容量与实际运行负荷的比值作为“水位线”,可以有效地实时监控和调整集群的运行状态。
图片
在调度决策时候,就可以根据水位线来做决定。你可以看到下面图中划分了两条线,一条是安全线,一条是致命线。当集群的水位线位于致命线以下时,就需要立即扩容,在扩容一定数量的机器后,水位线回到安全线以上并保持一段时间后,就可以进行缩容了。
图片