![Linux:](https://linux22.com/image/173636/Linux%EF%BC%9A.png)
一个简单的例子。我正在运行一个使用 TCP 套接字服务 http 请求的进程。它可能 A) 计算某些内容,这意味着 CPU 将成为瓶颈 B) 发送可能导致网络成为瓶颈的大文件或 C) 具有半随机访问的复杂数据库查询导致磁盘瓶颈
我是否应该尝试将每个页面/API 调用分类为上述类型中的一种或多种,并尝试平衡每个页面/API 调用的数量?或者操作系统会为我做这件事吗?我如何决定需要多少个线程?
我将使用 2 个数字表示硬件线程 12 和 48(英特尔至强有那么多)。我正在考虑将 2/3 的线程用于繁重的 CPU (8/32),1 个线程用于繁重的磁盘(或每个磁盘 1 个繁重的线程),剩余的 3/15 用于其他任何事情,这意味着不尝试平衡网络。
我应该在仅支持 12/48 线程的硬件上拥有超过 12/48 线程吗?我是否想要更少,这样我就不会导致CPU进入较慢的节流模式(我忘记了它叫什么,但我听说如果太多的芯片同时处于活动状态,就会发生这种情况)。如果我必须加载和资源平衡我的线程,我该怎么做?
答案1
Linux:
Linux 内核在这方面有一个很好的实现,并且有许多功能/设置旨在管理正在运行的进程的资源(通过 CPU 调控器、sysctl 或 cgroup),在这种情况下,调整这些设置以及交换调整(如果需要)是建议,基本上您将根据您的设备调整默认工作模式。
应用更改后的基准测试、压力测试和情况分析是必须的,尤其是在生产服务器上。当将内核设置调整为所需的使用情况时,性能增益可能非常重要,另一方面,这需要测试并充分了解不同的设置,这对于管理员来说非常耗时。
Linux确实使用州长为了在正在运行的应用程序之间平衡 CPU 资源的负载,可以使用许多调节器;根据您的发行版内核,某些调控器可能不可用(可以重建内核以添加缺失或非上游调控器)。你可以检查现任州长是什么,更改更重要的是在这种情况下,调整其设置。
附加文件:阅读,指导,类似的问题,频率缩放,州长的选择,绩效调控者和CPU频率。
系统控制:
系统命令是一个用于在运行时检查和更改内核参数的工具,可以通过配置文件进行永久调整/etc/sysctl.conf
,这是这个答案的重要部分,因为可以使用 Sysctl 更改许多内核设置,可以显示可用设置的完整列表该命令sysctl -a
,详细信息可参见这和本文。
组别:
内核提供了以下功能:控制组,在本指南中通过其较短的名称 cgroups 进行调用。 Cgroup 允许您在系统上运行的用户定义的任务(进程)组之间分配资源,例如 CPU 时间、系统内存、网络带宽或这些资源的组合。您可以监控您配置的 cgroup、拒绝 cgroup 对某些资源的访问,甚至可以在正在运行的系统上动态重新配置您的 cgroup。 cgconfig(控制组配置)服务可以配置为在启动时启动并重新建立预定义的 cgroup,从而使它们在重新启动后保持不变。
内存:
如果系统的 RAM 数量有限,这会很有用,否则您可以禁用交换以主要使用 RAM。互换系统可以调整每个进程或与交换设置。如果需要,可以限制每个进程的资源(内存)极限值(也用于限制其他资源)。
磁盘:
磁盘 I/O 设置(输入/输出调度程序)可能会改变以及簇尺寸。
备择方案:
答案2
对此最好的答案是“忍住看看”……执行一些压力测试,看看什么能带来最好的结果。这是因为线程行为中非常微小的细微差别都可能导致性能差异。
以下内容主要基于我自己的经验...
从哪儿开始?
Linux 防止线程饥饿的能力非常好。这并不一定意味着每个线程都会获得均匀的份额,但所有线程至少都会获得一些份额。如果您有两个线程争夺 CPU 时间...假设一个线程尝试使用 100% CPU,另一个线程尝试仅使用 10%...那么如果在 91% 和 9% 或某个位置达到平衡,请不要感到惊讶围绕那个。
整体性能可能会降低特定资源所在的位置重重地超额认购。对于旋转硬盘上的磁盘 IO 来说尤其如此。磁头必须在磁盘上的位置和位置之间物理移动(寻找)连续的在不同文件之间振荡可能会导致速度显着减慢。但是,如果一个线程严重 IO 绑定,而另一个线程想要执行此操作,则这种影响通常相当小一点IO。
这两件事加在一起意味着超额认购 20% 通常比认购不足 20% 更好。换句话说,不要为不尝试使用太多 CPU 的线程保留 CPU 时间。
例如:如果您有 CPU 绑定线程和磁盘 IO 绑定线程,并且您有 8 个核心和 1 个硬盘,那么从...开始8 个 CPU 密集型线程和 1 个硬盘 IO 密集型线程。 7 和 1 可能会让核心在大部分时间处于空闲状态。 8 和 1 几乎肯定不会耗尽 HD 线程,这意味着您可以充分利用 HD 和 CPU。
短寿命线程的危险
只是要小心 Linux 可能会与很多短寿命线程。这是更明显的故意试图破坏系统。但不断产生线程/进程可能会导致 Linux 表现不佳。
在您的问题中,您描述了专用工作线程,这听起来像是长期存在的线程。这听起来是正确的方法。
伦敦巴士效应
你等了半个小时等一辆公共汽车,然后马上有 5 辆公共汽车来。 发生这种情况是因为上前排公交车的乘客减慢了公交车的速度。后来的公交车上缺少乘客,从而加速了公交车的速度,从而造成了拥挤效应。
线程中也可能存在同样的问题,尤其是线程争夺资源时。如果您的线程可预测地在任务之间交替,例如从一个磁盘读取然后写入另一个磁盘,那么它们可能会倾向于聚集在一起,而不是像您预期的那样随机分散。因此,一种资源可能会减慢另一种资源的使用速度。因此,有时进一步细分线程的任务会更好。
cgroups
我将避免讨论太多细节。但我应该提到 Linux 有一个名为“cgroups”的功能,它允许您对进程进行分组并限制它们的集体资源。这对于进一步的性能调整非常有用。
对它们有一个简短的讨论这里。但我建议你花一些时间在谷歌上看看他们的全部能力,因为从长远来看他们可能会帮助你。
答案3
你可能会以错误的方式处理这件事。你在做简单的同步IO吗?
两种方法是:
Apache 方式:同步 IO、每个连接一个进程、进程池以避免创建和销毁任务。这很容易编码,允许强大的功能,每秒有很多连接,但同时连接的数量很少。
Nginx方式:异步IO,每核一个进程。这使用pole
系统调用来等待连接、数据包和磁盘 IO。如果使某些功能更难编码(如果需要,必须显式存储状态),但它可以有更多的并发连接。
这两种方法都允许操作系统平衡线程,并充分利用内核、磁盘和网络。如果您选择每个核心一个线程和同步 IO,那么大多数时候您的大部分核心都会处于空闲状态。
查找select
,poll
和epoll
系统调用: