学习记录,仅供参考
前面介绍了负载均衡的架构,实际运用中负载均衡器有多种分类(参考笔记一),当设备达到最佳线程数的时候,设备的并发量最大,下面主要介绍最佳线程数的计算。
一、并发类型
需要运用到并发操作的类型分为如下两种
1、CPU 密集型
对于CPU密集型计算, 多线程本质上是提升多核CPU的利用率, 所以对于一个4核的CPU, 每个核一个线程, 理论上创建4个线程就可以了, 再多创建线程也只是增加线程切换的成本。所以, 对于CPU密集型的计算场景, 理论上“线程的量=CPU核数”就是最合适的。但是在实际工作中, 一般会将线程数量设置为“CPU核数+1”, 这样的话, 当线程因为偶尔的内存页失效或其他原因导致阻塞时, 这个额外的线程可以顶上, 从而保证CPU的利用率 。
所以,在CPU密集型的程序中,一般可以将线程数设置为CPU核数+1。
最佳线程数= CPU核数(逻辑) + 1
2、I/O密集型程序
对于I/O密集型的程序,最佳的线程数是与程序中CPU计算和I/O操作的耗时比相关。总体来说,可以将其总结为如下的公式。
单核CPU
最佳线程数 = 1 +(I/O耗时 / CPU耗时)
多核CPU
最佳线程数 = CPU核数 * [ 1 +(I/O耗时 / CPU耗时) ]
公式变换
最佳线程数 = CPU核数 * [ 任务执行时间 / (任务执行时间 - I/O耗时) ]
推导过程:
CPU耗时 = 任务执行时间 - I/O耗时
任务执行时间 = CPU耗时 + I/O耗时
最佳线程数 = CPU核数 * [ 1 +(I/O耗时 / CPU耗时) ]
= CPU核数 * [ (CPU耗时 + I/O耗时) / CPU耗时 ]
= CPU核数 * [ 任务执行时间 / (任务执行时间 - I/O耗时) ]
假如服务的处理时间为30ms,其中CPU处理时间10ms,IO等待时间为20ms,采用4核服务器。
那么我们可以通过上述公式计算出最佳线程数为 12
4 * [ 1 + (20 / 10) ] = 4 * 3 = 12
或者
4 * [ 30 / (30 - 20) ] = 4 * 3 = 12
二、实际运用
1、实际线程数计算
假设要求一个系统的 TPS至少为20,然后假设每个Transaction由一个线程完成,继续假设平均每个线程处理一个Transaction的时间为4s,如何设计线程个数,使得可以在1s内处理完20个Transaction?
1个线程处理1个Transaction需要4s,那么 1秒处理 1 / 4 = 0.25
Transaction,需要1s完成20个处理,那么需要 20 / 0.25 = 80个线程。
CUP计算操作需要5ms,I/O操作需要 100ms,对于一台 8个CPU的服务器,怎么设置线程数呢?
根据上面的公式可以算出
线程数 = 8 * (1 + 100 / 5) = 168
实际情况中,单台设备的QPS上限为1000,如何设置线程数呢?
1s钟单线程处理的任务数量为:1000ms / 105ms
那么168个线程处理数量为 168 * ( 1000 / 105 ) = 1600
吞吐量上线为1000,那么同比 168 * ( 1000 / 1600 ) = 105
所以实际只能分配105个线程。
2、设备数计算
上述例子 CUP计算操作需要5ms,不考虑CPU切换时间,那么每面请求数量为
1000 / 5 = 200
那么8核CPU最大请求数量为
8 * 200 = 1600
每台可以处理的请求数量为每秒1600,服务并发量超过1600时,单台服务器已无法满足需求,此时需要多台服务器进行处理,此时需要用到负载均衡组件,即可以采用nginx软件负载均衡。
总请求数 / 单台设备并发数量 向上取整 = 服务器数量
如图所示: