Skip to content

Latest commit

 

History

History
68 lines (35 loc) · 3.4 KB

线程数到底怎么设置.md

File metadata and controls

68 lines (35 loc) · 3.4 KB

线程数到底怎么设置

在聊具体场景的时候,需要区分两种场景:

  • CPU 密集型程序
  • I/O 密集型程序

一、CPU 密集型程序

​ 一个完整请求,I/O操作可以在很短时间内完成, CPU还有很多运算要处理,也就是说 CPU 计算的比例占很大一部分,假如我们要计算 1+2+....10000亿 的总和,很明显,这就是一个 CPU 密集型程序。

如果是单核,在使用 4 个线程(必不可少上下文切换带来的开销)的时候(每个线程计算2500亿),CPU 利用理想场景图示:

img

此时如果在 4 核 CPU 下:

img

​ 所以如果是多核CPU 处理 CPU 密集型程序,我们完全可以最大化的利用 CPU 核心数,应用并发编程来提高效率。

二、I/O 密集型程序

​ 与 CPU 密集型程序相对,一个完整请求,CPU运算操作完成之后还有很多 I/O 操作要做,也就是说 I/O 操作占比很大部分,在进行 I/O 操作时,CPU是空闲状态,所以我们要最大化的利用 CPU,不能让其是空闲状态。

单核 CPU 的情况下:

img

发现 I/O 操作耗时变为 CPU 耗时的 2 倍。也就是说单核下可以同时跑 3 个线程。

​ 所以线程等待时间所占比例越高,需要越多线程;线程CPU时间所占比例越高,需要越少线程。

三、创建多少个线程合适?

1、CPU 密集型程序创建多少个线程合适?

​ 理论上 线程数量 = CPU 核数(逻辑) 就可以了,但是实际上,数量一般会设置为 CPU 核数(逻辑)+ 1。

​ 计算密(CPU)集型的线程恰好在某时因为发生一个页错误或者因其他原因而暂停,刚好有一个“额外”的线程,可以确保在这种情况下CPU周期不会中断工作。所以对于CPU密集型程序, CPU 核数(逻辑)+ 1 个线程数是比较好的经验值。

2、I/O密集型程序创建多少个线程合适?

单核最佳线程数 = (1/CPU利用率) = 1 + (I/O耗时/CPU耗时)

多核最佳线程数 =CPU核心数 * (1/CPU利用率) = CPU核心数 * (1 + (I/O耗时/CPU耗时))

四、怎么确认具体的 I/O耗时、CPU耗时和查看 CPU 利用率

SkyWalking、CAT、zipkin

五、场景题

1、假设要求一个系统的 TPS 至少为 20,然后假设每个事务由一个线程完成,继续假设平均每个线程处理一个 Transaction 的时间为 4s,如何设计线程个数,使得可以在 1s 内处理完 20 个 Transaction?

​ 每秒一个线程可处理 0.25 个事务,所以理论线程数为:20 / 0.25 = 80。

​ 但是,如果有 80 个线程,那么肯定会带来太多不必要的线程上下文切换开销,所以就需要调优了,找到最佳性能点。

2、计算操作需要5ms,DB操作需要 100ms,对于一台 8个CPU的服务器,怎么设置线程数呢?

线程数 = 8 * (1 + 100/5) = 168 (个)

如果DB的 QPS(Query Per Second)上限是1000,此时这个线程数又该设置为多大呢?

img

接下来就又是细节调优的阶段了。