1
xbh1794970183564 2021-01-05 19:18:57 +08:00
这里的线程主要是一直在运行的线程数吧,hotspot 后台一直进行垃圾收集,线程数太多肯定影响使用,service 里面 500 多应该大部分都是 WAITING 状态,真正在运行的没多少
|
2
xbh1794970183564 2021-01-05 19:20:38 +08:00
@xbh1794970183564 mark,蹲个大佬回答
|
3
shangzhanyu OP @xbh1794970183564 是的,运行中的不多,所以没搞懂有些服务设置 500 有啥用。。。
|
4
shaoyijiong 2021-01-05 19:23:39 +08:00
其实那些写 service 的人根本就没考虑过你说的最佳线程数 😂
|
5
xbh1794970183564 2021-01-05 19:23:50 +08:00
@shangzhanyu 我们服务启动有 200 线程左右,很多都是框架相关的,自己的线程池一般是 IO 任务 CPU*2 线程,计算密集就是 CPU 核心数
|
6
php8 2021-01-05 19:56:02 +08:00 via Android
使用 eventloop 的 nonblocking 应用,eventloop 线程数设置为 CPU 核心数的 2 倍,这是个推荐值,超过这个值不能提高吞吐量,小于这个值降低吞吐上限,性能够用设置为 1 或 2 也行。
blocking IO 密集型应用,比如 springmvc 那套 web,线程是用来等 IO 的,假设每个请求 IO 等待 1 秒,线程数≈qps,500 线程就是 500 qps,某些场景等待时间 5 秒,500 线程就是 100qps 。 现代 linux 和 jvm,维持几千个等待 IO 的线程开销很小,所以很多地方推荐 200 或者 500 。 计算公式是对的,但也要看具体情况,还有其他因素要考虑。 |
7
liuch 2021-01-05 20:22:37 +08:00 2
书上、网上这些所谓的公式,都偏理想化,实际指导意义不大。生产环境,最好是根据 ThreadPoolExecutor 的统计数据,分析做调整,最好支持动态。特别是微服务里面各种复杂的调用相关的
|
8
YouLMAO 2021-01-05 20:26:43 +08:00 via Android
我们一天处理大概 2 万亿 request,c++, 单容器 16c 开 16 工作线程池,开这么多想干嘛,都是 epoll 了,io 不阻塞工作线程的
|
9
pkwenda 2021-01-05 20:58:40 +08:00
主要还是看 io 密集性,如果不密集 & 内存允许的情况,个人项目我开的比较随意 ( jvm 单个线程默认 1M+ 的内存)
|
10
neoblackcap 2021-01-05 21:05:26 +08:00 2
我就提一个吧,你们都是跑在物理机上面吗?要不然还是按 @liuch 的说,根据统计模型来调吧。
书本上的东西很理想化的。虚拟机的 CPU 调度就能将所谓的最优碾烂。 |
12
90d0n 2021-01-06 09:15:41 +08:00
How to Find the Optimal Database Connection Pool Size
A formula which has held up pretty well across a lot of benchmarks for years is that for optimal throughput the number of active connections should be somewhere near ((core_count * 2) + effective_spindle_count). Core count should not include HT threads, even if hyperthreading is enabled. Effective spindle count is zero if the active data set is fully cached, and approaches the actual number of spindles as the cache hit rate falls. Benchmarks of WIP for version 9.2 suggest that this formula will need adjustment on that release. There hasn't been any analysis so far regarding how well the formula works with SSDs. However you choose a starting point for a connection pool size, you should probably try incremental adjustments with your production system to find the actual "sweet spot" for your hardware and workload. Remember that this "sweet spot" is for the number of connections that are actively doing work. Ignore mostly-idle connections used for system monitoring and control when working out an appropriate pool size. You should always make max_connections a bit bigger than the number of connections you enable in your connection pool. That way there are always a few slots available for direct connections for system maintenance and monitoring. https://wiki.postgresql.org/wiki/Number_Of_Database_Connections |
13
90d0n 2021-01-06 09:17:03 +08:00
|
14
shangzhanyu OP @YouLMAO 同感,设置那么多不知道干啥,大部分都在等待状态
|
15
shangzhanyu OP @neoblackcap 对哦,跑在虚拟机上确实和物理机不一样。。。
|
16
shangzhanyu OP @liuch 就是想搞懂为什么设置这么大的线程数还没问题,按理说这么多线程上下文切换行得通么,机器配置 8c 8g
|
17
BBCCBB 2021-01-06 09:51:41 +08:00
根据压测得到.
|
18
wysnylc 2021-01-06 10:07:53 +08:00
尽信书,不如无书
|
19
hangszhang 2021-01-06 10:18:17 +08:00 1
美团有一篇文章说这个的, 大意是公式与生产有偏差, 需要做压测然后支持动态调整参数
|
20
php8 2021-01-06 10:18:46 +08:00 via Android
@shangzhanyu IO 密集型应用,开那么多线程的作用就是等待,一个请求阻塞一个线程,如果阻塞 1 秒钟,开 10 个线程每秒只能处理 10 个请求,开 100 个性能就提高到 100qps 了。就算开几万个这类线程,切换开销都能小到忽略不计。
|
21
shangzhanyu OP @wysnylc 不信书才有此问
|
22
shangzhanyu OP @php8 这个我去再研究下,好像是这么回事
|
24
shangzhanyu OP @YouLMAO epoll -> tomcat 分配 -> 工作线程执行 java 程序,现在就差 jvm 和操作系统线程之间的关系了
|
25
Jooooooooo 2021-01-06 11:04:52 +08:00
你看 io, 如果 io 很多基本都在等 io, 那线程数就大点
如果都是内存本地操作, 线程数和核数差不多就行 |
26
emSaVya 2021-01-06 11:37:01 +08:00
你们可以试试 用 Vizier 这种调参工具 来确定线程数
|
27
laminux29 2021-01-06 12:01:37 +08:00
现代软硬件太复杂了,教科书里那种简单的公式只能用来参考。建议通过实际压测 + 2 分法来寻找这个值。
|
28
YouLMAO 2021-01-06 13:07:26 +08:00
java nio/nio2 老早就是 epoll 异步的了, 不管 tomcat 还是 netty, 很多人在说 io 密集就多开 io 线程, 这是啥年代的网民????
有数据才会触发的呀, io 触发后业务逻辑是在业务线程池完成的, io 线程池很少就能十万并发 |
29
tairan2006 2021-01-06 13:11:36 +08:00
你要自己压测,或者换 golang 无脑开协程…
|
30
php8 2021-01-06 13:20:58 +08:00 via Android
@YouLMAO 同步阻塞 IO 依然是最主流的 Java 并发模型,tomcat 和 springboot 的默认 worker 线程数是 200 。异步回调写写 framework 和 infra 还行,拿来写业务逻辑有时会比较麻烦,大厂不论 C++还是 JVM 都搞了协程。
|
31
fakeshadow 2021-01-06 13:25:07 +08:00
常见的异步并不能处理所有 IO(如果你用 io_uring 或者 IOCP 之类的当我没说),所以阻塞线程池的 IO 作用仍然是很大的。具体设置多少可以根据你的实际情况,一般上限高的都是 spin on load 。
|
32
assiadamo 2021-01-06 13:32:22 +08:00
线程池设置线程数可以在运行时动态调的,根本不慌
|
33
weizhen199 2021-01-06 13:33:58 +08:00
很多大佬提过了,自己压测。
这个影响的因素包括了 cpu 架构,别试图整通项式了。 但是一个大致的范围还是能参考的. |
34
elintwenty 2021-01-06 13:36:50 +08:00
美团技术团队的博客: https://tech.meituan.com/2020/04/02/java-pooling-pratice-in-meituan.html
这个问题文章给的结论就是 —— “也曾尝试着去追求线程池参数设置的合理性,但面对业界方案具体落地的复杂性、可维护性以及真实运行环境的不确定性,我们在前两个方向上可谓“举步维艰”。最终,我们回到线程池参数动态化方向上探索,得出一个且可以解决业务问题的方案,” |
35
YouLMAO 2021-01-06 13:37:29 +08:00
我只看过 morgan stanley 和 facebook 都是异步的, 我是感觉大陆所谓架构师在 500nm 芯片年代追 5nm
|
36
Goldilocks 2021-01-06 13:47:02 +08:00
@YouLMAO 那不是异步。真正的异步 driven 的 io 只有 Windows 才有,linux 上是半残废没人用。
|
37
YouLMAO 2021-01-06 13:53:18 +08:00
@Goldilocks 举个例子, 我随手一搜, tomcat 8 默认是 nio 或 nio2, linux 下是不是异步? 或者等价问题 8 个 io 线程在 tomcat 8 够不够用, 还是说本帖架构师:最好核数*2 甚至 pool size=上百的线程池
|
38
gdcbhtd 2021-01-06 14:30:03 +08:00
IO 密集型任务:2*CPU 数,因为 IO 密集型任务,线程不是一直在运行,所以可以配置多一点;
CPU 密集型任务:因为一直在使用 CPU,所以要保证线程数不能太多,可以 CPU 数+1 ; |
39
shangzhanyu OP 感觉又要默默的去复习一下操作系统了。。。
|
40
xcstream 2021-01-06 15:19:58 +08:00
只要大于 cpu 核心数 小于千 区别应该不是很大
|
41
shangzhanyu OP @xcstream 怎么讲?
|
42
xcstream 2021-01-06 15:25:06 +08:00
开个压 cpu 的跑分软件, 线程数大于 cpu 核就可以跑满了
|
43
ZiLong 2021-01-06 16:33:43 +08:00
@Goldilocks 最近弄了个 io_uring,netty 作者也在跟进,在一个 incubator 分支,听他讲,测试效果蛮好的
|
45
php8 2021-01-06 17:12:27 +08:00 via Android
@YouLMAO tomcat 8 的 connector 是 nio,但是 parse 完 request 后还得丢给 worker thread pool 去做业务逻辑,这个 pool 默认 200 个线程,干的事多半会阻塞线程
|
46
RudyS 2021-01-06 17:28:53 +08:00
1:1 是基本思路吧,然后再是业务类型,要是 CPU 密集,多开也没意义呀。
|
47
gaifanking 2021-01-06 18:06:57 +08:00
公式不对吧 不是应该 N=Cpu 个数*Cpu 目标占有率*(1+W/C)吗
W:Wait time C:Compute time 然后提速极限=1/P P 为并发时必须串行的部分百分比。 基于公式推荐的个数: IO 密集型 2*CPU 计算型 CPU+1 这个推荐不好使,我一个 Demo IO 密集型任务 我测试 12 核单机起 1 万多个最快 |
48
gitdoit 2021-01-07 08:50:54 +08:00
@shaoyijiong 抓到了,上班划水,等下来我办公室
|
49
shangzhanyu OP @anjxue demo 和实际不能比吧,毕竟有执行时间、gc 等等
|
50
shangzhanyu OP @RudyS hotspot 是 1:1 内核线程,linux 系统理论上限是好几万,但是实际弄这么多也不起作用好多都是休眠状态
|