https://www.cnblogs.com/codelogs/p/16060498.html

简介#

这是Linux命令拾遗系列的第七篇,本篇主要介绍Linux中负载的概念与问题诊断方法。

本系列文章索引
Linux命令拾遗-入门篇
Linux命令拾遗-文本处理篇
Linux命令拾遗-软件资源观测
Linux命令拾遗-硬件资源观测
Linux命令拾遗-剖析工具
Linux命令拾遗-动态追踪工具

一般在类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


若无法使用/proc/sysrq-trigger与bcc工具,也可以借助/proc/$pid/task/$tid/stack伪文件查看,如下:

$ cat /proc/2666/task/2666/stack
[<0>] _do_fork+0x237/0x390
[<0>] do_syscall_64+0x55/0x110
[<0>] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[<0>] 0xffffffffffffffff

可以发现,/proc/$pid/task/$tid/stack文件记录着线程的内核栈,因此当系统负载高时,只要查看一下R或D状态线程的内核栈,即可发现问题所在,如下:

$ ps h -eLo pid,tid,s \
| grep -E 'R|D' \
| while read pid tid s;do paste -s /proc/$pid/task/$tid/stack;done \
| sort | uniq -c | sort -nr 100 [<0>] _do_fork+0x237/0x390 [<0>] do_syscall_64+0x55/0x110 [<0>] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [<0>] 0xffffffffffffffff

如上,通过ps、grep找出R或D状态线程,通过paste将线程内核栈折叠成一行,再通过sort、uniq将相同的栈聚合,即可发现是内核的哪些关键代码路径导致系统负载高。

往期内容#

Linux命令拾遗-入门篇
原来awk真是神器啊
Linux文本命令技巧(上)
Linux文本命令技巧(下)
字符编码解惑

[转帖] Linux命令拾遗-理解系统负载的更多相关文章

  1. Linux性能优化-理解平均负载

    1 平均负载含义 当系统变慢的时候,我们一般使用 top 或 uptime 命令来查看系统平均负载情况. 正确定义:单位时间内,系统中处于可运行状态和不可中断状态的平均进程数.错误定义:单位时间内的c ...

  2. Linux命令行–理解Linux文件权限(转)

    6.1.1 /etc/passwd文件 /etc/passwd:包含系统用户账户列表以及每个用户的基本配置信息 每个条目有七个字段,每个字段用冒号隔开 登录用户名 用户密码 用户账户的UID 用户账户 ...

  3. 【Linux命令】常用系统工作命令11个(echo、date、reboot、poweroff、wget、ps、top、pidof、kill、killall、pkill)

    目录 echo命令 date命令 reboot命令 poweroff命令 wget命令 ps命令 top命令 pidof命令 kill命令 killall命令 pkill命令 一.echo命令 ech ...

  4. [转帖]Linux命令pmap

    Linux命令pmap https://www.cnblogs.com/lnlvinso/p/5272771.html jmap可以查看Java程序的堆内存使用情况,pmap可以查看Linux上运行的 ...

  5. [转帖]Linux命令中特殊符号

    Linux命令中特殊符号 转自:http://blog.chinaunix.net/uid-16946891-id-5088144.html   在shell中常用的特殊符号罗列如下:# ; ;; . ...

  6. [转帖]linux命令dd

    linux命令dd   dd 是diskdump 的含义 之前学习过 总是记不住 用的还是少. http://embeddedlinux.org.cn/emb-linux/entry-level/20 ...

  7. Linux基础命令---tload显示系统负载

    tload tload指令以字符的方式显示当前系统的平均负载情况. 此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.Fedora.SUSE.openSUSE.   1.语法   ...

  8. 每天一条Linux命令(OS X系统上操作)

     Linux菜鸟必学的60个命令 安装和登录命令:login.shutdown.halt.reboot.install.mount.umount.chsh.exit.last: 文件处理命令:file ...

  9. linux日常管理-查看系统负载

    查看系统的负载常用命令w 16:32::15是系统时间 up 16 min 是开机使用时间 1 user 是登录的用户数 重要 load average:0.00 0.00 0.00 负载分别表示1分 ...

  10. linux 命令拾遗

    man ascii 这个命令会打印出八进制.十六进制和十进制的ASCII码表. xxd xxd可以生成所给与文件的十六进制拷贝,也可以将编辑好的十六进制拷贝还原成二进制格式.它也可以将十六进制拷贝输出 ...

随机推荐

  1. 昇腾CANN 7.0 黑科技:大模型推理部署技术解密

    本文分享自华为云社区<昇腾CANN 7.0 黑科技:大模型推理部署技术解密>,作者:昇腾CANN. 近期,随着生成式AI.大模型进入公众视野,越来越多的人意识到抓住AI的爆发就是抓住未来智 ...

  2. 带你认识数仓的监控系统TopSQL

    本文分享自华为云社区<GaussDB(DWS)TopSQL总结>,作者:nullptr_ . TopSQL 背景 TopSQL为DWS的监控系统,记录DWS中各个作业.算子级别的资源使用数 ...

  3. 解惑“高深”的Kafka时间轮原理,原来也就这么回事!

    [摘要] Kafka时间轮是Kafka实现高效的延时任务的基础,它模拟了现实生活中的钟表对时间的表示方式,同时,时间轮的方式并不仅限于Kafka,它是一种通用的时间表示方式,本文主要介绍Kafka中的 ...

  4. Open Serverless Benchmark Initiative: 华为云联合上海交大发布ServerlessBench 2.0

    Key Takeaways 华为云联合上海交大,首次提出 Open Serverless Benchmark Initiative (OSBI) ,推动Serverless基准测评规范化.标准化: O ...

  5. 移动应用中的第三方SDK隐私合规检测,早知道

    摘要: 在移动应用隐私合规检测中,第三方SDK隐私声明由于其展现位置展现形式的多样性,自动化提取与解析是比较困难的任务. 本文分享自华为云社区<移动应用中的第三方SDK隐私合规检测>,作者 ...

  6. 云原生时代,领域驱动设计思想(DDD)如何落地?

    摘要:随着数字化世界的持续演进,软件架构设计思想在碰撞中不断优化.云原生时代的到来,加速了行业对于领域驱动设计理念(Domain-Driven Design)的实践落地诉求. 本文分享自华为云社区&l ...

  7. WebKit三件套(3):WebKit之Port篇

    了解其有关Port方面的设计,从而了解究竟如何能移植WebKit到自己的应用中. WebKitPort方面的内容是可以很广的,例如可将不同的图形库.网络库与WebCore集成,提供不同的Port接口供 ...

  8. 如何利用CCXT交易数字货币合约

    更多精彩内容,欢迎关注公众号:数量技术宅,也可添加技术宅个人微信号:sljsz01,与我交流. 对于币圈量化老司机来说,相信或多或少都有接触过ccxt这个接口,ccxt为我们提供了多交易所统一的标准格 ...

  9. 阿里云视频云人脸生成领域最新研究成果入选CVPR2022

    CVPR(IEEE Conference on Computer Vision and Pattern Recognition)作为计算机视觉和模式识别领域的顶级会议,在全球具有极高的权威性.目前在中 ...

  10. Java 开发手册 (阿里巴巴开发手册)

    Java 开发手册 (有需要pdf版本的私信我,可以邮箱发)0版本号 制定团队 更新日期 备注 1.4.0 阿里巴巴集团技术团队 2018.5.20 增加设计规约(详尽版) 一.编程规约 (一) 命名 ...