对于QPS,RT这些名词想必大家都不生疏,然而说到如何晋升他们却束手无策。明天咱们就来钻研一下吧
目录
名称解释
QPS与线程数的关系
最佳线程数
案例
优化方向
QPS与RT的关系
总结
名词解释
RT(Response Time): 1个申请所实现的工夫
QPS(Query Per Second): 1秒钟内所实现的申请数量
QPS与线程数的关系
对于单线程而言,QPS = 1000ms/RT
比方一个零碎只有一个线程,响应工夫为50ms,那么它的qps就是1000/50=20
如果它有两个线程,那么它的qps为:20*2=40
这里假如不受cpu、io、内存等其余影响
实践上服务器可能反对的线程数越多,那么qps就会越高,qps与线程数成正比例关系。
当然,服务器的资源是无限的,在理论压测过程中,开始时QPS将随着线程数的减少而减少,当线程数达到肯定数量,达到cpu瓶颈时,qps放弃不变,随着持续压测,qps还会稍微降落,并且响应工夫变长。
起因其实很简略,在cpu资源短缺时,线程有足够的cpu执行工夫用于运行程序,当线程数达到肯定数量,同时cpu资源耗尽时,线程开始争抢cpu,频繁产生线程上下文切换(该过程非常耗时),线程之间相互期待,响应工夫天然减少。
最佳线程数
通过QPS与线程数的关系,能够很容易的就能得出一个概念。
最佳线程数:刚好耗费完服务器资源的临界线程数。
公式:最佳线程数 = ((线程等待时间 + 线程cpu工夫)/ 线程cpu工夫) * cpu数量
等价于: 最佳线程数 = (线程等待时间/ 线程cpu工夫 + 1) * cpu数量
网上是第一种,等价的公式是我换算的,因为能解释出具体的意义
当然,如果你晓得第一种公式的具体意义,还请通知我
公式阐明
假如在单线程状况下,线程等待时间为100ms,线程cpu工夫为20ms,在线程期待的100ms,cpu是处于闲暇状态,那么咱们便能够把这100ms交给其余的线程应用,一共能够给多少个线程应用呢,每个线程须要cpu20ms,那么就是:100/20 = 5, 再加上本人这个线程就是6,所以在这一个时间段内cpu最大能够摆布的线程数为6,如果服务器有2个cpu,那么就是6*2 = 12。
套用公式:(10/2 + 1)*2 = 12
当然,在理论执行中,必定不是他20ms我20ms这样的,而是cpu为每个线程调配工夫片交替执行
个性
在达到最佳线程数时,线程数量持续减少,但qps不变,而响应工夫变长,持续减少线程数,qps开始降落。
如何失去最佳线程数
1、通过压测的形式,迟缓递增线程数,察看压测状况,依据个性会很容易获得最佳线程数
2、通过公式间接进行计算,这个形式有点难,因为咱们难以晓得零碎的线程cpu工夫与线程等待时间
3、依据第一种形式的改良,进行一次压测,察看cpu状况,而后将线程数*(cpu期望值/以后cpu值),就会失去一个大略值,而后略作调整即可失去最佳线程数。
案例
为了更好的意识以上实践,并探讨如何晋升QPS,咱们通过springboot构建一个测试案例
定义一个用于模仿cpu执行的办法
public long runCpu(int count){ long start = System.currentTimeMillis(); // 用几个参数让cpu运行 int a = 0; double b = 0; long c = 0; for (int i = 0; i < count; i++) { for (int j = 0; j < 100; j++){ a++;b++;c++; a=a*2;b=b/2; a=a/2;b=b*2; c=c*2;c=c/2; a--;b--;c--; } a++;b++;c++; } System.out.println(a); // 返回运行工夫 return System.currentTimeMillis() - start;}
count参数使得该办法的运行工夫存在可变性
定义压测接口
/** * @param count 循环次数,用于模仿cpu运行工夫 * @param sleep io工夫 毫秒 */@GetMapping("/benchmark")public String qps(int count, long sleep) throws InterruptedException { long start = System.currentTimeMillis(); // cpu运行工夫 long cpuTime = runCpu(count); long ioStart = System.currentTimeMillis(); // 模仿io阻塞 Thread.sleep(sleep); long ioTime = System.currentTimeMillis() - ioStart; long total = System.currentTimeMillis() - start; return "total: "+ total + " cpu-time:" + cpuTime + " io-time:" + ioTime;}
为了不便测试,我将它做成了镜像,应用docker运行
这是我的docker-compose文件,给了2个cpu
version: '3.5'services: qps-test: image: qps-test:1.0.0 container_name: qps-test ports: - 8080:8080 resources: limits: cpus: '2.00'
第一次测试,将count调为100000(这里相当于我机器的cpu-time为10~20ms),io time为80ms
http://192.168.65.206:8080/qp...
得出后果如下
RT | qps | cpu | 最佳线程数 |
---|---|---|---|
103 | 125 | 190% | 13 |
单线程的QPS: 1000/103 = 9.7
可能会有小伙伴不知道怎么调出这个后果的,这里我简略阐明下
首先咱们须要晓得,服务器的瓶颈在cpu上,因为我这个案例不可能存在内存瓶颈,所以咱们须要将cpu压测到190%左后(临界cpu的瓶颈),如果压到了200%,阐明此时线程数很可能曾经超了,cpu资源已耗尽,就须要升高线程数,如果没到190%,就持续减少压测线程,直到恒定在190%左右。
压测工具我用的是jmeter
有了这个基准数据,当初就要尝试进行晋升qps
优化方向
依据公式:QPS = (1000/RT) * 线程数
因为cpu资源曾经将要耗尽,那么咱们就只能尝试升高响应工夫
而响应工夫分为两个局部:cpu工夫和线程等待时间,所以咱们从这两个方面动手。
升高IO等待时间
咱们尝试将io理论从80ms降为40ms
http://192.168.65.206:8080/qp...
进行压测后果如下:
RT | qps | cpu | 最佳线程数 |
---|---|---|---|
65 | 123 | 190% | 8 |
单线程QPS: 1000/65 = 15.4
咱们发现响应工夫尽管从原来的103变为了65,但qps却简直未变,而最佳线程数从13变为了8
得出结论:升高IO工夫并不能晋升QPS,为什么?
咱们依据CPU资源恒定准则:CPU资源 = 线程的cpu工夫 线程总数 单线程的qps
所以得出式子:基准数据的cpu每秒的解决工夫 = 升高IO等待时间的cpu每秒的解决工夫
23ms 13 9.7 = 25ms x 15.4 解出 x = 7.53
其中25ms为RT(65) - IO(40) 15.4为1000/65
线程数 | 单线程QPS | RT | CPU解决工夫 | QPS |
---|---|---|---|---|
13 | 9.7 | 103 | 23ms 13 9.7 | 125 |
x ≈ 8 | 15.4 | 65 | 25ms x 15.4 | 123 |
升高CPU执行工夫
咱们将cpu运行工夫削减个别,count值100000 -> 50000
http://192.168.65.206:8080/qp...
进行压测后果如下:
RT | qps | cpu | 最佳线程数 |
---|---|---|---|
101 | 244 | 190% | 25 |
单线程qps: 1000/101 = 9.9
响应工夫简直未产生扭转,但QPS翻了一倍,最佳线程数也翻了一倍
得出结论:升高cpu工夫能显著晋升QPS
同样依据CPU资源恒定准则失去:
23ms 13 9.7 = 21ms x 9.9
x ≈ 14
因为未知起因,这里翻车了,按理说cpu工夫该当为10ms左右,因为count值减半了。
如果cpu工夫为10ms~15ms,那么x就靠近25,合乎压测状况了。这里猜想是因为io工夫有误,导致RT变长。
小结
count | sleep | RT | qps | cpu | 最佳线程数 |
---|---|---|---|---|---|
100000 | 80ms | 103 | 125 | 190% | 13 |
100000 | 40ms | 65 | 123 | 190% | 8 |
50000 | 80ms | 101 | 244 | 190% | 25 |
QPS与RT的关系
如果说单纯的依据公式:QPS = 1000/RT,QPS与RT的关系如下
但通过案例咱们的得悉,在理论状况下,QPS与RT的关系并非如此,RT中的存在两种工夫对QPS有所影响。
CPU执行工夫缩小,QPS显著晋升。
IO等待时间缩小,QPS晋升不显著或者无晋升。
总结
通过以上内容分析,如果想要晋升RT
1、缩小IO的响应工夫
2、缩小CPU的执行工夫
如果想要晋升QPS
1、缩小CPU的执行工夫
2、减少CPU数量
提醒:如果在压测过程中,cpu还未达到瓶颈,QPS就曾经达到了峰值,那么则阐明存在其余的瓶颈,如内存
参考资料
https://www.docin.com/p-73662763.html?docfrom=rrela
追更,想要理解更多精彩内容,欢送关注公众号:程序员阿紫
集体博客空间:https://zijiancode.cn
如果我的文章对你有所帮忙,还请帮忙点赞、转发一下,你的反对就是我更新的能源,非常感谢!