07 | Load Average:加了CPU Cgroup限制,为什么我的容器还是很慢?
该思维导图由 AI 生成,仅供参考
问题再现
- 深入了解
- 翻译
- 解释
- 总结
本文深入探讨了在使用CPU Cgroup限制容器资源后,容器中的进程仍可能运行缓慢的问题。作者首先介绍了Load Average的概念,指出它是Linux进程调度器中可运行队列的平均进程数目,与CPU Usage有所不同。通过实例验证了Load Average的影响,作者指出,即使容器内的进程CPU使用率较低,但Load Average值却很高,可能导致系统变得缓慢。文章还探讨了Load Average的计算方式及其与CPU Usage的差异,以及Load Average值升高导致应用性能下降的原因。此外,文章还介绍了Linux系统中Load Average的计算原理,包括可运行队列进程平均数和休眠队列中不可打断的进程平均数。通过对Load Average的解释和验证,读者能更好地理解CPU Cgroup限制对容器性能的影响。整体而言,本文深入浅出地解释了技术概念,对读者快速了解CPU Cgroup限制对容器性能影响具有指导意义。
《容器实战高手课》,新⼈⾸单¥59
全部留言(20)
- 最新
- 精选
- garnett请问老师,引入为 TASK_UNINTERRUPTIBLE 状态的进程的案例,top 输出中为什么wa使用率这一项没有增长?
作者回复: TASK_UNINTERRUPTIBLE 状态的进程不一定是做I/O, 比如等待信号量的进程也会进入到这个状态。
2020-11-30217 - 莫名推荐 stress 压测工具:stress -c 1 -t 600 平均负载计算公式(nr_active 表示单位时间内平均活跃进程个数,每个 CPU 对应一个 运行队列 rq,rq->nr_running、rq->nr_uninterruptible 分别表示该运行队列上可运行进程、不可中断进程的个数。累积的 nr_active 再进行指数衰减平均得到最终的平均负载) /* * The global load average is an exponentially decaying average of nr_running + * nr_uninterruptible. */ nr_active = 0; for_each_possible_cpu(cpu) nr_active += cpu_of(cpu)->nr_running + cpu_of(cpu)->nr_uninterruptible;
作者回复: @莫名, 是的,stress是很好的负载模拟工具! kernel/sched/loadavg.c 里有完整的load average代码
2020-11-30410 - 争光 Alan感谢分享 我想问下 1.如果出现就D进程,我为什么好的故障方法排查在等待什么吗? 2.一直有个疑问,是不是linux的进程数不能太多?太多会有很多的调度时间造成很卡? 3.容器目前每个节点官方推荐是110个pod,openshift是250个,能问下你们这边的最佳实践不引起性能下降的前提下节点最大pod是多少个吗?
作者回复: @争光 Alan > 1 可以 `cat /proc/<pid>/stack`, 看到进程停在内核中的哪个函数上,结合内核的代码,可以“猜一下”大概是在哪个信号量上。 > 2 进程太多会有问题的。 > 3 我们用的缺省110个pod, 不过对pod/container要做一下max pid的限制, 同时需要监控cpu/memory/disk io/ network/D process number/max pid/max fd 等等
2020-12-0248 - 游离的鱼首先很感谢老师,然后我还是有一些些不太明白,第一个: 处于task_interruptible的进程,虽然它在等信号量和等待io上,但是我理解这个时候其实cpu是空闲的,为什么不把cpu资源让出来,等io完成或者有信号量时再把它放入可运行的队列中去等待调用呢,类似于回调函数那样的思想。第二个: 如果是我的机器长期平均负载过高,是不是一定是D状态的进程或线程引起的。 第三个: 我有四个cpu的机器,现有五个进程,有四个在cpu中运行,其中三个是处于运行状态,另一个是处于task_interruptable状态,也就是D状态,还有一个在排队,那这个时候的负载是不是就是5?如果除了刚刚的D状态的进程其他的进程都运行完了,负载是不是又变成1了。 第四个: 根据老师的定义和公式,平均负载是...的平均进程数,我感觉平均进程数是一个整数,为什么我们看到的平均负载都是带小数的。希望老师帮忙解答一下,帮我解除疑惑。万分感谢
作者回复: > 第一个 这时候cpu仍然是空闲的,cpu也可以用来调度别的进程,只是需要竞争信号量的几个进程间相互在等待中。 > 第二个 这个就是我在文章中讲的,引起load average增高就是两个原因一个running 队列里的进程,一个是D进程。 > 第三个 如果在较长的一段时间里,都是处于这种状态,那么load average是5。只是处于D状态的进程,其实是不用cpu的,因此其他的四个进程应该都在运行。当其他的四个进程都退出了,只剩D进程,那么等待相当长的一段时间后,load average变成1. > 第四个 因为load average是过去1分钟/5分钟/15分钟的一个平均值
2020-12-0126 - Jackson Wu老师好,一个CPU只能同时处理一个进程,为什么还能把CPU分为0.5C的单位呢,这个cpu的单位是怎么理解的呢
作者回复: CPU是分时处理进程的。有两个进程A,B在一个CPU的机器上运行, 每一秒时间里,A可以运行0.5秒,B可以运行0.5秒,那么A拿到的CPU资源就是0.5 cpu
2020-12-063 - 笃定文中的第二个实验,四个cpu的系统,运行六个进程。理论上六个进程同一时刻不可能都处于R状态吧?一个cpu同一时刻不是只能处理一个进程吗?我的理解top输出应该是四个R状态两个S状态
作者回复: R状态的进程不是单指正在运行的进程,还指在runqueue上可以随时得到调度时间片而可以运行的进程。
2021-03-282 - Harold对于 load average 的值还是有些模糊,不考虑 D 进程的情况下,1台8核的机器有 16个 running 的进程,cpu并没有占满100%的情况下,load average取的值是 16*(1 - cpu idle) 还是 16?换句话说,是不是只要 cpu idle 不是0,取的都是 cpu usage 的值。望解答。
作者回复: > 换句话说,是不是只要 cpu idle 不是0,取的都是 cpu usage 的值. 没有D进程的情况下,是的。
2021-01-122 - po有事,好几天没来留言了,我有个确认点: 1. 如果一台2个cpu的机器,跑了8个进程,每个进程使用一个cpu的10%,那么load average应该是0.8吧? 2. 平常说的物理机CPU,比如2核4线程,这个在Linux里面看是几个cpu呢?
作者回复: @po, >1, 是的 >2, 对于处理器里的hyper-threading, 从Linux角度看到的也是1个cpu。2核4线程(hyper-threading), 看到的是4个cpu. 你可以 sys/, proc/下看到cpu信息。 /sys/devices/system/cpu/online /proc/cpuinfo
2020-12-0992 - Geek4329感谢老师,受益匪浅! 有一点不是很懂,想请教下: “这里我们做一个kernel module,通过一个 /proc 文件系统给用户程序提供一个读取的接口,只要用户进程读取了这个接口就会进入 UNINTERRUPTIBLE。” 老师上面给的kernel module中,我的理解是只调用sleep,然后用户调用这个接口就进入D state,算是模拟DISK IO状态时获取不到资源时的状态吗?老师能不能给个参考,用户进程读是如何取了这个接口呢?
作者回复: @Geek4329 内核模块里调用的是 msleep(), 这个函数会把进程的状态设置为TASK_UNINTERRUPTIBLE。 就用它来模拟一下。 void msleep(unsigned int msecs) { unsigned long timeout = msecs_to_jiffies(msecs) + 1; while (timeout) timeout = schedule_timeout_uninterruptible(timeout); } signed long __sched schedule_timeout_uninterruptible(signed long timeout) { __set_current_state(TASK_UNINTERRUPTIBLE); return schedule_timeout(timeout); } 用户程序读取/proc的接口的例子程序: https://github.com/chengyli/training/blob/main/cpu/load_average/uninterruptable/app-test.c
2020-11-3022 - 钱米请问老师,我的宿主机的memory cgroup很多,处于上升趋势,未下降 ~# cat /proc/cgroups #subsys_name hierarchy num_cgroups enabled cpuset 3 30 1 cpu 2 101 1 cpuacct 2 101 1 blkio 6 99 1 memory 7 1013 1 devices 4 99 1 freezer 9 30 1 net_cls 10 30 1 perf_event 8 30 1 net_prio 10 30 1 pids 5 100 1 这个影响了api对容器的创建和启动,改如何处理呢?
作者回复: 如果被删的memory cgroup还有cache memory, 对应的memroy cgroup 控制块不会随 /sys/fs/cgroup/memory/.../<memory_cgroup> 的删除而马上删掉。 你可以用 “echo 3 > /proc/sys/vm/drop_caches” 释放cache之后, memory cgroup num_cgroups的数值应该会下降一些。 > 这个影响了api对容器的创建和启动 这个有什么样的影响?
2021-01-221