四、性能分析-硬件CPU
先分析硬件 、网络、 系统配置、应用程序
一:硬件: cpu、内存、磁盘、网络、io
1、CPU 中央处理器(架构,主频,核)
CPU 结构:主要物理结构是3个,实际是有4;
运算器: 真正进行计算的单元
控制器: leader
寄存器: 存储 指令、数据、地址
时钟
CPU中: 内核、线程、架构:正常情况下一个内核对应一个线程,若对应多个则是“超频”
查看CPU命令:`top` `lscpu` `cat /proc/cpuinfo`
lscpu : 当前服务器CPU数4,主频,
`cat /proc/cpuinfo`:/proc 虚拟文件,操作系统启动时,读取的信息,这些信息放内存中
`cat /proc/cpuinfo |grep "physical id" |sort |uniq |wc -l ` 查看物理cpu数量
`cat /proc/cpuinfo | grep "cpu cores" |uniq `查看CPU的core数,即核数
`cat /proc/cpuinfo | grep "processor" |wc -l` 查看逻辑CPU数量
load average = cpuload + ioload
上下文切换:https://blog.csdn.net/qq_41359051/article/details/89600544
是什么:多线程编程中一般线程的个数都大于 CPU 核心的个数,而一个 CPU 核心在任意时刻只能被一个线程使用,为了让这些线程都能得到有效执行,CPU 采取的策略是为每个线程分配时间片并轮转的形式。当一个线程的时间片用完的时候就会重新处于就绪
状态让给其他线程使用,这个过程就属于一次上下文切换。 概括来说就是:当前任务在执行完 CPU 时间片切换到另一个任务之前会先保存自己的状态,以便下 次再切换回这个任务时,可以再加载这个任务的状态。任务从保存到再加载的过程就是一次
上下文切换。上下文切换通常是计算 集型的。也就是说,它需要相当可观的处理器时间,在每秒几十上百次的切换中, 每次切换都需要纳秒量级的时间。所以,上下文切换对系统来说意味着消耗大量的 CPU 时间,事实上,可能是操作系统中时间消耗
最大的操作。Linux 相比与其他操作系,(包括其他类 Unix 系统)有很多的优点,其中有一项就是,其上下文切换和模式切换的时间消耗非常少
分类: 自愿上下文切换: 资源不够,自觉的切换到另外指令上
非自愿上下文切换: 有可能有优先级更高的指令、指令执行的时间已经到了,被迫中止当前的指令,去执行其他指令
如何区分: vmstat 只给出了系统总体的上下文切换情况,要想查看每个进程的详细情况,需要 pidstat。
cswch/s:每秒自愿上下文切换次数;
nvcswch/s:每秒非自愿上下文切换次数
差异:自愿上下文切换,指进程无法获取所需资源,导致的上下文切换。比如说, I/O、内存等系统资源不足时,就会发生自愿上下文切换。
非自愿上下文切换,是指进程由于时间片已到等原因,被系统强制调度,进而发生的上下文切换。比如说,大量进程都在争抢 CPU 时,就容易发生非自愿上下文切换(系统的就绪队列过长,也就是正在运行和等待 CPU 的进程数过多,
导致大量上下文切换;而上下文切换又会导致系统 CPU 的占用率升高)
上下文切换次数多少合理?
每秒上下文切换次数多少才算正常,其实取决于系统本身的 CPU 性能。 如果系统的上下文切换次数比较稳定,那么从数百到一万以内,都应该算是正常。但当上下文切换次数超过一万次,或者切换次数出现数量级的增长时,
很可能已经出现了性能问题。实际场景有如下几个:
自愿上下文切换变多,说明进程都在等待资源,可能是发生了 I/O 等其他问题;
非自愿上下文切换变多,说明进程都在被强制调度(都在争抢 CPU),说明 CPU 成了瓶颈;
中断次数变多,说明 CPU 被中断处理程序占用,还需要通过查看 /proc/interrupts 文件来分析具体的中断类型
如何解决:1、 要么在服务器上,减少启动的程序 2. 要么增加cpu的数量
实例:第一步:启动服务器资源监控:服务器硬件资源监控: grafana(前端) + prometheus(时序数据库) + node_exporter(硬件资源收集器)
第二步:模拟服务器压力
1. stress-ng: 性能测试模拟工具,可以直接模拟服务器各种压力情况
安装:1)安装epel源,更新系统 yum install -y epel-release.noarch && yum -y update 2)安装stess-ng 的工具 yum install -y stress-ng (第一步不可省去,不然工具安装不上)
第三步:进行上下文切换命令
1.模拟多进程
1) 命令 (( proc_cnt = `nproc`*10 )); stress-ng --cpu $proc_cnt --pthread 1 --timeout 150 模拟100个进程,持续150s
# nproc 这个命令可以获得服务器cpu的数量
# (( proc_cnt = `nproc`*10 )); 把cpu核的数量乘以10倍,给变量proc_cnt
# --cpu $proc_cnt $proc_cnt shell编程中的变量引用
# --pthread 每个进程有多少个线程
# --timeout 超时时间,在命令执行多长时间之后自动结束
2) 分析 top命令,可以到 loadaverage 有持续上升,cpu被100%使用 us + sy + si
vmstat 3 中r列有非常大的数据 有非常多的进程在抢cpu的资源,cs 上下文数据非常多 (系统总体的上下文切换情况)
memory: free 数据变小, 内存有一部分被使用
system: in有一点点, cs 有明显数据变大,说明有大量的 上下文切换
pidstat -w 1----这个命令可以上下文的每个进程详细信息
我们看到的大量 stress-ng--cpu cswch/s 自愿 nvcswch/s非自愿上下文的值
3)结论:现在可以得出 ,我们线程有大量的 进程上下文切换问题,而这个问题的进程:stress-ng–cpu
当你的服务器,使用top命令发现,系统负载比较高,所有的cpu的使用率接近或等于 100%,我们要排查问题,vmstat 1 , 结果我们看到有procs 中r列 有大量数据,说明我们有大量进程在竞争cpu的资源。
--------可能服务器的cpu数量不够, 也可能是 进程启动的太多
vmstat 我们还看 system中 cs 比较高 --------肯定有大量的上下文切换,但是,此时,我并不知道,是哪个进程导致 抢占cpu,-----找具体是哪个进程
==== 应该是某个经常有大量的上下文切换,而导致的cpu使用率过高,系统负载过高的问题
---问题的关键点,找到具体的进程:pidstat -w 3 看到具体的 上下文切换的数据比较大的进程。-------**得到具体进程 和进程id**
2.模拟多线程
1)命令 stress-ng --cpu `nproc` --pthread 1024 --timeout 60 1个进程产生1024个线程
2)分析 top 基本信息 vmstat 1 具体那块 pidstat -w 5 上下文切换
3)结论
1、top: load值一直在增加,而且增长的非常大
2、top:CPU的 us + sy ≈ 100%,us较低,**sy较高**
3、vmstat: procs的**r 就绪队列**长度,正在运行和等待的CPU进程数很大
4、vmstat: system的in(每秒中断次数) 和 **cs(上下文切换次数) 都很大**
5、vmstat:free变小、buff基本不变、cache变大
6、pidstat: cswch/s **自愿上下文切换** 升高
3.模拟IO(换入/换出) IO密集型,导致服务器平均负载比较高
1)命令 stress-ng -i 6 --hdd 1 --timeout 150
2)分析 top: loadaverage 上升; cpu: wa值很大 us、sy不是很大, buff/cache有增大
vmstat 1: mem free减少, cache有明显的增大, **bo**有明显数据, 说明有大量磁盘数据交换
mpstat -P ALL 3 : %iowat 数值比较大 再次证明,我们线程系统负载比较高的原因是,系统的磁盘读写测试性能瓶颈, 哪到底是哪个进程导致我们的磁盘读写高?
pidstat -w 1 stress-ng-hdd这个进程的 自愿上下文切换数据比较大,pid的值 进程id
3)结论 已经定位到了具体是哪个程序导致了:要么换磁盘,要么迁移到io性能更好的服务器
如果你是整体的迁移你的数据库,这个风险比较大,我们可以再另外一个IO性能比较好服务器,再安装一个数据库,做要给数据库读写分离。
要么 减少io操作