如何根据可用内核数选择最大负载阈值?

ter*_*don 5 linux performance load-average

我有一个管道,可以在 Linux 机器上运行一些计算密集型任务。启动这些的脚本会检查当前的平均负载——如果它高于某个阈值——等待直到负载低于它。这是在 Ubuntu 虚拟机上(运行在 Ubuntu 主机上,如果相关的话),它可以分配不同数量的内核。我们的开发和生产机器都是运行在同一台物理服务器上的虚拟机,我们根据需要手动为每个机器分配内核。

我注意到,即使虚拟机只有 20 个内核,大约 60 的负载也不会使机器瘫痪。我对Linux 平均负载如何工作的理解是,任何超过 CPU 数量的东西都表明存在问题,但显然事情并没有那么明确。

我正在考虑将阈值设置在$(grep -c processor /proc/cpuinfo) x Nwhere 之类的地方N>=1。是否有任何聪明的方法来确定N应该采取的价值,以便最大限度地提高性能并最大限度地减少滞后?

换句话说,在性能开始下降之前,我怎么知道一台机器可以支持的最大平均负载是多少?我天真地认为这是 CPU 的数量(所以,N=1),但这似乎站不住脚。由于内核的数量可能会有所不同,因此测试可能的组合既复杂又耗时,而且由于这是一台供不同人使用的机器,因此不切实际。

那么,如何根据可用内核的数量确定可接受的最大平均负载阈值?

Mat*_*Ife 10

在 Linux 上,负载是一个经常被误解的值。

在 Linux 上,它是对处于运行或不间断睡眠状态的所有任务的测量。

请注意,这是任务,而不是流程。线程包含在此值中。

负载由内核每五秒计算一次,是一个加权平均值。即分钟负载是 5/60、五分钟 5/300 和十五分钟 5/900 的平均值。

一般来说,负载作为一个纯数字没有参考点的价值很小,我认为这个值经常被误传。

误解 1:负载为比率

换句话说,在性能开始下降之前,我怎么知道一台机器可以支持的最大平均负载是多少?

这是人们对 Linux 负载最常见的谎言。它可用于根据某个固定比率来衡量 CPU 性能。这不是负载给你的。

详细说明 - 人们很容易理解 CPU 利用率。这是随着时间的推移效用。您完成工作,然后将其除以可能的工作。

在这方面可能的工作是一个固定的已知值,通常表示为 100 的百分比 - 这就是您的固定比率。

然而,负载没有约束。没有固定的最大值,这就是为什么您很难理解要衡量的对象。

为了澄清采样的负载确实有一个不固定的最大值,即采样时系统中当前存在的任务总数(这与 CPU 正在完成的工作没有实际关系)。

计算出的负载没有固定的最大值,因为它被抛入加权平均值,并且在测量加权时没有给出任务数量的记录。

因为我喜欢食物,所以你可以打个比方,利用率是你吃盘子的速度,负载是——平均而言——你还剩多少盘子可以吃。

因此,CPU 效用和负载之间的区别很微妙但很重要。CPU 效用是对已完成工作的衡量,而负载是对需要完成工作的衡量。

误解 2:负载是即时测量

第二个谬误是负载是粒度测量。您可以阅读一个数字并了解系统状态。

负载不是细粒度的,而是代表系统的一般长期状况。它不仅每 5 秒采样一次(因此错过了 5 秒窗口内发生的正在运行的任务),而且分别作为 1、5 和 15 分钟的平均值进行测量。

您不能将其用作容量的即时衡量标准,而是对较长时期内系统负担的一般意义。

负载可以是 100,然后在 30 秒后变为 10。它是您必须不断观察才能使用的价值。

Load 能告诉你什么?

它可以让您了解系统的工作趋势。它被给予的超出了它的承受能力还是更少?

  • 如果负载小于您拥有的 CPU 数量,则这(通常)表示您的 CPU 容量大于工作容量。
  • 如果负载大于或等于 CPU 的数量并且呈上升趋势,则表明系统的工作量超出了它的处理能力。
  • 如果负载大于或等于 CPU 的数量并且呈下降趋势,则表明系统完成工作的速度比您给它做的事情要快。

由于不间断的睡眠状态,这确实将负载值作为纯粹的工作调度分数弄糊涂了 - 但会给您一些关于磁盘上有多少需求的指示(它仍然需要在技术上完成的工作)。

负载还提供系统异常的线索。如果您看到 50+ 的负载,则表明出现问题。

另外负载会引起人们无端的关注。

  1. 众所周知,磁盘活动会增加负载。
  2. 如果大量进程绑定到一个正在等待的 CPU,则负载可能会人为增加。
  3. 具有非常低优先级(niceness)的任务通常会等待很长时间,将特定进程的负载增加 1。

总之

我发现 load 是一个非常模糊的值,确切地说,它没有绝对值。您在一个系统上获得的测量结果与另一个系统相比通常毫无意义。

它可能是我在顶部看到的第一件事,纯粹是为了检查明显的异常情况。基本上,我几乎像使用温度计一样使用它 - 仅作为系统的一般条件。

我发现它的采样周期对于我投入系统的大多数工作负载来说太长了(通常以秒的顺序运行,而不是几分钟)。我想这对于执行长时间运行的密集任务的系统是有意义的,但我并没有真正做太多。

我使用它的另一件事是长期容量管理。绘制长时间(几个月)的图表是一件好事,因为您可以使用它来了解与几个月前相比,您处理的工作量增加了多少。


最后,回答你关于在你的场景中做什么的问题。老实说,我提供的最好建议是,不要考虑使用负载作为何时运行的一个因素——使用 nice 来执行你的进程,让其他进程优先于它。这有几个原因。

  1. 当其他进程忙时,您只为该进程分配少量 CPU 时间。
  2. 如果 CPU 上没有任何内容或 CPU 空闲,则您的任务 100% 的时间都花在它上面。
  3. 进程组中的所有进程都继承了相同的niceness。

当 niceness 为 0(默认值)时,每个进程的权重为 1024。权重越低,为进程提供的 CPU 时间就越少。这是这种行为的表格。

Nice  Weight
0     1024
1     820
2     655
3     526
4     423
5     335
6     272
7     215
8     172
9     137
10    110
11    87
12    70
13    56
14    45
15    36
16    29
17    23
18    18
19    15
Run Code Online (Sandbox Code Playgroud)

因此,比较一下,在有 2 个进程等待运行的情况下 - 如果你 renice 一个进程 +10,它将获得优先级 0 进程所拥有的 CPU 时间的大约 1/10。如果你 renice 它 +19,它将获得优先级 0 进程所拥有的 CPU 时间的 1/100。

应该注意的是,至少在管道运行期间,您可能会看到负载为 1 。

我想这将是您问题的更优雅的解决方案。