为了账号安全,请及时绑定邮箱和手机立即绑定

多少线程太多了?

/ 猿问

多少线程太多了?

潇湘沐 2019-11-15 15:10:34

多少线程太多了?

我正在编写一个服务器,当请求传入时,我将每个动作分支到一个线程中。我这样做是因为几乎每个请求都会进行数据库查询。我正在使用线程池库来减少线程的构造/破坏。

但是,我的问题是-对于这样的I/O线程来说,什么是一个好的临界点?我知道这只是一个粗略的估计,但我们说的是数百人吗?成千上万?


编辑:

谢谢大家的回应,似乎我要测试一下才能找到我的线计数上限。但问题是:我怎么知道我撞到了那个天花板?我该测量什么?


查看完整描述

3 回答

?
吃鸡游戏

有些人会说线程太多了-我不是很在行:-)

以下是我的建议:量一下,别猜。一种建议是使其可配置,并最初将其设置为100,然后将您的软件发布到野外,并监视发生的情况。

如果您的线程使用高峰在3,那么100是太多了。如果一天大部分时间都保持在100,那就把它提高到200,看看会发生什么。

你,你们实际上,让您的代码本身监视使用情况,并在下次启动时调整配置,但这可能是过火了。


为澄清和阐述:

我并不提倡滚动您自己的线程池子系统,无论如何都要使用您拥有的线程池子系统。但是,由于您询问的是线程的一个好的断点,所以我假设您的线程池实现能够限制创建的最大线程数(这是一件好事)。

我编写了线程和数据库连接池代码,它们具有以下特性(我认为这些特性对性能至关重要):

  • 活动线程的最小数量。
  • 最大线程数。
  • 关闭有一段时间没有使用的线程。

第一种方法根据线程池客户端设置最低性能基准(线程数量总是可用的)。第二个设置了对活动线程使用资源的限制。第三种方法在安静的时候将您返回到基线,以便最大限度地减少资源的使用。

您需要平衡未使用线程(A)的资源使用情况和没有足够的线程执行工作的资源使用情况(B)。

(A)通常是内存使用(堆栈等等),因为不工作的线程将不会占用大量CPU。(B)当请求到达时,通常会延迟处理请求,因为你需要等待线程可用。

这就是你测量的原因。正如您所述,绝大多数线程将等待数据库的响应,这样它们就不会运行。有两个因素影响您应该允许多少线程。

第一个是可用的DB连接数。这可能是一个很难的限制,除非您可以在DBMS中增加它-在这种情况下,我将假设您的DBMS可以获得无限数量的连接(虽然理想情况下您也应该对此进行度量)。

然后,您应该拥有的线程数量取决于您的历史使用。您应该运行的最小值是您曾经运行过的最小数+A%,其绝对最小值为(例如,并使其可配置,就像A)5。

线程的最大数量应该是历史上最大的+B%。

您还应该监视行为的变化。如果由于某种原因,在相当长的一段时间内,您的使用率会达到可用的100%(因此会影响客户端的性能),那么您应该提高允许的最大值,直到它再次高出B%。


回应“我应该衡量什么?”问题:

具体衡量的是负载下并发使用的线程的最大数量(例如,等待DB调用的返回)。然后加上10%的安全系数(强调一下,因为其他海报似乎把我的例子当作固定的建议)。

此外,这应该在生产环境中进行调优。事先得到一个估计是可以的,但您永远不知道什么生产会以您的方式进行(这就是为什么所有这些事情都应该在运行时进行配置)。这是为了捕捉一种情况,例如客户端电话的意外加倍。



查看完整回答
反对 回复 2019-11-16
?
智慧大石

这个问题讨论得很透彻,我没有机会阅读所有的答复。但是,在查看可以在给定系统中和平共存的同步线程数量上限时,需要考虑以下几点。

  1. 线程堆栈大小:在Linux中,默认的线程堆栈大小是8MB(您可以使用uLim-a查找它)。
  2. 给定操作系统变体支持的最大虚拟内存。LinuxKernel2.4支持2GB的内存地址空间。使用内核2.6,我要大一点(3GB)
  3. [1]显示每个给定支持的最大VM的最大线程数的计算。对于2.4,结果是大约255个线程。对于2.6,这个数字要大一点。
  4. 你有什么样的内核调度程序。将Linux2.4内核调度程序与2.6进行比较,后者给出了一个O(1)调度,它不依赖于系统中存在的任务数,而第一个则更像是O(N)。因此,内核调度的SMP功能在系统中最大数量的可持续线程中也起到了很好的作用。

现在您可以调整堆栈大小以合并更多的线程,但是必须考虑线程管理的开销(创建/销毁和调度)。您可以对给定的进程和给定的线程强制执行CPU亲和力,以将它们绑定到特定的CPU,以避免CPU之间的线程迁移开销,并避免出现冷现金问题。

请注意,您可以根据自己的意愿创建数千个线程,但是当Linux耗尽VM时,它只是随机地开始终止进程(因此是线程)。这是为了防止工具配置文件被最大化。(实用程序函数告诉给定资源的全系统实用程序。在这种情况下,随着CPU周期和内存的不断增加,效用曲线会随着越来越多的任务而变平)。

我确信windows内核调度程序也会做一些这样的事情来处理过度使用资源的问题。

[1] http:/adywicaksono.wordpress.com/2007/07/10/i-不能创建超过255个线程-linux上的什么是解决方案/



查看完整回答
反对 回复 2019-11-16
?
繁星点点滴滴

如果您的线程正在执行任何类型的资源密集型工作(CPU/磁盘),那么您将很少看到超过一两个的好处,而且过多的线程会很快降低性能。

“最好的情况”是,以后的线程在第一个线程完成时会停止运行,或者一些线程在资源上具有低开销的低争用块。最糟糕的情况是,您开始破坏缓存/磁盘/网络,而您的总体吞吐量则下降。

一个好的解决方案是将请求放在一个池中,然后将请求从线程池发送给工作线程(是的,避免连续的线程创建/破坏是一个伟大的第一步)。

然后,可以根据分析结果、正在运行的硬件以及机器上可能发生的其他事情来调整和缩放此池中的活动线程数。




查看完整回答
反对 回复 2019-11-16
  • 3 回答
  • 0 关注
  • 35 浏览
我要回答

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信