不压测,如何估算单机最大QPS?
共 1030字,需浏览 3分钟
·
2021-08-25 04:43
日常工作中,在监控系统上我们能看到一个微服务的总QPS和每台机器的单机QPS,但这个数值并不是单机能承受的最大值。
想要知道单机最大QPS,一个办法是压测。那有没有办法,在不压测的情况下,对单机QPS做一个预估呢?
先看一个评估单机最大QPS的简单方法:假设系统处理一个请求的响应时间是100ms,则1s可以处理10个请求,然后CPU是24核,所以QPS = 10*24 = 240。
请问,这个评估方法正确吗?如果是一个纯粹的CPU密集型应用,只读写内存,无任何磁盘I/O,网络I/O(RPC调用、数据库访问、缓存读写),则这个评估方法基本是正确的。
但实际上,对于大部分的Web应用来说,虽然请求处理时间是100ms,但不代表CPU就运行了100ms。那我怎么知道,这100ms,哪些是耗在了CPU计算,哪些是耗在了数据库访问,哪些是耗在了磁盘读写呢?一个办法是对代码做profiling,对代码打点,统计这100ms的耗时分布。
假设,最终发现:
100ms = 10ms(CPU计算)+ 70ms(数据库访问)+ 20ms(缓存读写)
那意味着CPU只运行了10ms,另外90ms都是空闲的,在等待I/O。假设让CPU跑满,1s钟则应该可以处理100个请求,则估算的最大QPS = 100 * 24 = 2400。(这里是假设CPU是整个系统的资源瓶颈,不是内存、带宽)
当然,要达到2400/s,得让CPU充分利用,不等待I/O,那技术上如何实现呢?
(1)开多线程
线程个数 = CPU核数 * (线程等待时间 + 线程CPU时间)/ 线程CPU时间
在这个例子中,就是24 * 100/10 = 240个线程。当然,线程多了,线程切换也需要耗费一定的CPU时间,所以实际效果可能是比2400qps略小。
(2)使用异步I/O
不等待I/O,每个CPU只需要一个线程,线程数 = CPU数。最典型的例子就是Redis和Nginx,前者是单线程程序,后者是单进程程序,跑一个CPU。有多少个CPU,就部署多少个实例。
知道了单机的最大QPS,紧接着就是下1个问题:
我怎么知道这个最大QPS已经是上限了,还有多大提升空间?