一、RT(Response-time、响应时间)
响应时间是用户请求发出和服务器返回之间的时间差。
这个过程包括DNS解析、网络数据传输、服务器计算、网络数据返回,如下图例子:
期中,服务器计算时间又可细分为:
1. Web Server响应的时间;
2. App Server响应的时间;
3. CPU执行时间;
4. 线程等待时间(DB、存储、rpc调用等导致的IO等待,sleep,wait等等)。
RT的大小与用户体验密切相关
开发人员能够有效去优化的,是CPU执行时间,线程等待时间两大部分。
二、QPS(Query-per-second)
定义:QPS是指在一定并发度下,服务器每秒可以处理多少请求,通常我们要算的是在资源充分利用而不过度的前提下的合理QPS。
提高QPS能将服务器资源的充分利用, QPS提升1倍理论上服务器数能减少1半。
TPS类似,本文统一用QPS来贯穿讲解。
3.1 QPS计算
QPS = 并发线程数量 * 1000/线程RT
缩短线程RT,QPS未必会变!因为随着RT变化支持的并发线程数也可能会跟着变,这里涉及一个新的概念:最佳线程数量。
3.2 最佳线程数
最佳线程数量:刚好消耗完服务器的瓶颈资源的临界线程数
备注:瓶颈资源可以是CPU,可以是内存,可以是锁资源,也可以是IO资源
举例:在一个4cpu的服务器上,有这样一个线程:
• 预处理数据耗时 15ms
• 调用rpc等待耗时 80ms
• 解析结果耗时 5ms
-
如果CPU计算为瓶颈资源,那么
最佳线程数量 = ((RT) / RT中CPU执行时间) * CPU数量=( (15+80+5) / (15+5) ) * 4 cpu = 20
-
如果调用rpc的方法加了同步锁,且这个锁是瓶颈资源,那么
由于同步锁是个串行资源,并行数是1,所以
最佳线程数量 = (RT / RT中的lock时间) * 1 = ((15+80+5) /80) * 1个串行锁 = 1.25
-
同理,以xx为瓶颈资源为例,计算最佳线程数量
最佳线程数量=(RT/xx瓶颈资源时间) * xx瓶颈资源的线程并行数
总结:
最佳线程数量=(线程总时间/瓶颈资源时间)*瓶颈资源最佳线程数
QPS = 1000/RT中瓶颈资源时间 * 瓶颈资源最佳线程数
所以理论上如果缩短的是在瓶颈资源上消耗的RT是能提升QPS的,
缩短其他RT则不行,因为最佳线程数会跟着变,且理论上会变得恰好是“刚好消耗完服务器的瓶颈资源的临界线程数”,最终还是取决于瓶颈资源。
三、性能曲线模型分析
典型的性能趋势变化的曲线拐点模型图如下:
1)X轴从左往右分别是轻压力区、重压力区、拐点区。
2)响应时间:随着线程并发数增加,在轻压力区的响应时间变化不大,比较平缓,进入重压力区后响应时间先呈现增长的趋势,然后进入拐点区后响应时间急剧增大。
3)吞吐量:随着并发线程数的增加,吞吐量增加,进入重压力区后逐步平稳,到达拐点区后急剧下降,这个时候系统已经达到了处理极限,再继续压系统性能就会急剧下降甚至崩溃。
4)资源利用率:随着并线程数的增加,资源利用率逐步上升,最后达到饱和状态,资源利用率见顶后横盘不再涨。
5)综合分析:
-
随着线程并发数的增加,吞吐量与资源利用率增加,在达到最佳线程数的时候,QPS达到比较理想的顶点。
-
在QPS达到顶点后线程数继续递增,QPS一开始不变,但RT会增大:线程增多RT增大并不是说我们的代码执行效率下降了,而是资源的竞争,导致线程等待的时间上升了。
-
但随着并发线程的持续增加,吞吐量与资源利用率都达到了饱和,随后资源争抢加剧开始导致资源浪费,所以吞吐量急剧下降,并且响应时间急剧增长。
-
轻压力区与重压力区的交界点是系统的最佳线程数,因为各种资源都利用充分,且响应也很快;而重压力区与拐点区的交界点就是系统的最大线程数,若超过这个点,系统性能将会急剧下降甚至崩溃。
四、QPS及RT相关总结
-
支撑同样的业务量,QPS大小和机器数量成反比。
-
只有在瓶颈资源上进行优化才能提升QPS,瓶颈资源可以包括CPU、内存、锁、IO、外部依赖、甚至网卡等等
-
QPS和RT是性能优化的两个不同的方向,二者并无绝对必然的联系,他们的优化也有不同的思路。
-
但在大多数情况下,如果别的资源瓶颈不够明显,在高并发下RT越大越容易出现线程堆积,到一定程度就会开始线程争抢CPU资源造成资源浪费,所以很多时候RT越高会越快间接导致CPU资源变成瓶颈。
所以,虽然RT不是资源更不是瓶颈,但RT过大却能间接带来CPU的瓶颈。
备注【CPU时间片】:
程序的任何指令的执行往往都会要竞争CPU这个最宝贵的资源,不论你的程序分成了多少个线程去执行不同的任务,他们都必须排队等待获取这个串行资源来计算和处理命令。在Linux的内核处理过程中,每一个进程默认会有一个固定的时间片来执行命令(默认为1/100秒),这段时间内进程被分配到CPU,然后独占使用。如果使用完,同时未到时间片的规定时间,那么就主动放弃CPU的占用,如果到时间片尚未完成工作,那么CPU的使用权也会被收回,进程将会被中断挂起,等待下一个时间片。
</article>