线程池要设置多大
https://cloud.tencent.com/developer/article/1605149
线程数是怎么设置的呢?
服务器的配置、服务器资源的预算和任务自身的特性。具体来说就是服务器有多少CPU、多少内存、IO支持的最大QPS是多少,任务主要执行的是计算、IO还是混合操作。任务中是否包含数据库连接等的稀缺资源。
假设机器有N个CPU,对于计算密集型的任务,应该设置线程数为N+1;对于IO密集型的任务,应该设置线程数为2N。
而对于同时有计算工作和IO工作的任务,应该考虑使用两个线程池,一个处理计算任务,一个处理IO任务,分别对两个线程池按照计算密集型和IO密集型来设置线程数。
N+1和2N都是经验值。
首先计算CPU的利用率A,为了让CPU到达100%,可以设置A的倒数个线程X。
如果IO操作是DB操作,而DB的QPS上限是1000,这个线程池又该设置为多大呢?
可以先计算出X个线程数的QPS大小,然后和1000比较,按相同比例设置线程的个数。
线程数的第一种计算方法
在一个基准负载下,使用几种不同大小的线程池运行你的应用程序,并观察CPU利用率的水平。
给定下列定义:
Ncpu = CPU的数量
Ucpu = 目标CPU的使用率, 0 <= Ucpu <= 1
W/C = 等待时间与计算时间的比率
为保持处理器达到期望的使用率,最优的池的大小等于:
Nthreads = Ncpu x Ucpu x (1 + W/C)
第二种计算方法
线程数 = CPU可用核心数/(1 - 阻塞系数),其中阻塞系数的取值在0和1之间。
计算密集型任务的阻塞系数为0,而IO密集型任务的阻塞系数则接近1。
一个完全阻塞的任务是注定要挂掉的,所以我们无须担心阻塞系数会达到1。
阻塞系数可以通过公式:阻塞系数=阻塞时间/(阻塞时间+计算时间),其实也就是上一种算法中的W/C的方式来计算,所以阻塞系数也是可以通过基准程序计算得出的。
所谓的经验值由来
以第一种计算方式来看,对于计算密集型应用,假定等待时间趋近于0,使得CPU利用率达到100%,那么线程数就是CPU核心数,那这个+1意义何在呢?
计算密集型的线程恰好在某时因为发生一个页错误或者因其他原因而暂停,刚好有一个“额外”的线程,可以确保在这种情况下CPU周期不会中断工作。
所以N+1确实是一个经验值。
而对于IO密集型应用
W/C值趋向于1,那么线程数应该去2N。