Div*_*hah 5 cpu multithreading kubernetes
我对 Kubernetes 中的毫核概念感到困惑。根据我的编程知识,每个内核只能运行 1 个线程,那么为什么要限制毫核呢?例如,如果我给一个容器 600m 的 cpu 限制,我可以将 400m 用于另一个 pod 或容器,这可能吗?我试过安装 minikube 并运行它。容器或 Pod 会运行不同的线程吗?请如果有人可以解释。
Mar*_*oom 24
最好把millicores看作是表示分数的一种方式,x millicores对应分数x/1000(例如250millicores = 250/1000 = 1/4)。
值 1 表示完全使用 1 个内核(或硬件线程,如果启用了超线程或任何其他 SMT)。
所以 100mcpu 意味着进程使用了单个 CPU 时间的 1/10。这意味着它使用了 10 秒中的 1 秒,或 100 秒中的 100 毫秒或 100 秒中的 10 微秒。
只需将任何时间单位分成十个部分,该过程仅针对其中一个运行。
当然,如果间隔太短(比如 1us),调度器的开销就变得不可忽略,但这并不重要。
如果该值大于 1,则该进程正在使用多个 CPU。值 2300mcpu 意味着在 10 秒内,进程运行了... 23!
这用于表示该进程正在使用 2 个完整的 CPU 和三分之一的 3/10。
这听起来可能很奇怪,但与说:“我每周锻炼 3.5 次”没有什么不同,意思是“我每两周锻炼 7 天”。
请记住:毫核代表CPU 时间的一小部分,而不是 CPU 数量。所以 2300mcpu 是单个 CPU 时间的 230%。
我讨厌 Kubernetes 和 Docker 等技术的地方在于它们隐藏了太多,让经验丰富的程序员感到困惑。
该millicores单元出现,在它的基础,从Linux调度的工作方式。它不会将时间划分为量程,而是为每个线程分配一个量程的 CPU,而是运行一个线程,直到让它继续运行不公平为止。所以一个线程可以运行一个可变的时间。
当前名为 CFS 的Linux 调度程序使用等待时间的概念。
每个线程都有一个等待时间,一个计数器每纳秒递增(但任何足够精细的时间单位都可以),线程正在等待执行,并且线程正在执行的每纳秒递减。
然后线程按等待时间除以线程总数排序,等待时间最长的线程被选中并运行,直到它的等待时间(现在正在减少)低于另一个线程的等待时间(这将是然后预定)。
因此,如果我们有一个内核(没有超线程或任何其他 SMT)和四个线程,比如说,一秒钟后,调度程序将为每个线程分配那一秒(250 毫秒)的 1/4。
可以说每个线程使用了 250 毫核。这意味着它平均使用 250/1000 = 1/4 的核心时间。“核心时间”可以是任何时间量,当然它远大于调度程序挂钟。所以 250 毫核意味着每 4 分钟有 1 分钟的时间,或者每 8 天有 2 天的时间。
当系统有多个 CPU/内核时,等待时间会被调整以解决这个问题。现在,如果一个线程在 1 秒的过程中被调度到两个 CPU,一整秒,第一个 CPU 的使用率为 1/1,第二个 CPU 的使用率为 1/1。一共 1/1 + 1/1 = 2 或 2000mcpu。
这种计算 CPU 时间的方式,虽然一开始很奇怪,但优点是它是绝对的。100mcpu 是指 CPU 的 1/10,不管有多少个 CPU,这是设计使然。
如果我们以相对的方式计算时间(即,值 1 表示所有 CPU),那么像 0.5 这样的值表示 48 个 CPU 的系统中有 24 个 CPU,而 8 个 CPU 的系统中有 4 个。
很难比较时间。
Linux 调度程序实际上并不知道millicores,因为我们已经看到它使用等待时间并且不需要任何其他测量单位。
这millicores单元仅仅是一个单位,我们弥补,到目前为止,我们的便利。
然而,事实证明,由于容器的限制方式,这个单元会自然出现。
顾名思义,Linux 调度程序是公平的:所有线程都是平等的。但是您并不总是希望这样,容器中的进程不应该占用机器上的所有内核。
这就是cgroups发挥作用的地方。它是一个内核特性,与命名空间和联合 fs 一起用于实现容器。
它的主要目标是限制进程,包括它们的 CPU 带宽。
这是通过两个参数完成的,一个period和一个quota。
调度程序允许受限线程在每个周期运行配额微秒 (us) 。
在这里,同样,大于周期的配额意味着使用多个 CPU。引用内核文档:
将组限制为 1 个 CPU 的运行时。如果周期为 250 毫秒且配额也是 250 毫秒,则该组每 250 毫秒将获得 1 个 CPU 的运行时间。
在多 CPU 机器上将一组运行时间限制为 2 个 CPU。有了 500 毫秒的周期和 1000 毫秒的配额,该组每 500 毫秒可以获得 2 个 CPU 的运行时间。
我们看到,给定x毫核,我们如何计算配额和周期。
我们可以将周期固定为 100 毫秒,并将配额固定为 (100 * x) / 1000。
这就是Docker 的做法。
当然,我们有无限的选择对,我们将周期设置为 100 毫秒,但实际上我们可以使用任何值(实际上,没有无限值但仍然存在)。
较大的周期值意味着线程可以运行更长的时间,但也会暂停更长的时间。
这就是 Docker 向程序员隐藏内容的地方,使用周期的任意值来计算配额(考虑到millicores,作者称之为更“用户友好”)。
Kubernetes 是围绕 Docker 设计的(是的,它可以使用其他容器管理器,但它们必须公开一个类似于 Docker 的接口),并且 Kubernetes 的毫核单位与 Docker 在其--cpus参数中使用的单位相匹配。
因此,长话短说,毫核是单个 CPU的时间分数(而不是 CPU 数量的分数)。
Cgroups以及 Docker 以及 Kubernetes 不会通过将内核分配给进程(就像 VM 那样)来限制 CPU 使用率,而是通过限制进程可以在每个 CPU 上运行的时间量(一段时间内的配额)来限制 CPU 使用率(每个 CPU 最多占用 1000mcpus 的允许时间)。
| 归档时间: |
|
| 查看次数: |
3233 次 |
| 最近记录: |