高并发系统性能指标
高并发系统性能指标
系统的性能指标通常包含以下几个:
- QPS:每秒查询量
- TPS:每秒处理事务量
- RT:系统响应时间
- 并发数
- 吞吐量
QPS
QPS(每秒查询率,Queries Per Second)是衡量服务器性能的一个重要指标,表示服务器每秒能够处理的查询次数。QPS通常用于评估Web系统的吞吐率,即系统在单位时间内完成的用户或系统请求数量.
“每秒查询率”,是一台服务器每秒能够相应的查询次数,是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准。
计算公式:
QPS = 并发数 / 平均响应时间
假设处理一个业务请求的平均响应时间为100ms,同时系统内有10台Apache的Web服务器,配置Apache的最大连接数目为500,那么Web系统的理论峰值QPS为:QPS = 10 * 500 / 0.1 = 50000(5万QPS)
实际在高并发情况下,服务器的负载很高,平均响应时间会延长,因此我们通过增加缓存等各种优化其实就是在降低响应时间从而提高QPS;
用户的一次页面浏览操作,可能会有多个查询操作;
附注:通常QPS用来衡量服务器性能,我们也是不断的为增加它的数量而优化改进,通过多线程、增加负载、甚至提高代码质量、算法优化等方式。当然优化性能是有上限的,我们需要在性能和投入上作出一定的平衡。要对现有的业务状况、未来的发展潜力以及爆发力上作出一些判断,很好的驾驭它是需要花费一些精力的,需要经验和技术能力同时发挥作用,让效率和投入达到最好的产出。
TPS
TPS:是TransactionsPerSecond的缩写,也就是事务数/秒。具体事务的定义,都是人为的,可以一个接口、多个接口、一个业务流程等等。一个事务是指事务内第一个请求发送到接收到最后一个请求的响应的过程,以此来计算使用的时间和完成的事务个数。
Tps即每秒处理事务数,包括了
1、用户请求服务器
2、服务器自己的内部查询等处理
3、服务器返回给用户
QPS vs TPS:QPS基本类似于TPS,但是不同的是,对于一个页面的一次访问,形成一个TPS;但一次页面请求,可能产生多次对服务器的请求,服务器对这些请求,就可计入“QPS”之中。如,访问一个页面会请求服务器2次,一次访问,产生一个“T”,产生2个“Q”。
区别:
如果是对一个查询接口压测,且这个接口内部不会再去请求其它接口,那么 TPS = QPS,否则,TPS ≠ QPS
如果是容量场景,假设 N 个接口都是查询接口,且这个接口内部不会再去请求其它接口,QPS = N * TPS
RT
RT(Response-time)响应时间:执行一个请求从开始到最后收到响应数据所花费的总体时间,即从客户端发起请求到收到服务器响应结果的时间。该请求可以是任何东西,从内存获取,磁盘IO,复杂的数据库查询或加载完整的网页。
暂时忽略传输时间,响应时间是处理时间和等待时间的总和。处理时间是完成请求要求的工作所需的时间,等待时间是请求在被处理之前必须在队列中等待的时间。
响应时间是一个系统最重要的指标之一,它的数值大小直接反应了系统的快慢。
Concurrency并发数
并发数是指系统同时能处理的请求数量,这个也反应了系统的负载能力。
并发意味着可以同时进行多个处理。并发在现代编程中无处不在,网络中有多台计算机同时存在,一台计算机上同时运行着多个应用程序。
吞吐量
系统的吞吐量(承压能力)和处理对CPU的消耗、外部接口、IO等因素紧密关联。单个处理请求对CPU消耗越高,外部系统接口、IO速度越慢,系统吞吐能力越低,反之越高。
系统吞吐量有几个重要指标参数:QPS(TPS)、并发数、响应时间。
- QPS(TPS):(Queries Per Second)每秒钟请求/事务数量。
- 并发数: 系统同时处理的请求/事务数。
- 响应时间: 一般取平均响应时间。
理解了上面三个指标的意义之后,就能推算出它们之间的关系:
QPS(TPS)= 并发数/平均响应时间
并发数 = QPS*平均响应时间
案例
我们通过一个实例来把上面几个概念串起来理解。按二八定律来看,如果每天 80% 的访问集中在 20% 的时间里,这 20% 的时间就叫做峰值时间。
公式:( 总PV数 * 80% ) / ( 每天秒数 * 20% ) = 峰值时间每秒请求数(QPS)
机器:峰值时间每秒QPS / 单台机器的QPS = 需要的机器
每天300w PV 的在单台机器上,这台机器需要多少QPS?
( 3000000 * 0.8 ) / (86400 * 0.2 ) = 139 (QPS)
如果一台机器的QPS是58,需要几台机器来支持?
139 / 58 = 3
最佳线程数
计算密集型:CPU核数1
IO密集型:CPU核数2
1、单线程QPS公式:QPS=1000ms/RT(平均响应时间)
对同一个系统而言,支持的线程数越多,QPS越高。假设一个RT是80ms,则可以很容易的计算出QPS,QPS = 1000/80 = 12.5。即一秒钟最多支持13次访问请求。
多线程场景,如果把服务端的线程数提升到2,那么整个系统的QPS则为 2*(1000/80) = 25,可见QPS随着线程的增加而线性增长,那QPS上不去就加线程呗,听起来是这个道理,但是往往现实并非如此。
2、QPS和RT的真实关系
我们想象中的QPS、RT关系如下:
理想情况下,随着响应时间逐渐增大,QPS应该是缓慢降低;但是实际情况是当服务器响应时间增大到一个临界值,QPS会急剧降低。
最佳线程数量
刚好消耗完服务器的瓶颈资源的临界线程数,公式如下
最佳线程数量=((线程等待时间+线程cpu时间)/ 线程cpu时间)* cpu数量
如何理解:
io密集型
各个公式综合考虑io密集型和计算密集型两种任务,因此在评估最佳线程数量的时候,最好结合我们的任务分析,评估计算和io的时间占比。
特性:
- 在达到最佳线程数的时候,线程数量继续递增,则QPS不变,而响应时间变长,持续递增线程数量,则QPS开始下降。
- 每个系统都有其最佳线程数量,但是不同状态下,最佳线程数量是会变化的。
- 瓶颈资源可以是CPU,可以是内存,可以是锁资源,IO资源,超过最佳线程数-->导致资源的竞争,超过最佳线程数-->响应时间递增。
计算最佳线程数理论基础
线程数 = CPU核数 * CPU利用率 * (1 + W/C)
即:线程数 = CPU核数 * CPU利用率 * (1 + 等待时间/计算时间)
其中:
- CPU核数:物理CPU核心的数量
- CPU利用率:通常在0.8-0.9之间,表示CPU的期望利用率
- 等待时间(W):线程等待时间,如I/O操作时间
- 计算时间(C):线程实际运行计算的时间
这个公式考虑了以下因素:
CPU核数:更多的核心可以支持更多的并发线程。
CPU利用率:考虑到系统开销,通常不会将CPU利用到100%。
等待时间与计算时间的比率(W/C):
- 如果程序是计算密集型(W/C接近0),那么线程数约等于CPU核数。
- 如果程序是I/O密集型(W/C较大),则可以设置更多的线程数。
使用这个公式可以帮助开发者估算出一个合理的线程数,以充分利用系统资源,同时避免过多的线程造成的上下文切换开销。但需要注意,这只是一个理论估算,实际的最佳线程数还需要根据具体应用场景和性能测试来确定。
计算密集型
假设我们有一个计算密集型的任务,需要在一个具有8个CPU核心的系统上运行。对于计算密集型任务,等待时间(W)几乎为0,因为CPU大部分时间都在进行计算,而不是等待I/O操作。我们希望CPU的利用率接近100%,即CPU利用率为1。
将这些值代入公式中:
线程数 = CPU核数 * CPU利用率 * (1 + W/C)
由于W(等待时间)几乎为0,W/C也接近0,所以公式可以简化为:
线程数 = CPU核数 * CPU利用率
如果我们希望CPU利用率为100%,即CPU利用率为1,那么:
线程数 = 8 * 1 = 8
这就是为啥网上总说计算密集任务建议设置的线程数为:CPU核数*1的原因
I/O密集型
假设我们有一个I/O密集型的任务,需要在一个具有4个CPU核心的系统上运行。对于I/O密集型任务,等待时间(W)远大于计算时间©,因为CPU大部分时间都在等待I/O操作完成,而不是进行计算。我们希望CPU的利用率接近100%,即CPU利用率为1。
假设等待时间是计算时间的1倍,即W/C = 1。
将这些值代入公式中:
线程数 = CPU核数 * CPU利用率 * (1 + W/C)
线程数 = 4 * 1 * (1 + 1)
线程数 = 4 * (1 + 1) = 4 * 2 = 8
这就是为啥网上总说IO密集任务建议设置的线程数为:CPU核数*2的原因