极客时间专栏:Linux性能优化

  • uptime命令查看1 5 15分钟的负载情况,如果相差不大说明系统负载平稳,1分钟远大于15分钟说明最近一分钟负载很高
  • lscpu:查看cpu信息
  • 假设我们在一个单 CPU 系统上看到平均负载为 1.73,0.60,7.98,那么说明在过去 1 分钟内,系统有 73% 的超载,而在 15 分钟内,有 698% 的超载,从整体趋势来看,系统的负载在降低。
  • 平均负载高于70%时就不好了
  • 平均负载案例:安装stress和sysstat
  • stress 是一个 Linux 系统压力测试工具,这里我们用作异常进程模拟平均负载升高的场景。
  • 而 sysstat 包含了常用的 Linux 性能工具,用来监控和分析系统的性能。我们的案例会用到这个包的两个命令 mpstat 和 pidstat。
  • mpstat 是一个常用的多核 CPU 性能分析工具,用来实时查看每个 CPU 的性能指标,以及所有CPU的平均指标。
  • pidstat 是一个常用的进程性能分析工具,用来实时查看进程的 CPU、内存、I/O 以及上下文切换等性能指标。
  • 安装两个性能测试工具
apt install stress sysstat
  • 给一个cpu模拟100%负载
stress --cpu 1 --timeout 600
  • -d 参数表示高亮显示变化的区域
watch -d uptime
  • -P ALL 表示监控所有CPU,后面数字5表示间隔5秒后输出一组数据
mpstat -P ALL 5
  • 到底是哪个进程导致了 CPU 使用率为 100% 呢?你可以使用 pidstat 来查询:
  • 间隔5秒后输出一组数据
pidstat -u 5 1

总结:
平均负载高有可能是 CPU 密集型进程导致的;
平均负载高并不一定代表 CPU 使用率高,还有可能是 I/O 更繁忙了;
当发现负载高的时候,你可以使用 mpstat、pidstat 等工具,辅助分析负载的来源。
cpu核数: lscpu、 grep ‘model name’ /proc/cpuinfo | wc -l
显示平均负载:uptime、top,显示的顺序是最近1分钟、5分钟、15分钟,从此可以看出平均负载的趋势。
watch -d uptime: -d会高亮显示变化的区域。
strees: 压测命令,–cpu cpu压测选项,-i io压测选项,-c 进程数压测选项,–timeout 执行时间。
mpstat: 多核cpu性能分析工具,-P ALL监视所有cpu。
pidstat: 进程性能分析工具,-u 显示cpu利用率。

  • 还是建议用top和ps或者lsof来分析,因为一般线上的机器不会额外安装这之外的工具,而且很多公司用堡垒机登录上去之后其他的基本上都用不了,用其自带的最保险

CPU上下文切换

  • 进程上下文切换,线程上下文切换,中断上下文切换
  • 同一个进程的线程上下文切换海星
vmstat 5
  • cs(context switch)是每秒上下文切换的次数。

  • in(interrupt)则是每秒中断的次数。

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

  • b(Blocked)则是处于不可中断睡眠状态的进程数。

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

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

  • sysbench来模拟系统多线程调度切换的情况

自愿上下文切换变多了,说明进程都在等待资源,有可能发生了 I/O 等其他问题;

非自愿上下文切换变多了,说明进程都在被强制调度,也就是都在争抢 CPU,说明 CPU 的确成了瓶颈;

中断次数变多了,说明 CPU 被中断处理程序占用,还需要通过查看 /proc/interrupts 文件来分析具体的中断类型。

某个应用使用率达到了100%该怎么办

  • execsnoop可以用来监控短时动态的性能问题
  • 碰到常规问题无法解释的 CPU 使用率情况时,首先要想到有可能是短时应用导致的问题,比如有可能是下面这两种情况。
  • 第一,应用里直接调用了其他二进制程序,这些程序通常运行时间比较短,通过 top 等工具也不容易发现。
  • 第二,应用本身在不停地崩溃重启,而启动过程的资源初始化,很可能会占用相当多的 CPU。
  • 对于这类进程,我们可以用 pstree 或者 e xecsnoop 找到它们的父进程,再从父进程所在的应用入手,排查问题的根源。

06 | 案例篇:系统的 CPU 使用率很高,但为啥却找不到高 CPU 的应用?

  • 分析工具不能分析出cpu升高的原因可能是因为top、pidstat和pstree不能监控短时进程
  • execsnoop 就是一个专为短时进程设计的工具
  • 它通过 ftrace 实时监控进程的 exec() 行为,并输出短时进程的基本信息,包括进程 PID、父进程 PID、命令行参数以及执行的结果。
  • execsnoop 所用的 ftrace 是一种常用的动态追踪技术,一般用于分析 Linux 内核的运行时行为
  • 应用本身在不停地崩溃重启,而启动过程的资源初始化,很可能会占用相当多的 CPU

07 | 案例篇:系统中出现大量不可中断进程和僵尸进程怎么办?(上)

  • 等待IO的进程因为得不到硬件的响应,长时间处于不可中断状态,从ps中看到都处于D状态,也就是不可中断状态
  • 进程的几种状态:R:running、D:disk sleep不可中断睡眠(进程和硬件交互)、Z:Zombie(僵尸进程)实际进程已经结束了,但是父进程还没有回收他的资源、S:睡眠,可以被唤醒、I:Idle空闲状态、T:暂停
  • 可能是子进程退出的太快,父进程还没来得及调用wait()方法
  • 通常,僵尸进程持续的时间都比较短,在父进程回收它的资源后就会消亡;或者在父进程退出后,由 init 进程回收后也会消亡。
  • 一旦父进程没有处理子进程的终止,还一直保持运行状态,那么子进程就会一直处于僵尸状态。大量的僵尸进程会用尽 PID 进程号,导致新进程不能创建,所以这种情况一定要避免。
  • 进程组表示一组 互相关联的进程,每个子进程都是父进程所在组的成员

08 | 案例篇:系统中出现大量不可中断进程和僵尸进程怎么办?(下)

09 | 基础篇:怎么理解Linux软中断?

  • 中断是操作系统用来响应硬件设备请求的一种机制,只会打断进程的正常调度和执行,中断就好比外卖到了的电话,没接到电话可以做其他的事情,中断其实是一种异步的事件处理机制,可以提高系统的并发处理能力
  • 但是长时间的中断会导致其他中断的丢失问题,为了解决此问题,Linux将中断处理分为上半部和下半部
  • 上半部用来快速处理中断,,下半部用来延迟处理上半部未完成的工作
  • 比如说前面取外卖的例子,上半部就是你接听电话,告诉配送员你已经知道了,其他事儿见面再说,然后电话就可以挂断了;下半部才是取外卖的动作,以及见面后商量发票处理的动作。这样,第一个配送员不会占用你太多时间,当第二个配送员过来时,照样能正常打通你的电话
  • 就是不要长时间的占线
  • Linux的 proc文件
  • Linux 中的软中断包括网络收发、定时、调度、RCU 锁等各种类型,可以通过查看 /proc/softirqs 来观察软中断的运行情况。

10 | 案例篇:系统的软中断CPU使用率升高,我该怎么办?

  • 处理程序,而中断处理程序被分为上半部和下半部这两个部分。
  1. 上半部对应硬中断,用来快速处理中断;

  2. 下半部对应软中断,用来异步处理上半部未完成的工作。

  • 软中断 CPU 使用率(softirq)升高是一种很常见的性能问题。虽然软中断的类型很多,但实际生产中,我们遇到的性能瓶颈大多是网络收发类型的软中断,特别是网络接收的软中断。

11 | 套路篇:如何迅速分析出系统CPU的瓶颈在哪里?

极客时间专栏:Linux性能优化_第1张图片

极客时间专栏:Linux性能优化_第2张图片

极客时间专栏:Linux性能优化_第3张图片

极客时间专栏:Linux性能优化_第4张图片

12 | 套路篇:CPU 性能优化的几个思路

15 | 基础篇:Linux内存是怎么工作的?

  • 之只有内核可以直接访问物理内存,当进程要访问内存时该怎么办?
  • Linux内核给每个进程提供了独立的虚拟地址空间,这个地址空间是连续的,进程可以很方便访问虚拟内存
  • 虚拟地址空间又分为用户空间和内核空间

极客时间专栏:Linux性能优化_第5张图片

  • 进程的用户态和内核态,进程在用户态时只能访问用户空间内存,进入内核态后才能访问内核空间内存
  • 虚拟内存分布:

极客时间专栏:Linux性能优化_第6张图片

  • 只读段,包括代码和常量等。

  • 数据段,包括全局变量等。

  • 堆,包括动态分配的内存,从低地址开始向上增长。

  • 文件映射段,包括动态库、共享内存等,从高地址开始向下增长。

  • 栈,包括局部变量和函数调用的上下文等。栈的大小是固定的,一般是 8 MB。

  • malloc() 是 C 标准库提供的内存分配函数,对应到系统调用上,有两种实现方式,即 brk() 和 mmap()。

  • 对小块内存(小于 128K),C 标准库使用 brk() 来分配,也就是通过移动堆顶的位置来分配内存。这些内存释放后并不会立刻归还系统,而是被缓存起来,这样就可以重复使用

  • 而大块内存(大于 128K),则直接使用内存映射 mmap() 来分配,也就是在文件映射段找一块空闲内存分配出去。

你可能感兴趣的:(极客时间专栏:Linux性能优化)