合理设置工作线程数

最大工作线程数,后端服务一般也有个配置,工作线程池的线程数量,这个线程数的配置不同的业务架构师有不同的经验值,有些业务设置为CPU核数的2倍,有些业务设置为CPU核数的8倍,有些业务设置为CPU核数的32倍。

一个典型的工作线程的处理过程,从开始处理start到结束处理end,该任务的处理共有7个步骤:

  • 从工作队列里拿出任务,进行一些本地初始化计算,例如http协议分析、参数解析、参数校验等

  • 访问cache拿一些数据

  • 拿到cache里的数据后,再进行一些本地计算,这些计算和业务逻辑相关

  • 通过RPC调用下游service再拿一些数据,或者让下游service去处理一些相关的任务

  • RPC调用结束后,再进行一些本地计算,怎么计算和业务逻辑相关

  • 访问DB进行一些数据操作

  • 操作完数据库之后做一些收尾工作,同样这些收尾工作也是本地计算,和业务逻辑相关

分析整个处理的时间轴,会发现:

    线程进行本地业务逻辑计算时需要占用CPU

    访问cache、service、DB过程中线程处于一个等待结果的状态,不需要占用CPU

通过量化分析,例如打日志进行统计,可以统计出整个Worker线程执行过程中这两部分时间的比例,例如:

  • 执行计算,占用CPU的时间(粉色时间轴)是100ms

  • 等待时间,不占用CPU的时间(橙色时间轴)也是100ms

得到的结果是,这个线程计算和等待的时间是1:1,即有50%的时间在计算(占用CPU),50%的时间在等待(不占用CPU):

  • 假设此时是单核,则设置为2个工作线程就可以把CPU充分利用起来,让CPU跑到100%

  • 假设此时是N核,则设置为2N个工作现场就可以把CPU充分利用起来,让CPU跑到N*100%

结论

N核服务器,通过执行业务的单线程分析出本地计算时间为x,等待时间为y,则工作线程数(线程池线程数)设置为 N*(x+y)/x,能让CPU的利用率最大化。

经验

一般来说,非CPU密集型的业务(加解密、压缩解压缩、搜索排序等业务是CPU密集型的业务),瓶颈都在后端数据库访问或者RPC调用,本地CPU计算的时间很少,所以设置几十或者几百个工作线程是能够提升吞吐量的。

六、总结

  • 线程数不是越多越好

  • sleep()不占用CPU

  • 单核设置多线程不但能使得代码清晰,还能提高吞吐量

  • 站点和服务最常用的线程模型是“IO线程与工作现场通过任务队列解耦”,此时设置多工作线程可以提升吞吐量

  • N核服务器,通过日志分析出任务执行过程中,本地计算时间为x等待时间为y,则工作线程数(线程池线程数)设置为 N*(x+y)/x,能让CPU的利用率最大化

https://mp.weixin.qq.com/s/EPWwJShDNmnQQE24tAOanQ

猜你喜欢

转载自my.oschina.net/u/3705388/blog/1793186