乐趣区

关于后端:如何提升QPSRT

对于 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

如果我的文章对你有所帮忙,还请帮忙 点赞、转发 一下,你的反对就是我更新的能源,非常感谢!

退出移动版