性能优化有两大指标:延时吞吐。

linux优化思维导图:

平均负载

[root@node200 ~]# uptime20:45:44 up 11:24,  2 users,  load average: 0.00, 0.01, 0.05
当前时间  启动运行时长 当前正在登陆的用户 1、5、15分钟系统的平均负载

平均负载是指单位时间内,系统处于可运行状态(runnable)和不可中断(uninterruptable)的平均进程数,也就是平均活跃进程数,它和CPU使用率没有直接关系。可以简单理解为,平均负载其实就是平均活跃进程数。

进程状态一共有如下5种

  1. R(运行):进程正在运行或在运行队列中等待。
  2. T(停止):进程收到停止信号后停止运行。
  3. Z(僵死):进程已经终止,但进程描述符依然存在, 直到父进程调用wait4()系统函数后将进程释放。
  4. S(中断):进程处于休眠中,当某个条件形成后或者接收到信号时,则脱离该状态。
  5. D(不可中断):进程不响应系统异步信号,即便用kill命令也不能将其中断。

比如,当一个进程向磁盘读写数据时,为了保证数据的一致性,在得到磁盘回复前,他是不能被其他进程或者中断打断,这个时候的进程就区域不可中断的状态。如果此时的进程被打断了,就容易出现磁盘数据与进程数据不一致的问题。因此,不可中断状态实际上是系统对进程和硬件设备的一种保护机制。

最理想的状态,就是每个CPU上都刚好运行着一个进程,这样每个CPU都得到充分利用。例如,当平均负载为2时,

  • 在只有2个CPU的系统上,意味着所有的CPU都刚好被完全占用,是最理想的状态
  • 在有4个CPU的系统上,意味着CPU有50%的空闲。
  • 在只有1个CPU的系统上,意味着有一半的进程竞争不到CPU。

因此,在评判平均负载的高低前,首先你要知道系统有几个CPU。可以通过top(按1)、lscpu或者查看/proc/cpuinfo获取本机cpu的个数。

[root@node200 ~]# lscpu
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                8
On-line CPU(s) list:   0-7
Thread(s) per core:    1
Core(s) per socket:    1
Socket(s):             8
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 61
Model name:            Intel Core Processor (Broadwell)
Stepping:              2
CPU MHz:               2099.998
BogoMIPS:              4199.99
Hypervisor vendor:     KVM
Virtualization type:   full
L1d cache:             32K
L1i cache:             32K
L2 cache:              4096K
NUMA node0 CPU(s):     0-7

[root@node200 ~]# grep "model name" /proc/cpuinfo |wc -l
8

当平均负载高于CPU数量的70%的时候,你就应该分析排查负载高的问题了。

平均负载是指单位时间内,处于可运行状态和不可中断状态的进程数。所以,它不仅包括了正在使用CPU的进程数,还包括等待CPU和等待I/O的进程数。

而CPU使用率,是根据单位时间内CPU的繁忙情况进行统计,和平均负载并一定完全一致。例如,

  • CPU密集型进程,大量使用CPU会导致负载升高,此时CPU使用率和平均负载是一致的。
  • I/O密集型进程,等待I/O也会导致平均负载升高,但是CPU的使用率并不一定会很高。
  • 大量等待CPU的进程调度也会导致平均负载升高,此时的CPU使用率也会比较高。

stress是一个Linux系统压力测试工具。

sysstat包含了常用的Linux性能工具,用来监控和分析系统的性能。以下案例使用mpstat和pidstat两个命令。

mpstat是一个常用的多核CPU性能分析工具,用来实时查看每个CPU的性能指标以及所有CPU的平均指标。

pidstat是一个常用的进程性能分析工具,用来实时查看进程的CPU、内存、I/O以及上下文切换等性能指标。

[root@node200 ~]#  yum install -y epel-release
[root@node200 ~]# yum install sysstat stress -y
[root@node200 ~]# cat /proc/cpuinfo|grep "model name" |wc -l
2

场景一:CPU密集型

第一个终端运行压力测试

[root@node200 ~]# stress -c 2 --timeout 600

第二个终端通过uptime实时查看平均负载

[root@node200 ~]# watch -d uptime
Every 2.0s: uptime                                                                                                                Sat May 16 21:53:46 202021:53:46 up 5 min,  4 users,  load average: 2.04, 0.96, 0.38

第三个终端使用mpstat查看cpu变化情况:

## -P ALL表示监控所有的CPU,5表示每间隔5秒后输出一组数据
[root@node200 ~]# mpstat -P ALL 5
Linux 3.10.0-1062.18.1.el7.x86_64 (node200.com)     05/16/2020  _x86_64_    (2 CPU)09:56:07 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
09:56:12 PM  all   99.70    0.00    0.30    0.00    0.00    0.00    0.00    0.00    0.00    0.00
09:56:12 PM    0   99.60    0.00    0.40    0.00    0.00    0.00    0.00    0.00    0.00    0.00
09:56:12 PM    1   99.80    0.00    0.20    0.00    0.00    0.00    0.00    0.00    0.00    0.00

第四个终端使用pidstat查看进程信息

## 每隔3秒后输出一组数据,总共输出5次
[root@node200 ~]# pidstat -u 3 5
Linux 3.10.0-1062.18.1.el7.x86_64 (node200.com)     05/16/2020  _x86_64_    (2 CPU)09:58:11 PM   UID       PID    %usr %system  %guest    %CPU   CPU  Command
09:58:14 PM     0      1693   99.67    0.00    0.00   99.67     0  stress
09:58:14 PM     0      1694   99.34    0.00    0.00   99.34     1  stress
09:58:14 PM     0      2043    0.00    0.33    0.00    0.33     1  pidstat09:58:14 PM   UID       PID    %usr %system  %guest    %CPU   CPU  Command
09:58:17 PM     0      1693   99.67    0.00    0.00   99.67     0  stress
09:58:17 PM     0      1694   99.33    0.00    0.00   99.33     1  stress
09:58:17 PM     0      1735    0.00    0.33    0.00    0.33     1  watch

场景二:I/O密集型

[root@node200 ~]# stress -i 4 --timeout 600s

然后也是通过uptime、mpstat和pidstat查看系统的负载情况,也可以通过top查看此时CPU使用率并不高,而平均负载却高达4。

场景三:大量进程情形(即大量进程处于可运行状态)

[root@node200 ~]# stress -c 8 --timeout 600s

8远大于2(cpu个数),此时CPU负载也是很高的。

小结:

  1. 平均负载高有可能是cpu密集型进程导致的,也有可能是I/O密集型进程导致的,也有可能是大量进程处于等待CPU调度的情况导致的
  2. 平均负载高并不意味着CPU使用率高,参见实验情景二。
  3. 平均负载高的时候,使用mpstat、pidstat、top、uptime等工具进行分析。

cpu上下文切换

进程在竞争CPU的时候并没有真正运行,是CPU上下文切换导致平均负载升高。在每个任务运行前,CPU都需要知道任务从哪里加载、又从哪里开始运行,也就是说,需要系统事先帮他设置好CPU寄存器程序计数器

cpu寄存器是CPU内置的容量小、但速度极快的内存。而程序计数器,则是 用来存储CPU正在执行的指令位置、或者即将执行的下一条指令位置。他们都是CPU在运行任何任务前,必须的依赖环境,因此也被叫做CPU上下文

CPU上下文切换,就是先把前一个任务的CPU上下文(也就是CPU寄存器和程序计数器)保存起来,然后加载新任务的上下文到这些寄存器和程序计数器,最后再跳转到程序计数器所指的新位置,运行新任务。而这些保存下来的上下文,会存储在系统内核中,并在任务重新调度之行时候再次加载进来,这样就能保证任务原来的状态不受影响,让任务看起来还是连续运行。

根据任务的不同,cpu的上在问切换可以分为几个不同的场景,也就是进程上下文切换、线程上下文切换、中断上下文切换。

Linux按照特权等级,把进程的运行空间分为内核空间和用户空间,分别对应下图中的Ring 0和Ring 3。

内核空间(Ring 0)具有最高权限,可以直接访问所有资源。

用户空间(Ring 3)只能访问受限资源,不能直接访问内存等硬件设备,必须通过系统调用陷入到内核中,才能访问这些特权资源。

也就是说,进程既可以在用户空间运行,又可以在内核空间中运行。进程在用户空间运行时候,被称为进程 的用户态,而陷入内核空间的时候,被称为进程的内核态。

从用户态到内核态的转变,需要通过系统调用来完成。例如,当我们查看文件内容时候,就需要多次系统调用来完成:首先调用open()打开文件,然后调用read()读取文件内容,并调用write()将内容写出到标准输出,最后再调用close()关闭文件。系统调用的过程也需要CPU进行上下文切换。

CPU寄存器里原来用户态的指令位置,需要先保存起来。接着,为了执行内核状态代码,cpu寄存器需要更新为内核态指令的新位置,最后才是跳转到内核态运行内核任务。系统调用结束后,CPU寄存器需要恢复原来保存的用户态,然后再切换到用户空间,继续运行进程。所以,一次系统调用的过程,其实时发生了两次CPU上下文切换。

不过,需要注意的是,系统调用过程中,并不会涉及到虚拟内存等用户态的资源切换,也不会切换进程,这和我们通常所说的进程上下文切换是不一样的:

  • 进程上下文切换,是指从一个进程切换到另一个进程中。
  • 而系统调用的过程一直是同一个进程在运行,只是用户空间与内核空间进行切换,分别执行相应权限的指令。

所以,系统调用过程通常称为特权模式切换,而不是上下文切换。

进程是由内核来管理和调度的,晋城的切换只能发生在内核态。所以,进程的上下文不仅包括了虚拟内存、栈、全局变量等用户空间的资源,还包括了内核堆栈、寄存器等内核空间的状态。因此,进程的上下文且换比系统调用时候多了一步:在保存当前进程的内核状态和CPU寄存器之前,需要把改进承诺的虚拟内存、栈等保存下来,而加载了下一进程的内核态后,还需要刷新晋城的虚拟内存和用户栈。

每次上下文切换都需要几十纳秒到数微秒的CPU时间。在进程上下文切换次数较多的情况下,很容易导致CPU将大量的时间耗费在寄存器、内核堆以及虚拟内存等资源的保存和回复上,进而大大缩短了真正运行进程的时间,从而导致平均负载升高。

另外,Linux通过TLB来管理虚拟内存到五力内存的映射,当虚拟内存更新后,TLB也需要刷新,内存的访问也会随之变慢。特别是在多处理器的系统上,缓存是被多个处理器共享的,刷新缓存不仅会影响当前处理器的进程,还会影响共享缓存的其他处理器的进程。

只有在进程调度切换时候,才需要切换上下文,linux为每一个cpu都维护了一个就绪队列,将活跃进程(即正在运行和正在等待CPU的进程)按照优先级和等待CPU的时间顺序,然后选择最需要CPU的进程,也就是优先级最高和等待CPU时间最长的进程来运行。

有如下场景会促发进程调度:

  1. 进程执行完终止了,它之前使用的CPU会释放出来,这时候会从就绪队列里,拿一个新的进程来运行
  2. 为了保证所有进程得到公平调度,CPU时间被划分成一段段的时间片,这些时间片再被轮流分配给各个进程。这样,当某个进程的时间片耗尽了,就会被系统挂起,切换到其他正在等待CPU的进程运行。
  3. 进程在系统资源不足(比如内存不足)时,要等大哦资源满足后才可以运行,这个时候进程也会被挂起,并由系统调度其他进程运行。
  4. 当进程通过睡眠函数sleep这样的方法将自己主动挂起时,自然也会重新调度。
  5. 当有优先级更高的进程运行时,为了保证高优先级进程的运行,当前进程也会被挂起,由高优先级进程来运行。
  6. 发生硬件中断时,CPU上的进程会被中断挂起,转而执行内核中的中断服务程序。

线程上下文切换

线程与进程的最大区别在于线程是调度的基本单位,而进程是资源拥有的基本单位。

  • 当进程只有一个线程时候,可以认为进程就等于线程。
  • 当晋城拥有多个线程时候,这些县城会共享相同的虚拟内存和全局变量等资源。这些资源在线程上下文切换时候不需要修改。
  • 线程也有自己的私有数据,比如栈和寄存器,这些在线程上下文切换是后也需要保存切换。

线程上下文切换分为两种情况:

前后两个线程数与不同进程,此时,因为资源不贡献,所以切换过程就和进程上下文切换是一致的。

前后两个线程同属于一个进程。此时,虚拟内存和圈局变量等资源是共享的,所以在切换时候,这些资源就保持不懂,只需要切换线程私有数据、寄存器等不共享的数据。

正因为同一进程内的不同线程切换的代价校园多进程间的上下文切换,因此,通常采用多线程来取代多进程。

中断上下文切换

除了上面两种上下文切换,还有一个场景也会切换CPU上下文,那就是中断。

为了快速响应硬件的事件,中断处理会打断进程的正常调度和执行,转而调用中断处理程序,响应设备事件。而在打断其他进程时,就需要将进程当前的状态保存下来,这样在中断结束后,进程任然可以从原来的状态恢复运行。

跟进程上下文不同,中断上下文切换并不涉及到进程的用户态。所以,即便中断打断了一个正在处于用户态的进程,也不需要保存和恢复这个进程的虚拟内存、全局变量等用户态资源。中断上下文,其中只包括内核态中断服务程序执行必须的状态,包括CPU寄存器、内核堆栈、硬件中断参数等。

对于同哦一个CPU来说,中断处理比进程拥有更高的优先级,所以终端上下文切换并不会与进程上下文切换同时发生。同样道理,由于中断会打断正常进程的调度和执行,所以大部分中断处理程序都短小精悍,以便尽可能快的执行结束。

另外,跟进程上下文切换一样,中断上下文切换需要消耗cpu,切换次数过多也会耗费大量的CPU,甚至严重降低系统的整体性能。

小结

  1. cpu上下文切换,是保证linux正常工作的核心功能之一,一般情况下不需要我们特别关注。
  2. 但过多的上下文切换,回报cpu时间消耗在寄存器,内核栈以及虚拟内存等数据的保存和恢复上,从而缩短进程真正运行的时间,导致系统的整体性能大幅下降。

vmstat是一个常用的系统性能分析工具,主要用来分析系统的内存使用情况,也常用来分析CPU上下文切换和中断的次数。

## 每隔3秒输出一组数据,输出一次
[root@node200 ~]# vmstat 3 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st1  0      0 7619244   2080 367984    0    0     2     3  177   26  2  1 98  0  0

cs(context switch):每秒上下文切换的次数。

in(interrupt):每秒中断的次数。

r(running or runnable)就是就绪队列的长度,也就是正在运行和等待CPU的进程数。

b(blocked)处于不可中断睡眠状态的进程数。

vmstat只给出了系统总体的上下文切换情况,想要查看每隔进程的详细情况,可以使用pidstat。

[root@node200 ~]# pidstat  -w 5
Linux 3.10.0-1062.18.1.el7.x86_64 (node200.com)     05/17/2020  _x86_64_    (2 CPU)08:38:57 PM   UID       PID   cswch/s nvcswch/s  Command
08:39:02 PM     0         1      2.59      0.00  systemd
08:39:02 PM     0         6      0.20      0.00  ksoftirqd/0
08:39:02 PM     0         7      0.20      0.00  migration/0
08:39:02 PM     0         9     10.58      0.00  rcu_sched
08:39:02 PM     0        11      0.20      0.00  watchdog/0
08:39:02 PM     0        12      0.20      0.00  watchdog/1
08:39:02 PM     0        13      0.20      0.00  migration/1
08:39:02 PM     0        14      0.60      0.00  ksoftirqd/1
08:39:02 PM     0        37      0.20      0.00  khugepaged
08:39:02 PM     0       102      1.00      0.00  kauditd
08:39:02 PM     0       382      1.00      0.00  kworker/1:1H
08:39:02 PM     0       394      2.20      0.00  kworker/0:1H
08:39:02 PM     0       493      1.20      0.00  systemd-journal
08:39:02 PM     0       902      1.20      0.00  auditd
08:39:02 PM     0       925      0.40      0.00  abrt-watch-log
08:39:02 PM   999       930      1.80      0.00  polkitd
08:39:02 PM     0       933      2.59      0.00  systemd-logind
08:39:02 PM    81       934      5.39      0.00  dbus-daemon
08:39:02 PM    70       939      0.80      0.00  avahi-daemon
08:39:02 PM     0       951      0.40      0.00  crond
08:39:02 PM     0       961      0.80      0.00  firewalld
08:39:02 PM     0       976      1.40      0.00  NetworkManager
08:39:02 PM    26      1402      0.20      0.00  postmaster
08:39:02 PM     0      1488      1.20      0.00  master
08:39:02 PM    89      1522      0.80      0.00  qmgr
08:39:02 PM     0      2739      0.40      0.00  kworker/u4:2
08:39:02 PM     0     14102      3.79      0.00  kworker/0:1
08:39:02 PM    89     16370      1.40      0.00  cleanup
08:39:02 PM     0     16373      1.20      0.00  local
08:39:02 PM    89     16765      0.60      0.00  pickup
08:39:02 PM    89     16771      0.40      0.00  trivial-rewrite
08:39:02 PM     0     16926      1.20      0.00  kworker/1:0
08:39:02 PM     0     16970      0.40      0.00  kworker/0:2
08:39:02 PM     0     16971      0.20      0.20  pidstat

cswch表示每秒资源上下文切换(voluntary context switches)的次数

nvcswch表示每秒非自愿上下文切换(non voluntary context switches)的次数。

所谓自愿上下文切换,是指进程无法获取所需资源,导致的上下文切换。比如,I/O、内存等系统资源不足时,就会发生自愿上下文切换。

而非资源上下文切换,是指进程由于时间片已到等原因,被系统强制调度,进程发生的上下文切换。比如说,大量进程都在争抢CPU时候,就容易发生非自愿上下文切换。

实验

sysbench是一个多线程的基准测试工具,一般用来评估不同系统参数下的数据库负载情况。当然,在本次案例中,我们只把它当成一个异常进程来看,作用是模拟上下文切换过多的问题。

root@fzlinwenw-KVM:~# vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----r  b 交换 空闲 缓冲 缓存   si   so    bi    bo   in   cs us sy id wa st0  0      0 4453964  52164 3245532    0    0     9    40  152  301  2  1 96  0  00  0      0 4453956  52164 3245532    0    0     0     0   41   48  0  0 100  0  00  0      0 4453956  52164 3245532    0    0     0     0   36   49  0  0 100  0  00  0      0 4453956  52164 3245532    0    0     0     0   32   44  0  0 100  0  0

可以看出,在压测之前,系统的us(user)用户cpu使用率、sy(system)系统cpu使用率、cs、in、r、b指标都是比较低的。

root@fzlinwenw-KVM:~# sysbench --threads=10 --max-time=600 threads run

root@fzlinwenw-KVM:~# vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----r  b 交换 空闲 缓冲 缓存   si   so    bi    bo   in   cs us sy id wa st8  0      0 4451664  52196 3245548    0    0     9    40  166  133  2  1 96  0  08  0      0 4451632  52196 3245548    0    0     0     0 78520 833560 19 79  3  0  07  0      0 4451632  52196 3245548    0    0     0     0 72674 842205 21 78  1  0  08  0      0 4451632  52196 3245548    0    0     0     0 72225 862825 21 77  2  0  06  0      0 4451632  52196 3245548    0    0     0     0 76753 904941 21 79  1  0  0

可以看出,在压测之后,系统的us(user)用户cpu使用率、sy(system)系统cpu使用率、cs、in、r、b指标都迅速上升。

r:running/runnable队列的长度已经到达8了,远超过系统cpu的个数2,所以肯定会有大量的cpu竞争。

us和sy这两列的cpu使用率加起来达到100%左右了,其中系统的cpu使用率,也就是sy高达84%,说明cpu主要是被内核占用了。

in中断次数也是直线上升。

root@fzlinwenw-KVM:~# pidstat -wu 3
10时49分22秒   UID       PID    %usr %system  %guest   %wait    %CPU   CPU  Command
10时49分25秒     0     18748    0.00    0.33    0.00    0.00    0.33     0  kworker/u4:0-events_freezable_power_
10时49分25秒     0     18802   41.67  100.00    0.00    0.00  100.00     0  sysbench
10时49分25秒     0     18813    0.33    0.00    0.00    0.00    0.33     1  pidstat10时49分22秒   UID       PID   cswch/s nvcswch/s  Command
10时49分25秒     0         9      0.33      0.00  ksoftirqd/0
10时49分25秒     0        10      5.67      0.00  rcu_sched
10时49分25秒     0        11      0.33      0.00  migration/0
10时49分25秒     0        17      0.33      0.00  migration/1
10时49分25秒     0        18      1.67      0.00  ksoftirqd/1
10时49分25秒     0       180      0.33      0.00  kworker/1:1H-kblockd
10时49分25秒     0       485      0.33      0.00  irqbalance
10时49分25秒     0       919      0.67      4.33  sshd
10时49分25秒   121      1165      1.00      0.00  gsd-color
10时49分25秒     0      1325      2.00      0.00  sshd
10时49分25秒     0     18315      4.67      0.00  kworker/1:1-events
10时49分25秒     0     18748      9.67      0.33  kworker/u4:0-events_freezable_power_
10时49分25秒     0     18756      6.67      0.00  kworker/u4:2-events_unbound
10时49分25秒     0     18790      1.00      2.00  vmstat
10时49分25秒     0     18813      0.33      0.67  pidstat
10时49分25秒     0     19252      4.67      0.00  kworker/0:3-ata_sff

可以看出,cpu使用率上升是由于sysbench导致的,他的CPU使用率达到了100%。上下文切换来自其他进程,包括非自愿上下文切换频率最高的sshd以及费最远上下文切换频率最高的kworker。但是此处不同进程间的上下文切换也就几十次,比vmstat的几十万磁明显小太多了,因此此处pidstat查看出来的上下文切换是忽略掉线程的数据的,可以加一个-t参数查看线程间上下文切换的详细情况,可以看到__sysbench的线程产生了大量的上下文切换。

root@fzlinwenw-KVM:~# pidstat -wt 3
Linux 5.3.0-28-generic (fzlinwenw-KVM)  2020年05月20日     _x86_64_    (2 CPU)
平均时间:   UID      TGID       TID   cswch/s nvcswch/s  Command
平均时间:     0        10         -      8.52      0.00  rcu_sched
平均时间:     0         -        10      8.52      0.00  |__rcu_sched
平均时间:     0        11         -      0.33      0.00  migration/0
平均时间:     0         -        11      0.33      0.00  |__migration/0
平均时间:     0        17         -      0.33      0.00  migration/1
平均时间:     0         -        17      0.33      0.00  |__migration/1
平均时间:     0        18         -      1.64      0.00  ksoftirqd/1
平均时间:     0         -        18      1.64      0.00  |__ksoftirqd/1
平均时间:     0         -       583      0.33      0.00  |__gmain
平均时间:     0         -       558      0.33      0.00  |__gmain
平均时间:   121      1165         -      0.98      0.00  gsd-color
平均时间:   121         -      1165      0.98      0.00  |__gsd-color
平均时间:     0      1325         -      1.97      0.00  sshd
平均时间:     0         -      1325      1.97      0.00  |__sshd
平均时间:     0      3235         -      0.33      0.00  sshd
平均时间:     0         -      3235      0.33      0.00  |__sshd
平均时间:     0     18315         -      4.26      0.00  kworker/1:1-events
平均时间:     0         -     18315      4.26      0.00  |__kworker/1:1-events
平均时间:     0     18790         -      0.98      1.97  vmstat
平均时间:     0         -     18790      0.98      1.97  |__vmstat
平均时间:     0     18796         -      2.30      0.33  kworker/u4:1-events_unbound
平均时间:     0         -     18796      2.30      0.33  |__kworker/u4:1-events_unbound
平均时间:     0         -     18803  13103.28  70691.80  |__sysbench
平均时间:     0         -     18804  12831.80  66949.18  |__sysbench
平均时间:     0         -     18805  13769.84  64950.49  |__sysbench
平均时间:     0         -     18806  10572.79  74155.41  |__sysbench
平均时间:     0         -     18807  12378.69  77803.28  |__sysbench
平均时间:     0         -     18808  12265.90  70099.02  |__sysbench
平均时间:     0         -     18809  10985.90  72320.00  |__sysbench
平均时间:     0         -     18810  11994.10  66074.43  |__sysbench
平均时间:     0         -     18811  13417.70  69490.82  |__sysbench
平均时间:     0         -     18812  12335.41  69239.67  |__sysbench
平均时间:     0     18816         -      0.33      6.23  pidstat
平均时间:     0         -     18816      0.33      6.23  |__pidstat
平均时间:     0     19252         -      5.25      0.00  kworker/0:3-events
平均时间:     0         -     19252      5.25      0.00  |__kworker/0:3-events

中断详情查看:

root@fzlinwenw-KVM:~# watch -d cat /proc/interruptsCPU0       CPU10:          4          0   IO-APIC   2-edge      timer1:          0          9   IO-APIC   1-edge      i80426:          0          3   IO-APIC   6-edge      floppy8:          0          0   IO-APIC   8-edge      rtc09:          0          0   IO-APIC   9-fasteoi   acpi10:         24          0   IO-APIC  10-fasteoi   virtio3, ehci_hcd:usb1, uhci_hcd:usb211:          0         72   IO-APIC  11-fasteoi   uhci_hcd:usb3, uhci_hcd:usb4, qxl12:         15          0   IO-APIC  12-edge      i804214:      62011       1219   IO-APIC  14-edge      ata_piix15:          0          0   IO-APIC  15-edge      ata_piix24:          0          0   PCI-MSI 98304-edge      virtio1-config25:         35          0   PCI-MSI 98305-edge      virtio1-virtqueues26:          0          0   PCI-MSI 114688-edge      virtio2-config27:          0     134237   PCI-MSI 114689-edge      virtio2-req.028:          0          0   PCI-MSI 49152-edge      virtio0-config29:      39099     270567   PCI-MSI 49153-edge      virtio0-input.030:     147242      51517   PCI-MSI 49154-edge      virtio0-output.031:        564          0   PCI-MSI 65536-edge      snd_hda_intel:card0
NMI:          0          0   Non-maskable interrupts
LOC:    1536267    1587458   Local timer interrupts
SPU:          0          0   Spurious interrupts
PMI:          0          0   Performance monitoring interrupts
IWI:          0          0   IRQ work interrupts
RTR:          0          0   APIC ICR read retries
RES:   70568928   69478828   Rescheduling interrupts
CAL:      99581      63530   Function call interrupts
TLB:       5505       5158   TLB shootdowns
TRM:          0          0   Thermal event interrupts
THR:          0          0   Threshold APIC interrupts
DFR:          0          0   Deferred Error APIC interrupts
MCE:          0          0   Machine check exceptions
MCP:        205        205   Machine check polls
HYP:          0          0   Hypervisor callback interrupts
HRE:          0          0   Hyper-V reenlightenment interrupts
HVS:          0          0   Hyper-V stimer0 interrupts
ERR:          0
MIS:          0
PIN:          0          0   Posted-interrupt notification event
NPI:          0          0   Nested posted-interrupt event
PIW:          0          0   Posted-interrupt wakeup event

/proc实际上是linux的一个虚拟文件系统,用于内核空间与用户空间的通信。/proc/interrupts就是这种通信机制的一部门,通过了一个只读的中断使用情况。观察一段时间,可以发现刷新最快的是Rescheduling interrupts(重调度中断),这个终端类型表示,唤醒空闲的CPU来调度新的任务运行。这是多处理器系统中,调度器用来分散任务到不同CPU的机制,也称为处理期间中断。所以,这里的中断升高还是因为过、过多任务的调度问题。

每秒多少次上下文切换才算正常?这个数值其实取决于系统本身的CPU性能。如果系统的上下文切换次数比较稳定,那么从数百到一万以内,应该都算正常。但当上下文切换超过一万或者切换次数出现数量级的增长,就很有可能出现了性能问题了。

小结:

  • 资源上下文切换变多了,说明进程都在等待资源,有可能发生了I/O等其他问题
  • 非自愿上下文切换变多了,说明进程都在被强制调度,也就是都在争抢CPU。说明cpu是瓶颈。
  • 中断次数变多了,说明cpu被中断处理程序占用,需要通过查看/proc/interrupts文件来分析具体的终端类型

CPU使用率

linux是一个多任务操作系统,将每个CPU的时间划分为很短的时间片,在通过调度器轮流分配给各个任务使用。为了维护CPU时间,linux通过事先定义的节拍率(内核中表示为HZ),触发时间中断,并使用全局变量Jiffies记录了开机以来的节拍数,没发生一次时间中断,Jiffies的值就会加一。

节拍率HZ是内核的可配选项,可以设置为100/250/1000等,不同的系统可能设置不同的数值,可以通过/boot/config内核选项来查看他的配置值。下图节拍率设置为250,也就是每秒钟触发250次时间中断

root@fzlinwenw-KVM:~# grep 'CONFIG_HZ=' /boot/config-$(uname -r)
CONFIG_HZ=250

linux 使cpu使用率升高_linux性能优化相关推荐

  1. linux 使cpu使用率升高_Linux程序性能优化:CPU的上下文切换

      linux操作系统是将CPU轮流分配给任务,分时执行的.而每次执行任务时,CPU需要知道CPU寄存器(CPU内置的内存)和程序计数器PC(CPU正在执行指令和下一条指令的位置)值,这些值是CPU执 ...

  2. linux 使cpu使用率升高_Linux系统中CPU占用率较高问题排查思路与解决方法

    Linux服务器上出现CPU负载达到100%居高不下的情况,如果CPU 持续跑高,则会影响业务系统的正常运行: CPU利用率.根据经验来看,用户空间进程占用CPU比例在 65-70%之间,内核(系统) ...

  3. linux 使cpu使用率升高_linux命令总结(二)

    每天不断完善和更新自己的认知是件让人很愉悦的事情!!! MOMO:linux命令总结(一)​zhuanlan.zhihu.com MOMO:linux命令总结(二)​zhuanlan.zhihu.co ...

  4. linux 使cpu使用率升高_Linux CPU使用率超过100%的原因

    今天在服务器上部署流媒体做推流的时候使用top命令发现CPU占用率竟高达270% 在top模式下按1可看见CPU的数量是4 百度了一番发现原来top命令是按CPU总使用率来显示的,4核理论上最高可达4 ...

  5. linux 使cpu使用率升高_关于linux系统CPU篇---gt;CPU使用率升高

    1.CPU使用率为单位时间内CPU使用情况的统计,以百分比的方式展示. LINUX作为一个多任务操作系统,将每个CPU的时间划分为很短的时间片,再通过调度器轮流分配给各个任务使用,因此造成多任务同时运 ...

  6. linux 使cpu使用率升高_[Linux小技巧] 一行命令让CPU占用率达到100%

    Java关键字--transient 当使用Serializable接口实现序列化操作时,如果一个对象中的某一属性不希望被序列化,则可以使用transient关键字进行声明 import java.i ...

  7. linux查看cpu占用率_Linux 性能查看

    查看系统负载 uptime 这个命令可以快速查看机器的负载情况. 在Linux系统中,这些数据表示等待CPU资源的进程和阻塞在不可中断IO进程(进程状态为D)的数量. 命令的输出,load avera ...

  8. linux 内核线程 软中断,Linux性能优化实战:系统的软中断CPU使用率升高,我该怎么办?(10)...

    一.坏境准备 1.拓扑图 2.安装包 在第9节的基础上 在VM2上安装hping3依奈包 wget http://www.tcpdump.org/release/libpcap-1.9.0.tar.g ...

  9. Linux 系统 CPU 使用率简单分析

    CPU 使用率是单位时间内 CPU 使用情况的统计,以百分比的方式展示. CPU 使用率 为了维护 CPU 时间,Linux 通过事先定义的节拍率(内核中表示为 HZ),触发时间中断,并使用全局变量 ...

  10. Linux:CPU使用率是如何计算的?怎么查看CPU使用率?

    CPU 使用率是最常用来描述系统CPU 性能的指标. CPU 使用率是单位时间内 CPU 使用情况的统计,以百分比的方式展示.那么 **CPU 使用率到底是怎么算出来的吗?再有 %user.%nice ...

最新文章

  1. Sizzle引擎--原理与实践(二)
  2. TF之data_format:data_format中的NHWCNCHW简介、转换的详细攻略
  3. 第2章 状态机思维与状态机变量
  4. 补交20145226蓝墨云班课 -- MyCP
  5. GCN--如何用图卷积网络在图上进行深度学习
  6. 互联网知识:工作多年的程序员都说不全
  7. python爬虫淘宝评论图片_Python爬虫实战四之抓取淘宝MM照片
  8. ArcCatalog导出数据
  9. 斩获微软offer后,我总结出这10个面试必备技巧(五星干货)
  10. iptables 跨网段转发
  11. mysql 横向分表_mysql横向和纵向的数据库分表
  12. 4年!我对OpenStack运维架构的总结
  13. STM32 实数FFT 极速配置
  14. linux 网络冲浪,命令行下的网络冲浪工具命令行浏览器介绍
  15. DEJA_VU3D - Cesium功能集 之 076-缓冲区分析
  16. 比特数据结构与算法(第二章收尾)带头双向循环链表的实现
  17. VS2019之wpf开发环境配置(非常详细)
  18. pdf中如何编辑文本框
  19. 大一下期计算机考试试题操作题,2016年大一计算机考试操作题
  20. HTML笔记——②HTML常用标签、属性

热门文章

  1. Atitit 各有所长原则 Thinker和Doer之争。 Doer Influencer relater thinker 目录 1. Doer Influencer relater thinke
  2. paip.java OutOfMemoryError 解决方法o33
  3. 易筋经:现代化支付系统脉络梳理
  4. 董承非: 如何从各种类型的错误中学习
  5. Julia : Formatting库的 fmt Base.@sprintf
  6. 高并发程序设计入门(转)
  7. LightTable:更改Julia代码字体和console中字体
  8. OAM 与 KubeVela 项目整体捐赠进入 CNCF,让云端应用交付更加简单
  9. 坚持开源、能力内化,中移苏研荣获“中国开源领军企业”大奖!
  10. 【优化运行】基于matlab多目标粒子群算法求解冷热电联供综合能源系统运行优化问题【含Matlab源码 1747期】