Linux中怎么理解系统负载

61次阅读
没有评论

共计 2265 个字符,预计需要花费 6 分钟才能阅读完成。

这篇文章主要介绍“Linux 中怎么理解系统负载”,在日常操作中,相信很多人在 Linux 中怎么理解系统负载问题上存在疑惑,丸趣 TV 小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Linux 中怎么理解系统负载”的疑惑有所帮助!接下来,请跟着丸趣 TV 小编一起来学习吧!

一般在类 unix 系统上,都会有系统负载(load average)这个指标,用来形容系统的繁忙程度,值越大则代表系统越繁忙。

查看负载

$ uptime
19:59:57 up 29 days, 7:08, 1 user, load average: 0.57, 0.26, 0.18

我们关注 load average 后的 3 个值,分别代表 1 分钟、5 分钟、15 分钟的系统平均负载,如果 1 分钟值 5 分钟值 15 分钟值,则代表近 15 分钟内系统压力越来越大,反之亦然。

同样,在 top 命令的第一行,也能看到系统负载,它的含义和 uptime 是一样的。

负载是什么

一般来说,系统线程基本都在这 3 个状态上:运行中,可运行,阻塞等待,其中,运行中的线程正在 CPU 上跑,可运行的线程等待 CPU 调度,而阻塞的线程等待锁释放或 io 完成。

在传统 unix 系统上(如 BSD),系统负载由正在运行的线程以及可运行的线程这 2 个部分组成。

它能很好的说明 CPU 的饱和情况,比如 4 核的 CPU,如果负载一直高于 4,那说明 CPU 资源饱和了。

而 Linux 扩大了负载的定义,如下:

Linux 负载由正在运行的线程和可运行的线程,以及 D 状态的线程 (一般是等待 io 完成) 这 3 个部分组成。

因为 Linux 认为,虽然 D 状态的线程并不消耗 CPU 资源,但是它会消耗磁盘、网卡等硬件资源以及锁这样的软件资源,因此它也应该被用来计算系统负载,想来也合理,毕竟系统负载是用来描述整个系统的繁忙程度的,而不仅仅是 CPU 的。

线程状态 D

在 Linux 里面,线程有如下常见状态:

R: 正在运行或可运行状态

S: 睡眠状态,被阻塞等待唤醒

D: 不可中断睡眠状态,一般是等待 io 完成

这里面的 R 与 D 状态的线程会影响系统负载,因此,当系统负载较高时,可以通过如下命令了解是哪些线程导致的:

ps -eLo pid,tid,stat,comm | grep -E   R|D

小实验: 将系统负载升到 100

# 使用 vfork 函数创建一个子进程,子进程如果不调用 exec 系统调用,它的状态会一直是 D。

$ cat uninterruptible.c 
int main() { vfork();
 sleep(600);
 return 0;
#  编译成可执行程序
$ gcc -o uninterruptible uninterruptible.c
#  运行 100 个程序
$ for i in {1..100}; do ./uninterruptible   done

等待 1 分钟,就会发现系统负载升到了快 100,如下:

$ uptime
20:24:42 up 29 days, 7:32, 1 user, load average: 99.94, 74.82, 35.87
#  可以看到很多 D 状态的进程
$ ps -eLo pid,tid,stat,pcpu,wchan:32,comm | grep   D 
3774195 3774195 D 0.0 do_fork uninterruptible
3774196 3774196 D 0.0 do_fork uninterruptible
3774197 3774197 D 0.0 do_fork uninterruptible
3774198 3774198 D 0.0 do_fork uninterruptible

如上,通过 ps 命令可以看到线程状态,还有一个 wchan 字段,它显示的是线程当前被阻塞在什么内核函数上,这能看出一些蛛丝马迹。

另外,通过 /proc/sysrq-trigger 可以看到 D 线程阻塞时的代码路径,如下:

#  写入一个 w 即可,需要 root 权限执行
$ echo w   /proc/sysrq-trigger
#  然后内核会把 D 状态线程调用栈输出到内核日志,这可以通过 dmesg 查看
$ dmesg

这里就能很清楚的看到,是由于 vfork 系统调用引起的负载上升。

之前介绍过 bcc 工具集里的 offcputime 工具,它可以用来绘制 offcpu 火焰图,同样的,诊断高负载问题时,也可以用这个工具,传一个参数,让其只关注 D 状态线程的 offcpu 行为即可,如下:

# ubuntu 安装 bcc 工具集
$ sudo apt install bpfcc-tools
#  使用 root 身份进入 bash
$ sudo bash
# --state 2 用于指定抓取 TASK_UNINTERRUPTIBLE 即 D 状态线程的 offcpu 栈
$ offcputime-bpfcc -K --state 2 -f 60   d_state_offcpu_stack.out
#  绘制为 offcpu 火焰图
$ awk  { print $1, $2 / 1000 }  d_state_offcpu_stack.out | ./FlameGraph/flamegraph.pl --color=io --countname=ms   d_state_offcpu.svg

到此,关于“Linux 中怎么理解系统负载”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注丸趣 TV 网站,丸趣 TV 小编会继续努力为大家带来更多实用的文章!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-08-04发表,共计2265字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)