Linux性能优化实战(一)
一、优化方向
1,性能指标
从应用负载的视角出发,考虑“吞吐”和“延时”
从系统资源的视角出发,考虑资源使用率、饱和度等
2,性能优化步骤
- 选择指标评估应用程序和系统的性能;
- 为应用程序和系统设置性能目标;
- 进行性能基准测试;
- 性能分析定位瓶颈;
- 优化系统和应用程序;
- 性能监控和告警。
3,Linux性能工具图谱
二、平均负载
1,stress
安装命令:apt install stress
#模拟一个CPU使用率 100%stress -c N
会让stress生成N个工作进程进行开方运算,以此对CPU产生负载。
stress --cpu 1 --timeout 600
#模拟I/O密集进程stress -i N
会产生N个进程,每个进程反复调用sync()将内存上的内容写到硬盘上, --timeout 600 表示600秒后退出 stress -i 1 --timeout 600
2,sysstat
安装命令:apt install sysstat
- mpstat 是一个常用的多核cpu性能分析工具,用来实时查看每个CPU的性能指标,以及所有CPU的平均指标
mpstat -P ALL 5
其中-P ALL 表示监控所有CPU
数字5,表示每间隔5秒输出一组数据- pidstat 是一个常用的进程性能分析工具,用来实时查看进程的CPU、内存、IO以及上下文切换等性能指标
pidstat -u 5 1
每间隔5秒输出一组数据
3,场景模拟
a>CPU密集
stress
#模拟一个CPU使用率 100% stress -c N 会让stress生成N个工作进程进行开方运算,以此对CPU产生负载。--timeout 600 表示600秒后退出
stress --cpu 1 --timeout 600
监控uptime,负载在升高
mpstat,发现一个CPU的使用率高达100%,但是iowait为0,说明平均负载的升高由于CPU的使用率为100%
pidstat,发现是stress进程导致CPU使用率升高
b>I/O密集
stress
#模拟I/O密集进程 stress -i N 会产生N个进程,每个进程反复调用sync()将内存上的内容写到硬盘上
stress -i 1 --timeout 600
监控uptime,负载在升高
mpstat,发现一个系统CPU使用率升至23.87%,iowait高达67.53% 。说明平均负载的升高由于iowait的升高
pidstat,发现是由于stress进程导致
c>大量进程的场景
stress
stress -c 8 --timeout 600
uptime
pidstat,发现8个进程在争抢2个CPU,每个进程等待CPU的时间高达75%,导致CPU过载
三、CPU的上下文切换
1,基本概念
CPU寄存器:CPU内置的容量小、但速度极快的内存
程序计数器:用于存储CPU正在执行的指令位置、或者即将执行的下一条指令位置
CPU上下文:CPU寄存器和程序计数器所必须的依赖环境
CPU上下文切换:先把前一个任务的CPU上下文(也就是CPU寄存器和程序计数器)保存起来,然后加载新任务的上下文到这些寄存器和程序计数器,最后再跳转到程序计数器所指的新位置,运行新任务。
2,分类
a>进程上下文切换
Linux按照特权等级,把进程的运行空间分为内核空间和用户空间,分别对应CPU特权等级的 Ring 0 和Ring 3
- 内核空间(Ring 0)具有最高权限,可以直接访问所有资源
- 用户空间(Ring 3)只能访问受限资源,不能直接访问内存等硬件设备,必须通过系统调用陷入内核中,才能访问这些特权资源
换个角度,也就是进程既可以在用户空间运行,又可以在内核空间运行。进程在用户空间运行时,被称为进程的用户态,而陷入内核空间的时候,被称为进程的内核态。
在进程切换时才需要切换上下文,也就是进程调度时。Linux为每个CPU都维护了一个就绪队列,将活跃进程按照优先级和等待CPU的时间排序,然后选择最需要CPU的进程,也就是优先级最高和等待CPU时间最长的进程运行。涉及到的场景包括:
- 为了保证所有进程可以得到公平调度,CPU时间被划分为一段段的时间片,这些时间片再被轮流分配给各个进程。这样,当某个进程的时间片耗尽了,就会被系统挂起,切换到其他正在等待CPU的进程运行
- 进程在系统资源不足(比如内存不足)时,要等到资源满足后才可以运行,这个时候进程也会被挂起,并有系统调度其他进程运行
- 当进程通过睡眠函数sleep这样的方法将自己主动挂起时,自然也会重新调度
- 当有优先级更高的进程运行时,为了保证高优先级进程的运行,当前进程会被挂起,由高优先级进程来运行
- 当发生硬件中断时,CPU上的进程会被中断挂起,转而执行内核中的中断服务进程
b>线程上下文切换
线程是调度的基本单位,而进程则是资源拥有的基本单位。
- 当进程只有一个线程时,可以认为进程就等于线程
- 当进程拥有多个线程时,这些线程会共享相同的虚拟内存和全局变量等资源。这些资源在上下文切换时不需要修改
- 线程也有自己的私有数据,比如栈和寄存器,这些在上下文切换时也需要保存
线程上下文切换:1,前后两个线程属于不同进程,由于资源不同就是进程上下文切换;2,前后两个线程属于同一个进程,此时虚拟内存共享,切换时只需要切换线程的私有数据、寄存器等不共享的数据。
c>中断上下文切换
- 为了快速响应硬件的事件,中断处理会打断进程的正常调度和执行,转而调用中断处理程序,响应设备事件。而在打断其他进程时,就需要将进程当前的状态保存起来,这样在中断结束后,进程仍然可以从原来的状态恢复运行
- 与进程上下文切换不同,中断上下文切换并不涉及进程的用户态。所以,即便中断过程打断了一个正处在用户态的进程,也不需要保存和恢复这个进程的虚拟内存、全局变量等用户态资源。中断上下文,其实只包括内核态中断服务程序执行所必需的状态,包括CPU寄存器、内核堆栈、硬件中断参数等
3,CPU上下文切换实战
a>vmstat
- cs(context switch)是每秒上下文切换的次数
- in(interrupt)是每秒中断的次数
- r(Running or Runnable)是就绪队列的长度,也就是正在运行和等待的CPU的进程数‘
- b(Blocked)是处于不可中断睡眠状态的进程数
b>pidstat
vmstat只给出了系统总体的上下文切换情况,要想查看每个进程的详细情况,就需要使用我们pidstat。加上-w选项,则可以查看每个进程上下文切换的情况
- cswch(voluntary context switches),每秒自愿上下文切换次数。指进程无法获取所需要资源,导致的上下文切换。比如:I/O、内存等系统资源不足时,就会发生自愿上下文切换。
- nvcswch(non voluntary context switches),每秒非自愿上下文切换。指进程由于时间片已到等原因,被系统强制调度,进程发生的上下文切换。比如:大量进程都在争抢CPU时,就容易发生非自愿上下文切换。
c>案例实操
查看系统的上下文切换次数
采用sysbench进行压测
再次查看vmstat
发现cs列的上下文切换数量从之前的35骤然上升到了139万多。同时,r列:就绪队列的长度为8,远超CPU的个数2,所以判定有大量的CPU竞争;us(user)和sy(system)列:这两列的CPU使用率加起来上升到了100%,其中系统CPU使用率,也就是sy列高达84%,说明CPU主要是被内核占用了;in列:中断次数也上升到1万左右,说明中断处理也是个潜在的问题。综合这几个指标,系统的就绪队列过长,也就是正在运行和等待CPU的进程数过多,导致大量的上下文切换,而上下文切换又导致系统的CPU的占用率升高。
采用pidstat分析
- CPU使用率升高果然是sysbench导致的,已达100%
- 非自愿上下文切换最高的为pidstat,自愿上下文切换频率最高的线程为kworker和sshd
- 问题:pidstat输出的上线文切换明显小于vmstat输出的上下文切换。采用man pidstat 发现,pidstat默认显示进程的指标数据,加上-t参数后,才会输出线程指标
结合两次的pidstat可以看出,sysbench(主线程)的上下文切换次数看起来并不太多,但它的子线程的上下文切换次数却很多。
采用watch观察interrupts中断
观察发现,变化速度最快的是重调度中断(RES),表示唤醒空闲状态的CPU来调度新的任务运行。这是多处理器系统(SMP)中,调度器用来分散任务到不同CPU的机制,通常也被称为处理器间中断(Inter-Processor Interrupts, IPI)。
d>总结
如果系统的上下文切换次数比较稳定,那么从数百到一万内,都应该算是正常的。当上下文切换次数超过一万次,或者切换次数出现数量级的增长时,都很可能已经出现了性能问题:
- 自愿上下文切换变多,说明进程都在等待资源,有可能发生了I/O等其他问题
- 非自愿上下文切换变多,说明进程都在被强制调度,也就是都在争抢CPU,说明CPU的确成了瓶颈
- 中断次数变多了,说明CPU被中断处理程序占用,需要查看/proc/interrupts文件来分析具体的中断类型
Linux性能优化实战(一)的更多相关文章
- Linux性能优化实战学习笔记:第四十五讲
一.上节回顾 专栏更新至今,四大基础模块的最后一个模块——网络篇,我们就已经学完了.很开心你还没有掉队,仍然在积极学习思考和实践操作,热情地留言和互动.还有不少同学分享了在实际生产环境中,碰到各种性能 ...
- 《Linux 性能优化实战—倪朋飞 》学习笔记 CPU 篇
平均负载 指单位时间内,系统处于可运行状态和不可中断状态的平均进程数,即平均活跃进程数 可运行状态:正在使用CPU或者正在等待CPU 的进程,也就是我们常用 ps 命令看到的,处于 R 状态 (Run ...
- Linux性能优化实战学习笔记:第三十一讲
一.上节回顾 上一节,我们一起回顾了常见的文件系统和磁盘 I/O 性能指标,梳理了核心的 I/O 性能观测工具,最后还总结了快速分析 I/O 性能问题的思路. 虽然 I/O 的性能指标很多,相应的性能 ...
- Linux性能优化实战学习笔记:第三十二讲
一.上节总结 专栏更新至今,四大基础模块的第三个模块——文件系统和磁盘 I/O 篇,我们就已经学完了.很开心你还没有掉队,仍然在积极学习思考和实践操作,并且热情地留言与讨论. 今天是性能优化的第四期. ...
- Linux性能优化实战学习笔记:第三十六讲
一.上节总结回顾 上一节,我们回顾了经典的 C10K 和 C1000K 问题.简单回顾一下,C10K 是指如何单机同时处理 1 万个请求(并发连接 1 万)的问题,而 C1000K 则是单机支持处理 ...
- Linux性能优化实战学习笔记:第四十三讲
一.上节回顾 上一节,我们了解了 NAT(网络地址转换)的原理,学会了如何排查 NAT 带来的性能问题,最后还总结了 NAT 性能优化的基本思路.我先带你简单回顾一下. NAT 基于 Linux 内核 ...
- Linux性能优化实战学习笔记:第四十四讲
一.上节回顾 上一节,我们学了网络性能优化的几个思路,我先带你简单复习一下. 在优化网络的性能时,你可以结合 Linux 系统的网络协议栈和网络收发流程,然后从应用程序.套接字.传输层.网络层再到链路 ...
- Linux性能优化实战学习笔记:第五十二讲
一.上节回顾 上一节,我们一起学习了怎么使用动态追踪来观察应用程序和内核的行为.先简单来回顾一下.所谓动态追踪,就是在系统或者应用程序还在正常运行的时候,通过内核中提供的探针,来动态追踪它们的行为,从 ...
- Linux性能优化实战学习笔记:第五十五讲
一.上节回顾 上一节,我们一起学习了,应用程序监控的基本思路,先简单回顾一下.应用程序的监控,可以分为指标监控和日志监控两大块. 指标监控,主要是对一定时间段内的性能指标进行测量,然后再通过时间序列的 ...
随机推荐
- 第十五个知识点:RSA-OAEP和ECIES的密钥生成,加密和解密
第十五个知识点:RSA-OAEP和ECIES的密钥生成,加密和解密 1.RSA-OAEP RSA-OAEP是RSA加密方案和OAEP填充方案的同时使用.现实世界中它们同时使用.(这里介绍的只是&quo ...
- A Primer on Domain Adaptation Theory and Applications
目录 概 主要内容 符号说明 Prior shift Covariate shift KMM Concept shift Subspace mapping Wasserstein distance 应 ...
- Eclipse控制台Console使用说明
1.说明 本文详细介绍Eclipse控制台Console使用说明, 调试时通过控制台查看日志, 有时候日志太多会找不到上面的日志, 有时候几个控制台会不受控制的弹出, 那么请参考本文, 通过调整Ecl ...
- C# double类型精度丢失问题
我们先看一段代码,可以在控制台程序中执行看看结果 { double d = 500; double d1 = 233.84; double d2 = d - d1; //d2=266.15999999 ...
- MongoDB分片设计
#### 如何做好分片集群 * 合理的架构 * 是否需要分片? * 要分多少片? * 数据分布规则? * 正确的姿势 * 选择需要分片的表 * 选择正确的片键 * 使用合适的均衡策略 * 足够的资源 ...
- python appium自动化报“Encountered internal error running command: UnknownError: An unknown server-side error occurred while processing the command. Original error: Could not proxy command to remote server
运行app自动化代码时报"Encountered internal error running command: UnknownError: An unknown server-side e ...
- win10系统微软账号登陆错误报错误码0x80190001
https://blog.csdn.net/u012878537/article/details/91353248 使用onenote同步的时候报出这样的错误. 知道问题出在了哪里,就容易解决了不是. ...
- js 关于replace() 的使用心得
1.前言 我想把一段话 let a = "抱歉,您当前的主治医生有紧急情况不得不下班,您的预约将由<br>医生:里斯<br>为您就诊,<br>诊室位置:门 ...
- jquery 的 ajax 传输 数组 ,但后台无法获取的 原因 与 解决 办法
1.前言 js传输数组到服务器 ,controller无法解析 ,打印结果是 null 2.原因 jQuery会调用jQuery.param序列化参数,源码是 jQuery.param( obj, t ...
- Zookeeper介绍一
Zookeeper是什么 ZooKeeper是一个开放源码的分布式协调服务,它是集群的管理者,监视着集群中各个节点的状态根据节点提交的反馈进行下一步合理操作.最终,将简单易用的接口和性能高效.功能稳定 ...