linux 调整 内核空间占用cpu,[Linux性能优化]3.CPU使用率100%,怎么办?

66b52468c121889b900d4956032f1009.png

8种机械键盘轴体对比

本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?

CPU使用率是单位时间内CPU使用情况的统计,以百分比的方式展示。

CPU时间是Linux通过事先定义的节拍率(内核中表示为 HZ),触发时间中断,并使用全局变量Jiffies记录了开机以来的节拍数。每发生一次时间中断,Jiffies的值就加 1。

节拍率 HZ 是内核的可配选项,可以设置为100、250、1000等。不同的系统可能设置不同数值,你可以通过查询 /boot/config 内核选项来查看它的配置值。比如在我的系统中,节拍率设置成了1000,也就是每秒钟触发1000次时间中断。

# grep 'CONFIG_HZ=' /boot/config-$(uname -r)

CONFIG_HZ=1000

同时,正因为节拍率HZ是内核选项,所以用户空间程序并不能直接访问。为了方便用户空间程序,内核还提供了一个用户空间节拍率 USER_HZ,它总是固定为100,也就是1/100 秒。这样,用户空间程序并不需要关心内核中HZ被设置成了多少,因为它看到的总是固定值USER_HZ。

CPU使用率相关的重要指标user(通常缩写为us),代表用户态CPU时间。注意,它不包括下面的nice时间,但包括了guest时间。

nice(通常缩写为ni),代表低优先级用户态CPU时间,也就是进程的nice值被调整为1-19之间时的CPU时间。这里注意,nice可取值范围是-20到19,数值越大,优先级反而越低。

system(通常缩写为sys),代表内核态CPU时间。

idle(通常缩写为 id),代表空闲时间。注意,它不包括等待I/O的时间(iowait)。

iowait(通常缩写为 wa),代表等待I/O的CPU时间。

irq(通常缩写为 hi),代表处理硬中断的CPU时间。

softirq(通常缩写为 si),代表处理软中断的CPU时间。

steal(通常缩写为 st),代表当系统运行在虚拟机中的时候,被其他虚拟机占用的CPU 时间。

guest(通常缩写为 guest),代表通过虚拟化运行其他操作系统的时间,也就是运行虚拟机的 CPU 时间。

guest_nice(通常缩写为 gnice),代表以低优先级运行虚拟机的时间。

指标异常的一些场景:用户CPU和Nice CPU高,说明用户态进程占用了较多的CPU,所以应该着重排查进程的性能问题。

系统CPU高,说明内核态占用了较多的CPU,所以应该着重排查内核线程或者系统调用的性能问题。

I/O等待CPU高,说明等待I/O的时间比较长,所以应该着重排查系统存储是不是出现了I/O问题。

软中断和硬中断高,说明软中断或硬中断的处理程序占用了较多的CPU,所以应该着重排查内核中的中断服务程序。

cpu使用率

CPU使用率,就是除了空闲时间外的其他时间占总CPU时间的百分比,用公式来表示就是:

空闲时间

CPU使用率 = 1 - --------------

总cpu时间

通过查看/proc/stat,我们根据公式可以计算出系统cpu使用率。但是这里面的数值是开机以来的累积数据,计算出来的cpu使用率是开机到现在的cpu使用率。

我们计算cpu使用率,一般是选择一段时间内的cpu使用率,比如top使用的是3秒内的数据,而ps则用的是进程的生命周期数据。

计算一段时间内的cpu使用率的公式:

空闲时间new - 空闲时间old

CPU使用率 = 1 - ------------------------------

总cpu时间new - 总cpu时间old

进程的cpu使用率是通过/proc/[pid]/stat文件内的数据来计算的。

怎么查看cpu使用率?

使用一些性能工具就能看到。top 显示了系统总体的 CPU 和内存使用情况,以及各个进程的资源使用情况。

ps 则只显示了每个进程的资源使用情况。

pidstat 显示了用户态和内核态的cpu使用率

# 默认每3秒刷新一次

# top

top - 19:33:00 up 6:11, 5 users, load average: 0.00, 0.01, 0.05

Tasks: 100 total, 1 running, 99 sleeping, 0 stopped, 0 zombie

%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st

KiB Mem : 999720 total, 671020 free, 102360 used, 226340 buff/cache

KiB Swap: 10485756 total, 10485756 free, 0 used. 722092 avail Mem

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND

1 root 20 0 43668 4124 2488 S 0.0 0.4 0:01.18 systemd

2 root 20 0 0 0 0 S 0.0 0.0 0:00.01 kthreadd

3 root 20 0 0 0 0 S 0.0 0.0 0:15.86 ksoftirqd/0

5 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H

7 root rt 0 0 0 0 S 0.0 0.0 0:02.79 migration/0

8 root 20 0 0 0 0 S 0.0 0.0 0:00.00 rcu_bh

9 root 20 0 0 0 0 S 0.0 0.0 0:01.40 rcu_sched

...

这个输出结果中,第三行%Cpu就是系统的CPU使用率,具体每一列的含义上一节都讲过,只是把CPU时间变换成了CPU使用率,我就不再重复讲了。不过需要注意,top默认显示的是所有CPU的平均值,这个时候你只需要按下数字1 ,就可以切换到每个CPU的使用率了。

继续往下看,空白行之后是进程的实时信息,每个进程都有一个%CPU列,表示进程的CPU 使用率。它是用户态和内核态CPU使用率的总和,包括进程用户空间使用的CPU、通过系统调用执行的内核空间CPU 、以及在就绪队列等待运行的CPU。在虚拟化环境中,它还包括了运行虚拟机占用的CPU。

# 每隔1秒输出一组数据,共输出2组

# pidstat 1 2

Linux 3.10.0-693.el7.x86_64 (node74-1) 2019年06月16日 _x86_64_(2 CPU)

19时36分16秒 UID PID %usr %system %guest %wait %CPU CPU Command

19时36分17秒 0 13528 0.00 0.99 0.00 0.00 0.99 0 kworker/0:0

19时36分17秒 0 13745 0.00 0.99 0.00 0.00 0.99 1 pidstat

19时36分17秒 UID PID %usr %system %guest %wait %CPU CPU Command

19时36分18秒 0 950 0.99 0.00 0.00 0.00 0.99 1 tuned

19时36分18秒 0 13745 0.00 0.99 0.00 0.00 0.99 1 pidstat

平均时间: UID PID %usr %system %guest %wait %CPU CPU Command

平均时间: 0 950 0.50 0.00 0.00 0.00 0.50 - tuned

平均时间: 0 13528 0.00 0.50 0.00 0.00 0.50 - kworker/0:0

平均时间: 0 13745 0.00 0.99 0.00 0.00 0.99 - pidstat

部分指标含义:用户态 CPU 使用率 (%usr)

内核态 CPU 使用率(%system)

运行虚拟机 CPU 使用率(%guest)

等待 CPU 使用率(%wait)

总的 CPU 使用率(%CPU)

CPU 使用率过高怎么办?

通过top,ps,pidstat我们可以很容易的找到使用cpu高的进程,找到进程后,下一步该做什么呢?使用GDB(The GNU Project Debugger)来调试程序,找出问题点。但是GDB会在程序中打上断点,影响业务正常工作。

使用perf分析CPU性能问题,它以性能事件采样为基础,不仅可以分析系统的各种事件和内核性能,还可以用来分析指定应用程序的性能问题。

# yum -y install perf

Samples: 106 of event 'cpu-clock', Event count (approx.): 26160156

Overhead Shared Object Symbol

56.38% [kernel] [k] mpt_put_msg_frame

8.97% [kernel] [k] _raw_spin_unlock_irqrestore

3.82% [kernel] [k] _raw_qspin_lock

3.82% [kernel] [k] xfs_iflush_int

3.82% [kernel] [k] xfs_inode_buf

...

输出结果中,第一行包含三个数据,分别是采样数(Samples)、事件类型(event)和事件总数量(Event count)。比如这个例子中,perf总共采集了106个CPU时钟事件,而总事件数则为26160156第一列 Overhead ,是该符号的性能事件在所有采样中的比例,用百分比来表示。

第二列 Shared ,是该函数或指令所在的动态共享对象(Dynamic Shared Object),如内核、进程名、动态链接库名、内核模块名等。

第三列 Object ,是动态共享对象的类型。比如 [.] 表示用户空间的可执行程序、或者动态链接库,而 [k] 则表示内核空间。

最后一列 Symbol 是符号名,也就是函数名。当函数名未知时,用十六进制的地址来表示。

# perf record # 先进行采样

^C[ perf record: Woken up 1 times to write data ]

[ perf record: Captured and wrote 0.232 MB perf.data (1762 samples) ]

# perf report # 对采样的数据生成报告,跟perf top一样

案例

还是之前模拟多进程的例子

使用stress模拟多进程

# -c 指定几个进程,-t指定时间

# stress -c 2 -t 600

stress: info: [13786] dispatching hogs: 2 cpu, 0 io, 0 vm, 0 hdd

使用top查看cpu使用率

# top

top - 19:53:34 up 6:31, 6 users, load average: 1.67, 0.62, 0.26

Tasks: 105 total, 3 running, 102 sleeping, 0 stopped, 0 zombie

%Cpu0 :100.0 us, 0.0 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st

%Cpu1 :100.0 us, 0.0 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st

KiB Mem : 999720 total, 631232 free, 107600 used, 260888 buff/cache

KiB Swap: 10485756 total, 10485756 free, 0 used. 710932 avail Mem

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND

13788 root 20 0 7264 96 0 R 99.7 0.0 1:42.94 stress

13787 root 20 0 7264 96 0 R 99.3 0.0 1:43.02 stress

...

从上面可以看到是stress进程导致cpu使用率比较高。

使用perf查看进程的哪个函数导致cpu上升的

# -g 开启调用关系分析,-p 指定进程id

# perf record -g -p 13788

^C[ perf record: Woken up 4 times to write data ]

[ perf record: Captured and wrote 0.966 MB perf.data (15691 samples) ]

# perf report

Samples: 15K of event 'cpu-clock', Event count (approx.): 3922750000

Children Self Command Shared Object Symbol

+ 36.33% 36.32% stress libc-2.17.so [.] __random_r

+ 30.27% 30.20% stress libc-2.17.so [.] __random

+ 12.40% 12.40% stress libc-2.17.so [.] rand

+ 9.80% 9.78% stress stress [.] 0x0000000000002dc1

+ 4.31% 4.31% stress stress [.] 0x0000000000001000

从输出结果可以看到是stress的__random随机数生成函数导致cpu上升的。 使用回车键可以看到引用内容。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值