CPU低、Load负载高排查
负载:需要运行处理但又必须等待队列前的进程处理完成的进程个数
cpu低而负载高也就是说等待磁盘I/O完成的进程过多,就会导致队列长度过大,这样就体现到负载过大了,但实际是此时cpu被分配去执行别的任务或空闲
可能性①:磁盘读写请求过多就会导致大量I/O等待
可能性②:数据库中存在没有索引的语句或存在死锁等情况
可能性③:外接硬盘故障,常见有挂了NFS,但是NFS server故障
案例① :
发现问题:这个问题是刚好登录这台机 df -Th看看磁盘使用情况的,但发现完全卡住,但关掉终端重登发现依然有问题,查看 top 发现CPU负载飙高到 10,纳闷怎么没有告警,登上华为云监控发现云监控这边CPU负载只有0.6左右,与Linux上TOP命令查看的完全不一样
处理思路:
排查 主要跑的java进程 并没有高CPU/内存占用,且华为云监控这边查看的CPU负载也很低,只有虚拟机这边的TOP命令查看的CPU负载很高
尝试在华为云提工单,排查是否为虚拟机所在宿主机的问题:CPU负载飙高,影响了虚拟机(因为之前在其他项目遇到过类似的问题,因此想先确认是不是相同情况)
提工单是因为 ① 云监控的CPU负载与TOP命令查看的CPU负载相差甚远
② 虚拟机莫名其妙的高CPU负载
客服反馈虚拟机内存缓存较高,free内存过低问题,缓存会影响到CPU负载飙高? echo 1 > /proc/sys/vm/drop_caches清除缓存,但并没有降低CPU负载
到这里其实都是 CPU高、Load高的排查分析:查各个进程的资源占用情况,定位系统中占用CPU较高的进程,并根据对应相关日志做进一步排查分析
但这里是CPU低,Load average高,且缓慢增长
说明: load average 是对 CPU 负载的评估,其值越高,说明其任务队列越长,处于等待执行的任务越多
那这里其实按照对load average的描述,就是处于等待执行的任务一直没执行完,导致load average会一直增长;
但TOP命令查看时虚拟机又没有业务应用在运行,出现这种情况,可能是由于僵死进程导致的:Uninterruptible sleep(D)状态
说明: D 状态是指不可中断的睡眠状态。该状态的进程无法被 kill,也无法自行退出。只能通过恢复其依赖的资源或者重启系统来解决
回顾下Linux系统进程状态/代码CODES
D Uninterruptible sleep (usually IO)——不可中断睡眠
R Running or runnable (on run queue)——运行中或正在运行队列
S Interruptible sleep (waiting for an event to complete)——可中断睡眠(等待事件完成)
T Stopped, either by a job control signal or because it is being traced.——被作业控制信号或因为被跟踪而停止
X dead (should never be seen)——结束
Z Defunct ("zombie") process, terminated but not reaped by its parent.——失效进程(“僵尸”),终止但未被父进程获取。
Linux 进程有两种睡眠状态:
① 一种interruptible sleep,处在这种睡眠状态的进程是可以通过给它发信号来唤醒的,比如发 HUP 信号给 nginx 的 master 进程可以让 nginx 重新加载配置文件而不需要重新启动 nginx进程
② 另外一种睡眠状态是 uninterruptible sleep,把信号(kill -9和kill -15)传递到这种睡眠状态的进程不能改变它的状态,也就是除非等待的资源得到满足,否则就是怎么kill,这个进程也不会变成TASK_RUNNING和进入就绪队列的,怎么都杀不死的
说明:uninterruptible sleep(D)不可中断睡眠的意义在于:内核的某些处理流程是不能被打断的,例如:进程调用read系统调用对某个设备文件进行读操作,而read系统调用最终执行到对应设备驱动的代码,并与对应的物理设备进行交互
通常情况下UNINTERRUPTIBLE状态是非常短暂的,处于 uninterruptible sleep 状态的进程通常是在等待 IO,比如磁盘 IO,网络 IO,其他外置 IO,如果进程正在等待的 IO 在较长的时间内都没有响应,很有可能有 IO 出了问题,可能是外置设备本身出了故障,也可能是比如挂载的远程文件系统NFS已经不可访问了,那么ps aux就会看到存在D状态位的进程
因为得不到 IO 的响应,进程才进入了 uninterruptible sleep 状态,所以要想使进程从 uninterruptible sleep (D)状态恢复,就得使进程等待的 IO 恢复,比如因为从远程挂载的 NFS 卷不可访问导致一个需要访问NFS挂载目录的进程进入 D 状态的,那么可以通过恢复该 NFS 卷的正常访问来使进程的 IO 请求得到满足,除此之外,要想干掉处在 D 状态进程就只能重启整个Linux 系统了。如果为了想要杀掉 D 状态的进程,而去杀掉它的父进程(通常是shell,在shell下允许某进程,然后某进程转入D状态),就会出现这样的状态:他们的父进程被杀掉了,但是他们的父进程 PID 都变成了1,也就是 init 进程,D状态的进程会变成僵尸进程
排查发现 nginx 存在几个D进程,检查 nginx 配置文件,检查涉及目录
location /cache {
alias /data/dfsx-datanode/cache;
autoindex off;
}
发现确实有NFS挂载:cd /data/dfsx-datanode/cache 完全卡住,df -Th 查看NFS挂载情况,还是完全卡住 —— 到这里跟前面 df -Th完全卡住对上了,这是同一类型问题
查看系统挂载信息:
① mount
② cat /etc/fstab
→ 192.168.0.124:/data/dfsx-datanode/cache /data/dfsx-datanode/cache nfs defaults 0 0 (发现也有对应挂载信息)
检查NFS服务端(192.168.0.124)的NFS服务情况——发现 NFS 服务挂了,重启
再回来检查 nfs-utils 服务情况,发现也已经挂了,重新启动 nfs-utils
重新启动 Nginx,发现 Nginx 已经没有 D进程了,再次查看负载 Load average 发现已经在慢慢降下来了
案例②:
问题描述:负载飙高,但top查看发现没有明显CPU使用率很高的进程
同样ps aux 或 ps aux | grep D 查看是否 存在 D 状态进程
[root@outer22n2 ~]# ps aux | grep D
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
... ...
root 7524 0.0 0.0 107980 900 ? DN 2021 14:58 /usr/bin/updatedb -f sysfs ramfs bdev proc cgroup cpuset tmpfs devtmpfs debugfs securityfs sockfs dax bpf pipefs anon_inodefs configfs devpts hugetlbfs autofs pstore mqueue rpc_pipefs binfmt_misc nfs nfs4
... ...
查看是否有NFS挂载失败,重复挂载的情况
[root@outer22n2 ~]# dmesg
... ...
[28810932.455094] nfs: server 10.30.13.231 not responding, still trying
[28810948.966929] nfs: server 10.30.13.231 not responding, still trying
[28810959.561444] nfs: server 10.30.13.231 OK
[28810959.561466] nfs: server 10.30.13.231 OK
[47930373.769434] nfs: server 10.30.13.231 not responding, still trying
[47930394.825235] nfs: server 10.30.13.231 not responding, still trying
[47995911.548848] nfs: server 10.30.13.231 not responding, still trying
查看nfs有关挂载
[root@outer22n2 ~]# mount | grep nfs
sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw,relatime)
10.30.13.231:/mnt/hdd on /home/data/robot/voice type nfs (rw,relatime,vers=3,rsize=131072,wsize=131072,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=10.30.13.231,mountvers=3,mountport=833,mountproto=udp,local_lock=none,addr=10.30.13.231)
... ...
发现确实有13.231的NFS挂载,确认机器情况(是否为关停的机器/服务),直接umount卸载——确认情况:服务器已关停回收
[root@outer22n2 ~]# umount -l /home/data/robot/voice
[root@outer22n2 ~]# mount | grep nfs
sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw,relatime)
10.30.12.83:/data/robot1000 on /home/data/robot/mp3 type nfs4 (rw,relatime,vers=4.1,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=10.30.12.22,local_lock=none,addr=10.30.12.83)
卸载后,直接kill掉对应 D 进程即可
kill -9 7524
再用df命令发现正常了,top负载也慢慢降下来了
[root@outer22n2 ~]# df -Th
Filesystem Type Size Used Avail Use% Mounted on
/dev/mapper/centos-root xfs 42G 3.1G 39G 8% /
devtmpfs devtmpfs 3.9G 0 3.9G 0% /dev
tmpfs tmpfs 3.9G 0 3.9G 0% /dev/shm
tmpfs tmpfs 3.9G 393M 3.5G 11% /run
tmpfs tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup
/dev/sda1 xfs 497M 138M 359M 28% /boot
/dev/mapper/vgdata-lvdata xfs 300G 1.5G 299G 1% /data
10.30.12.83:/data/robot1000 nfs4 300G 12G 289G 4% /home/data/robot/mp3
tmpfs tmpfs 783M 0 783M 0% /run/user/0
案例③:
问题描述:机器运行Influxdb,作为监控数据源,接收大部分生产机器的监控数据/指标,CPU使用率仅为 influxdb 服务占用 50%左右,但是 load average 却很高,且一直在缓慢增长
处理思路:
# iostat查看磁盘io情况——发现sdb设备(/data:influxdb数据目录)%util值基本吃满
iostat -xk 2
avg-cpu: %user %nice %system %iowait %steal %idle
3.77 0.00 1.51 65.66 0.00 29.06
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
sdd 0.00 0.00 0.00 0.50 0.00 2.00 8.00 0.01 22.00 0.00 22.00 22.00 1.10
sda 0.00 0.00 75.00 0.00 1534.00 0.00 40.91 0.05 0.73 0.73 0.00 0.10 0.75
sdb 0.00 0.00 301.50 53.50 10382.00 26221.25 206.22 22.56 56.85 25.12 235.63 2.82 100.00
%util: 在统计时间内所有处理IO时间,除以总共统计时间。例如,如果统计间隔1秒,该设备有0.8秒在处理IO,
而0.2秒闲置,那么该设备的%util = 0.8/1 = 80%,
所以该参数暗示了设备的繁忙程度
。一般地,如果该参数是100%表示设备已经接近满负荷运行了
(当然如果是多磁盘,即使%util是100%,因为磁盘的并发能力,所以磁盘使用未必就到了瓶颈)
# 看下io情况(很高的读写)
iotop -Po
Total DISK READ : 1565.36 K/s | Total DISK WRITE : 1432.96 K/s
Actual DISK READ: 1561.46 K/s | Actual DISK WRITE: 14.92 M/s
PID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND
16513 be/4 influxdb 130.08 M/s 28.49 M/s 0.00 % 16.60 % influxd -config /etc/influxdb/influxdb.conf
# 再看下磁盘类型,都是机械硬盘,那就没办法,这种IO需求,但凡有一点办法也不至于一点办法都没有
lsblk -d -o name,rota | grep -v NAME3
sda 1
sdb 1
sdc 1
sdd 1
sr0 1