Justin's Words

容量评估

原来的容量评估

各个团队给出的评估方案包括:

  1. 根据我们以往所能承受的最高峰值来评估。据我所知,我们业务最近承受过的最高峰值是在王者荣耀决赛的时候,那就拿那个时候的数据来评估,那个时候我们用了多少台机,世界杯期间就先部署多少台机,不够再加。这个方法就是简单粗暴,直接堆机器。
  2. 接口压测。直接对我们的接口进行压测,把机器压到爆,那么快把机器压到爆那个QPS,就是我们机器所能承受的最大QPS。但其实这种场景还是不够真实反映线上数据,因为压测往往只是压测几个接口,但是我们所有接口可没那么少,仅仅靠压测来评估还是欠缺准确性。

真实的线上压测

什么是真实的线上压测。

世界杯到了,海量的流量过来了,我们开始紧张地进行机器扩容,经过几次扩容,我们的机器终于能承受近期最高峰值了,QPS达到25W,那么是不是能用这个点的各项指标来做机器的容量评估呢?

我们把QPS在25W的时候的机器负载全部查出来,主要是CPU占比、内存占比和出外网带宽,对比当时单机的QPS。现在数据都有了,还是简单粗暴一点,认为QPS和各项指标存在线性关系,是不是2倍的QPS过来CPU也会翻倍呢?很难说,怎么验证这个线性关系是个问题。

大量机器负载样本

上面的方法还是不够有说服力啊。是不是样本太少了?我们决定把所有机器的负载和QPS全部跑出来看看。这里还是要感谢腾讯云提供了大部分机器负载数据供我们研究。还有我们的ELK上报系统,QPS数据就是从上面来的。

我把我们几百台机器的负载数据和QPS全部跑了出来,其中包括ngnix虚拟机、nginx容器、node虚拟机和node容器,一共起来有几百台机器。

负载样本

负载样本都有了,我们想得出各种机器的QPS和它们各项负载指标的关系,该怎么做?

尝试根据其中一个样本做个QPS和CPU的关系图:

QPS和CPU关系图

我眼睛花了…

最小二乘法

什么是最小二乘法?以下是维基百科看到的定义:

最小二乘法(又称最小平方法)是一种数学优化技术。它通过最小化误差的平方和寻找数据的最佳函数匹配。利用最小二乘法可以简便地求得未知的数据,并使得这些求得的数据与实际数据之间误差的平方和为最小。

回归分析

具体原理我就不班门弄斧,这个方法看起来很适合帮我们做容量分析,因为我们已经有了大量样本的,需要的就是在这些样本中找到一个关系,一个公式。

最小二乘法和容量评估

Matlab、Python 和 Ruby 都有对应的函数可以提供最小二乘法计算,这里我挑了 Python 的版本来说明下怎么使用,首先说明我是 Python 小白,写得不好请多多指教。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#!/usr/local/Cellar/python/3.7.0/bin/python3
# -*- coding: UTF-8 -*-

import matplotlib.pyplot as plt
import numpy as np
from excel import getNginx

# 获取到 Nginx 机器数据
cpu, qps, ram, bandWidth = getNginx()

cpu = sum(cpu, [])
qps = sum(qps, [])
ram = sum(ram, [])
bandWidth = sum(bandWidth, [])

# np.array 要求参数是 list,所以 qps 和 cpu 应该是一一对应的长度相同的 list
x = np.array(qps) # x 轴
y = np.array(cpu) # y 轴

z1 = np.polyfit(x, y, 1) # 1 代表单项式拟合,如果是 n,则代表多项式拟合,我们这里先计算线性函数
p1 = np.poly1d(z1) # 获取数据分析完成后的计算公式

print(p1)

# 绘图
yvals = p1(x)
plot1 = plt.plot(x, y, '*', label='original values')
plot2 = plt.plot(x, yvals, 'r', label='polyfit values')
plt.xlabel('x axis')
plt.ylabel('y axis')
plt.legend(loc=4)
plt.title('polyfitting')
plt.show()

运行一次分析 QPS 和 CPU 的关系试试看:

同时得到的计算公式是:y = 0.002823 x + 0.9327

再看下 QPS 和内存的关系:

所得到的公式是:y = 2.553e-05 x + 6.32

假设我们现在我们的 nginx 有 3W QPS 过来,计算得到 0.002823 * 30000 + 0.9327 = 85.6227,而内存是2.553 * 10e-5 * 30000 + 6.32 = 13.979,所以这个时候 CPU 负载会达到 85.6227%,内存负载会达到13.979%,其实已经和我们线上真实压测数据非常拟合了。

结论

这里通过最小二乘法来分析机器容量得到的公式已经非常接近我们的真实情况了,和机器学习一样,样本越多结果越可信,如果可以,每天收集样本一直跑下去,公式会越来越准确的。