使用SLS和ODPS进行系统的性能分析
作者:陈昕
在对计算机系统,尤其是分布式系统的搭建和验证过程中,性能因素是需要着重考虑的因素之一。更激进一点说,判断架构设计的正确与否,性能的好坏、是否可控、是否可预期绝对是最有效的衡量指标。
不幸的是,现有的性能工具大部分是针对代码级的运行时间进行分析,目标是诊断代码的性能bug。但目前我们并没有(或者我还没见到)针对大型的分布式系统的系统级性能分析工具。
虽然这样,但我们可以发扬DIY精神,卷起袖子自己来做这样的性能分析。通过简单日志服务(SLS)对性能日志进行收集,并使用SLS的离线通道将性能相关的数据导入ODPS中,再拿出专业的数据分析工具R语言,就能够做任意的性能分析了。只有想不到,没有做不到!
我们就以OXS场景来作背景,来看看不同时刻从OXS前端机发送到XXEngine的XXServer的请求是否均匀,是否有热点,热点是如何转移的,以及对性能的影响。从这个很有现实意义的例子来看看如何使用这样的方法来进行性能分析。
记录性能日志
所谓“巧妇难为无米之炊”,在性能分析的第一步一定要准备性能数据。在系统中打出一条性能日志应该是代价很小的一种方案。
对于飞天来说,在代码中添加一条性能日志也十分容易。飞天的日志可以采用异步的方式打出,所以几乎不会影响原有系统的性能。日志中最好记录一些与性能相关的数据和信息。如在XXServer 中就会记录如下的性能日志:
上述日志中记录了当时的时间点、请求类型、请求到达的时间点、在队列中等待的时间、系统处理这个请求的时间等有用的信息。
注意:为了收集日志的方便,最好单独将性能日志输出到一个日志文件中。
用SLS收集日志
性能日志如果可以正常生成,就可以配置SLS收集这些日志了。这篇文档(SLS控制台操作指南)详细讲述了如何配置SLS进行日志收集,这里就不再赘述了。
日志如果正常收集,可以从SLS的控制台上看到:
使用SLS的离线导入功能写入ODPS
在日志收集完成后,就能够用SLS的离线导入功能导入ODPS中,将这些数据持久化下来,也为之后的离线分析做准备。具体操作步骤请见文档(日志数据离线归档到ODPS参考手册、ODPS产品帮助文档)。此处不再赘述。
导入成功后就可以在ODPS中查到性能数据,如图:
使用R + ODPS进行性能分析
好的,终于可以开始正式进行性能分析啦。我们用的工具是专业的数据分析工具R语言。
首先载入数据:
注:rodps是ODPS内部基于R实现的SDK,还未通过阿里云服务对外开放。
一阵查询之后,我们需要的原始数据已经准备在了data这个数据框里面。需要解释一下的是qps这个字段计算的是不同的ip在查询范围内的任意一秒内处理好的请求数,我们约可以看作任意一秒内到达的请求数。
我们先将这个数据分成两部分,一部分是0点到1点的数据,另一部分是1点到2点的数据。使用如下的命令放入data_ext_0和data_ext_1两个数据框中:
请求的热度
为了知道不同机器的请求的热度,我们可以先做一下QPS的密度图看下:
从图上看,明显能够看出在不同时间段不同机器的请求热度又明显的不同,而且热度相当不均匀,最热的机器基本是最冷的机器的5-6倍左右。
图上还可以基本看出,与0-1点的到达率相比,1-2点大部分机器的密度图都有不同程度的右移,这意味着大部分机器的请求到达率有所提升。而0-1点到达率最高的一个机器(也就是xxx.xx.10.47),反而在1-2点的时候请求到达率有一定程度的下降。
让我们来定量地分析一下数据,看看是否能够支持上述结论。先是0-1点的数据,根据不同的机器IP统计出其均值(Mean)与标准差(SD):
输出(整理一下格式):
IP | xxx.xx.10.10 | xxx.xx.10.32 | xxx.xx.10.36 | xxx.xx.10.37 |
Mean(SD) | 93.49 (52.70) | 115.31 (65.45) | 150.41 (65.39) | 119.32 (72.38) |
IP | xxx.xx.10.38 | xxx.xx.10.39 | xxx.xx.10.40 | xxx.xx.10.41 |
Mean(SD) | 138.49 (74.21) | 158.57 (75.97) | 172.67 (106.83) | 132.28 (98.17) |
IP | xxx.xx.10.42 | xxx.xx.10.43 | xxx.xx.10.44 | xxx.xx.10.45 |
Mean(SD) | 133.97 (82.95) | 131.00 (72.58) | 62.11 (29.37) | 58.30 (28.62) |
IP | xxx.xx.10.46 | xxx.xx.10.47 | xxx.xx.10.9 | |
Mean(SD) | 170.90 (101.15) | 386.26 (67.11) | 127.19 (75.35) |
然后是1-2点的数据:
输出:
IP | xxx.xx.10.10 | xxx.xx.10.32 | xxx.xx.10.36 | xxx.xx.10.37 |
Mean(SD) | 93.78 (34.55) | 127.95 (34.14) | 171.14 (40.28) | 123.52 (35.96) |
IP | xxx.xx.10.38 | xxx.xx.10.39 | xxx.xx.10.40 | xxx.xx.10.41 |
Mean(SD) | 137.95 (43.62) | 120.44 (33.79) | 163.92 (43.58) | 106.91 (31.78) |
IP | xxx.xx.10.42 | xxx.xx.10.43 | xxx.xx.10.44 | xxx.xx.10.45 |
Mean(SD) | 139.55 (58.75) | 126.46 (35.30) | 69.72 (32.79) | 55.37 (24.16) |
IP | xxx.xx.10.46 | xxx.xx.10.47 | xxx.xx.10.9 | |
Mean(SD) | 178.37 (52.25) | 265.73 (50.06) | 108.33 (29.51) |
比较这两组数据,能够看到机器xxx.xx.10.10、xxx.xx.10.32、xxx.xx.10.36、xxx.xx.10.37、xxx.xx.10.42、xxx.xx.10.44、xxx.xx.10.46请求平均到达率有不同程度的提升,除了xxx.xx.10.47这台机器外,其余机器的到达率的热度有些微下降。xxx.xx.10.47这台机器的热度下降明显(从平均每秒到达386.26个请求降到了平均每秒到达265.73个请求),但这台机器依然是热度最高的机器。
定量的分析也能够支持之前我们所观察到的结论。这样,我们就能把热度的变化直观、准确地描述出来。当然,我们可以继续细化模型,从更多的维度观察系统内正在发生的事情,得到更多更精确的结论。如Partition级的热度统计,秒级的热点迁移的变化等等。
以上所使用的数据分析工具仅限于作图和统计均值、标准差。下面我们仍然以这些数据为基础,使用稍微高级一些的方法,得到一些更有意思的结论。
请求之间是否互相独立
理论上,如果请求之间都是独立的话,QPS的数值应该服从Poisson分布。那么我们可以沿着这个思路,通过判断各个机器在不同时间点上是否服从Poisson分布即可知道请求间的独立性。
我们可以通过拟合Poisson分布,根据拟合的标准差判断真实的数据与理论分布的差值。标准差越小,说明越服从Poisson分布,也就意味着这个XXServer收到的请求从时间上看越独立。
拟合分布的原理较简单,以Poisson为例:我们知道Poisson分布的概率质量函数是
其中只有一个参数。而Poisson分布的均值(Mean)也为。于是我们可以以样本的均值来作为拟合的Poisson理论分布的参数,那么这个Poisson分布就被唯一确定了。之后我们需要计算样本的抽样点与理论分布的对应点的偏差,将他们加和之后再归一化就是标准差了,作为样本与理论模型间差异度的衡量指标。一图胜千言:
标准差就是样本数据(直方图)与理论分布(红线)的差值的绝对值的和与均值的比值。
实际中,不必手工将上面的步骤都做一遍,R语言中MASS包的函数fitdistr就可以进行分布拟合。下面我们用的就是这种方法。
我们先来看看0-1点的结果:
结果会是这样的形式(截取一部分):
整理一下结果的样式:
IP | xxx.xx.10.10 | xxx.xx.10.32 | xxx.xx.10.36 | xxx.xx.10.37 |
SD |
16.1% |
17.9% |
20.4% |
18.2% |
IP | xxx.xx.10.38 | xxx.xx.10.39 | xxx.xx.10.40 | xxx.xx.10.41 |
SD |
19.6% |
21.0% |
21.9% |
19.2% |
IP | xxx.xx.10.42 | xxx.xx.10.43 | xxx.xx.10.44 | xxx.xx.10.45 |
SD |
19.3% |
19.1% |
13.1% |
12.7% |
IP | xxx.xx.10.46 | xxx.xx.10.47 | xxx.xx.10.9 | |
SD |
21.8% |
32.8% |
18.8% |
我们可以看到最服从Poisson分布的机器是xxx.xx.10.45,标准差值有12.7%,已经相当不错了。而偏差最大的则是机器xxx.xx.10.47,标准差已经达到了32.8%。注意到xxx.xx.10.47这台机器同时也是热度最高的一台机器,那么这个数据暗示我们有可能是我们的系统设计的不够好,以致相同的一批请求连续访问了某台机器,造成了热点的不均衡。
好的,我们再看看1-2点的数据:
得到的结果整理如下:
IP | xxx.xx.10.10 | xxx.xx.10.32 | xxx.xx.10.36 | xxx.xx.10.37 |
SD |
16.1% |
18.9% |
21.8% |
18.5% |
IP | xxx.xx.10.38 | xxx.xx.10.39 | xxx.xx.10.40 | xxx.xx.10.41 |
SD |
19.6% |
18.3% |
21.3% |
17.2% |
IP | xxx.xx.10.42 | xxx.xx.10.43 | xxx.xx.10.44 | xxx.xx.10.45 |
SD |
19.7% |
18.7% |
13.9% |
12.4% |
IP | xxx.xx.10.46 | xxx.xx.10.47 | xxx.xx.10.9 | |
SD |
22.3% |
27.2% |
17.3% |
这个数据与0-1点的数据做比较后,发现不同机器的请求时间独立性各有增高或降低。尤其是xxx.xx.10.47这台重点机器,在热度降低后,请求间独立性加强了,可能意味着一些连续的访问被调度到了其他的机器上。
从这个例子中,我们看到了不仅热度是变化的,而不同XXServer上处理的请求的独立性也是会转移的。之前我们一直在关注请求的到达的特性,那么下面我们来看看用户和系统设计者最关心的指标——系统的延时吧。
请求的延时与热度的关系
由上面的分析可知,在不同时间段内不同机器的热度是不同的,那么我们推测这些机器的平均请求延时也是不同的。所以我们下面要进行的是一种时间序列分析。
我们先使用ODPS强大的数据处理能力按照分钟粒度来准备数据,再整理一下时间表示,改为相对时间:
这样就拿到了15台机器两个小时内每分钟的平均请求到达率(QPS)和平均请求延时数据。我们先看下这些机器在不同时间上的请求到达率的变化:
再看下这些机器在不同时间上的请求延时的变化:
是不是感到眼花缭乱?那我们先把xxx.xx.10.10的数据抽取出来,分析分析,然后再应用到别的机器上。先做个图,看看QPS和Latency之间是否有联系:
确实能够看出QPS和延时之间是有一定的相关关系的,那么我们就会进一步问:这两者之间的关系是否能够被定量地描述呢?
这个问题就需要我们更进一步的思考和分析了。我们注意到,似乎这两者存在着线性关系。我们可以使用线性回归的方法来验证这一点。目前由于我们所收集的数据的维度较少,仅能够推测QPS与延时的关系,这种只有一个自变量和一个因变量的线性回归方法叫做简单线性回归。
在R中,可以使用函数lm来进行线性回归。为了展示方便,我们把延时的单位从us转换为ms,进行回归:
输出的结果如下:
注意到线性回归中QPS项是统计显着的(p值<0.001),调整后的回归系数是50%,表示样本数据中有一半都可以被线性模型解释。而QPS每增加1,平均请求的延时增加1.23 ms。
既然线性模型Work的不错,那么我们来看看这15台机器各自的QPS的影响和回归系数吧:
得到的结果的格式如下:
整理一下这个结果,可以得到下面的表格:
IP | QPS Coef | Adj.R.Sqr |
xxx.xx.10.10 | 1.23 | 0.50 |
xxx.xx.10.32 | -0.02 | 0.03 |
xxx.xx.10.36 | 0.01 | -0.00 |
xxx.xx.10.37 | 0.01 | -0.01 |
xxx.xx.10.38 | 0.00 | -0.01 |
xxx.xx.10.39 | 0.03 | 0.04 |
xxx.xx.10.40 | -0.02 | 0.03 |
xxx.xx.10.41 | -0.02 | 0.11 |
xxx.xx.10.42 | -0.02 | 0.06 |
xxx.xx.10.43 | 0.01 | 0.01 |
xxx.xx.10.44 | -0.00 | -0.01 |
xxx.xx.10.45 | 0.07 | 0.08 |
xxx.xx.10.46 | -0.01 | -0.00 |
xxx.xx.10.47 | -0.01 | 0.02 |
xxx.xx.10.9 | 0.01 | -0.00 |
不幸地,除了第一台机器xxx.xx.10.10外,其他机器的回归系数都不到10%,QPS的系数也非常低。这只能说明简单线性模型对其他机器的性能表现几乎无法刻画。虽然没有得到预期的结论,但是我们可以得到一个相反的可能有些和直觉相悖的结论:XXServer端的请求平均延时与请求的热度并没有多大的简单线性关系。
本节的分析说明了简单线性模型难以刻画系统的延时及其决定因素。既然延时对系统如此重要,是不是还有别的方法来深挖决定系统延时的因素呢?答案是肯定的,比如我们可以收集更多的数据,进行多元线性回归; 或者可以假设不同自变量对因变量的影响不一定是一次的,而有可能是二次的、三次的,这样的多项式回归等。甚至使用各种非线性回归方法以及其他的分析方法。
这里大家可以多试试不同的模型和方法,一定会有不少收获。
结语
SLS大大降低了分布式系统下的性能日志的收集和查询的成本,而ODPS强大的离线数据分析和处理能力则使大规模性能数据的处理成为了可能。这两个工具为我们打开了一扇系统级的性能分析的大门。
在这些强大的计算能力的支持下,利用通用的数据分析方法和性能领域模型,不仅可以监控系统的性能表现、探寻性能问题产生的部位和原因,还能够对系统的性能是否符合设计预期进行验证、评估系统的设计与实现。进而提高我们的产品和服务的质量,最终获得客户的认可。当然,目前这项工作的状态还比较初级,还有许多的工作要做。
希望本文能够大家提供一个新的看待系统性能的方法,也请大家多多实践,多多交流。祝玩得愉快!
P.S. 上文中一定有许多错误,还请各位大拿拍砖。
最后更新:2017-04-03 05:39:44