关于合理地估算线程池大小的方案比较和误区分析

    总所周知,在涉及多线程开发时不可避免的需要进行线程池大小估算的工作。常见三种处理的方式有:1,根据网上的估算公式来估算,但是往往会发现没什么用,因为你计算不出来准确值。2,按照经验先估算一个大小(具有一定随意的成分),然后用jmeter等压测工具去压测,然后逐渐修改已达到较为合理的值。3,自己去思考一下,整理出上限的各项指标,例如qps,程序处理性能等,然后用公式去推导出较为合理的大小。

    方式一所参考的一般来说有如下的两种。

    方案一:参考公式1(阿姆达尔定律 (Amdahl's law)关联的一个经验公式):NThreads= Ncpu * Ucpu * (1 + W/C)。其中,NThreads=最佳线程数;Ncpu=CPU数量;Ucpu=目标cpu的使用率(0<= Ucpu <= 1);W/C=线程等待时间与计算时间的比率。

特别注意:

1.线程等待时间W是非CPU运行时间,比如IO,而非一个线程被另一个线程阻塞所耽搁的时间。

2.线程计算时间C是指平均每个线程CPU运行时间,例如在内存里计算数据的耗时等。

3.CPU数量动态获取:Runtime.getRuntime().avaliableProcessors().【java语言获取方式】

公式1中值得肯定的地方是:逻辑没啥毛病,站在CPU工作切换本身的维度,有一定道理。

否定之处在于:你怎么知道W/C到底是多少呢?很难估算。例如每个线程做的事情如下:先计算并组装一下数据(计算时间C),然后用该数据去发起网络请求去调用服务(线程等待时间W),然后用拿到的结果去计算并组装成新的数据(C),然后去读文件并写入(W)。。。亲爱的朋友们,你们能准确的计算出W/C的比值么?答案显然是不能,所以除非是大牛否则个人并不建议用该公式去计算。

 

    方案二:网上所谓的“简单可行”的方案(N为CPU总核数):

如果是CPU密集型应用,则线程池大小设置为N+1;

如果是IO密集型应用,则线程池大小设置为2N+1;

个人理解其实也是根据上面公式1中,cpu密集型应用,W/C接近0,大致推算出来的一个数据为N+1。IO密集型应用,大致2N+1较好。但是细心的朋友想过吗?CPU密集或者IO密集型应用,那么到底有多密集才算密集型?划分的依据很模糊,所以估算的方案终究是不够准的。

方式二:有一定的随意之处,但是随着压测进行,终究会得到一个较为合理的大小。毕竟实践是检验真理的唯一标准嘛。但是太过费时费力,且模拟多机多核会很费劲。

方式三:个人的解决方案如下:

1.先收集最大的承载能力的指标。例如:并发要能扛得住1000qps,延时要低于10s,单线程处理完一次请求任务耗时2s,一天总的请求量100W,以后部署在5台物理机上。

2.个人独创的计算公式:

设线程数为x,执行时间为y。

则考虑并发时公式如下:

1000qps/(x * 5) <= 10s/2s ,计算出x=40

数据量时,100W/(40 * 5) * 2s =  10000s < 24H,故一天内的请求量不是瓶颈所在(一般来说,总请求量都不会是瓶颈,瓶颈一般出现在并发上面,但是依然需要简单的分析一下),该线程数设置的可以满足上述指标的需要。

上述计算方案主要站在业务需求的角度,忽略了CPU使用率的因素,对于高IO的场景可能会CPU略有闲置,但是一定是可以满足业务需求的。如果确实CPU闲置较久,可以适当地减少线程数即可。毕竟对于一个公司级的应用,出于稳定性考虑,CPU一般也不建议高于百分之七十或者八十的。

 

总结:个人一家之言或有不足之处,欢迎各位看官和大佬们批评和指正。纯原创手打,感谢各位支持,么么哒。

版权所有,盗版必究,转载请征求本人同意。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值