在Linux下做性能分析1:基本模型

news2024/12/23 0:02:49

==介绍==

本Blog开始介绍一下在Linux分析性能瓶颈的基本方法。主要围绕一个基本的分析模型,介绍perf和ftrace的使用技巧,然后东一扒子,西一扒子,逮到什么说什么,也不一定会严谨。主要是把这个领域的一些思路和技巧串起来。如果读者来讨论得多,我们就讨论深入一点,如果讨论得少,那就当作一个提纲给我做一些对外交流用吧。

==基本模型==

我们需要有一套完整的方法来发现系统的瓶颈。“瓶颈”这个概念,来自业务目标,不考虑业务目标就没有“瓶颈”这个说法。从业务目标角度,通常我们的瓶颈出现在业务的通量(Throughput)和时延(Latency)两个问题上。(手机等领域常常还会考虑功耗这个要素,但那个需要另外的模型,这里暂时忽略)

比如一个MySQL数据库,你从其他机器上对它发请求,每秒它能处理10万个请求,这个就是通量性能,每个请求的反应时间是0.5ms,这个就是时延性能。

通量和时延是相互相承的两个量,当通量达到系统上限,时延就会大幅提高。我们从下面这个例子开始来看这个模型(图1):

请求从客户端发到计算机上,花t1的时间,用t2的时间完成计算,然后用t3的时间把结果送回到客户端,这个时延是t1+t2+t3,如果我们在t3发过来后,发下一个请求,这样系统的通量就是1/(t1+t2+t3)。

当然,现实中我们不可能使用这样的方法来处理业务请求,这样处理通量肯定是很低的。因为t2和t1/t3作用在两个不同的运行部件上,完全没有必要让他们串行(在同一个会话中有必要,但整体上没有必要。其原理就是CPU流水线)。所以这个模型应该这样来实现(图2):

t2变成一个队列的处理,这样时延还是会等于t1+t2+t3,但t2的含义变了。只要调度能平衡,而且认为通讯管道的流量无限,通量可以达到1/t2(和CPU流水线中,一个节拍可以执行一条指令的原理相同)。1/t2是CPU清队列库存的速度,数据无限地供给到队列上,如果瞬时队列的长度是len,CPU处理一个包的时间是ti,t2=len*ti,如果请求无限上升,len就会越来越长,时延就会变大,所以,通常我们对队列进行流控,流控有很多方法,反压丢包都可以,但最终,当系统进入稳态的时候,队列的长度就会维持在一个稳态,这时的t2就是可以被计算的了。

对于上面这样一个简单模型,如果CPU占用率没有到100%,时延会稳定在len*ti。len其实就等于接收线程(或者中断)一次收入的请求数。但如果CPU达到100%,队列的长度就无限增加,时延也会跟着无限增加。所以我们前面说,当通量达到上限的时候,时延会无限增加,直到发生流控。

现代CPU是一个多核多部件系统,这种队列关系在整个系统中会变得非常复杂,比如,它有可能是这样的(图3):

虽然很多系统看起来不是这样一个接一个队列的模型,但其实如果你只考虑主业务流,几乎大部分情形都是这样的

对这样的系统,我们仍有如下结论:系统的时延等于路径上所有队列的len[i]*t[i]的和。其实你会发现,这个模型和前一个简单模型本质上并没有区别。只是原来的原则作用在了所有的队列上。

也就是说:如果CPU没有占满,队列也没有达到流控,则时延会稳定在len[i]*t[i]上。我们只要保证输入短可以供数据到系统中即可

这个结论为我们的性能优化提供了依据。就是说,我们可以先看CPU是否满载,满载就优化CPU,没有满载就找流控点,通过流控点调整时延和通量就可以了。

在多核的情况下,CPU无法满载还会有一个原因,就是业务线程没有办法在多个CPU上展开,这需要通过增加处理线程来实现。

==全系统的线程模型==

我们一般看系统是从“模块”的角度来看的,但看系统的性能模型,我们是从线程的角度来看的。

这里的线程是广义线程,表示所有CPU可以调度以使用自己的执行能力的实体,包括一般意义的线程,中断,signal_handler等。

好比前面的MySQL的模型,请求从网卡上发送过来。首先是中断向量收到包请求,然后是softirq收包,调用napi的接口来收包,比如napi_schedule。这时调用进入网卡框架层了,但线程上下文还是没有变,napi_schedule回过头调用网卡的polling函数,网卡收包,通过napi_skb_finish()一类的函数向IP层送包,然后顺着比如netif_receive_skb_internal->__netif_receive_skb->__netif_receive_skb_core->deliver_skb->...这样的路径一路进去到某种类型的socket buffer中,这个过程跨越多个模块,跨越多个协议栈的层,甚至在极端情况下可以跨越内核态和用户态。但我们仍认为是一个线程搬移,是softirq线程把网卡上的buffer,搬移到CPU socket buffer的一个过程。调整网卡和socket buffer之间的大小,流控时间,部署给这些队列的线程的数目和调度时间,就可以调整好整个系统的性能。

从线程模型上看性能,处理模型就会比较简单:我们如果希望提高一个队列清库存的效率,只要增加在这个队列上的搬移线程,或者提高部署在上面的线程(实际上是CPU核)的数量,就可以平衡它的流控时间。如果我们能平衡所有队列的效率和长度,我们就比较容易控制整个系统的通量和时延了。

这其中当然还会涉及很多细节的设计技巧,但大方向是这个。

在线程这个问题上,最后要补充几句:线程是为了驱动系统的运行。不少新手很容易把线程和模块的概念搞到一起,甚至给每个模块配备一个线程。这是不少系统调度性能差的原因。初学者应该要时刻提醒自己,线程和模块是两个独立的,正交的概念,是不应该绑定的。模块是为了实现上的内聚,而线程是为了:

1. 把计算压力分布到多个核上

2. 匹配不同执行流程的速率

3. 当线程的执行流程中有同步IO的时候,增加线程以便减少在同步IO上的等待时间(本质上是增加流水线层次提升执行部件的同步效率)

后面我们谈具体的优化技巧的时候我们会重新提到线程的这些效果。

==一般操作方法==

所以,当我们遭遇一个通量性能瓶颈的时候,我们通常分三步来发现瓶颈的位置:

1. CPU占用率是否已经满了,这个用top就可以看到,比如下面这个例子:

有两个CPU的idle为0,另两个基本上都是接近100%的idle,我们基于这个就可以决定我们下一步的分析方向是什么了。

如果CPU没有满,有三种可能:

1.1 某个队列提早流控了。我们通过查看每个独立队列的统计来寻找这些流控的位置,决定是否需要提升队列长度来修复这种流控。例如,我们常常用ifconfig来观察网卡是否有丢包:

wlan0     Link encap:以太网  硬件地址 7c:7a:91:xx:xx:xx  
          inet 地址:192.168.0.103  广播:192.168.0.255  掩码:255.255.255.0
          inet6 地址: fe80::7e7a:91ff:fefe:5a1a/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  跃点数:1
          接收数据包:113832 错误:0 丢弃:0 过载:0 帧数:0
          发送数据包:81183 错误:0 丢弃:0 过载:0 载波:0
          碰撞:0 发送队列长度:1000 
          接收字节:47850861 (47.8 MB)  发送字节:18914031 (18.9 MB)

在高速网卡场景中,我们常常要修改/proc/sys中的网络参数保证收包缓冲区足够处理一波netpolling的冲击。

我们自己写业务程序的时候,也应该对各个队列的水线,丢包数等信息进行统计,这样有助于我们快速发现队列的问题。

1.2 调度没有充分展开,比如你只有一个线程,而你其实有16个核,这样就算其他核闲着,你也不能怎么样。这是需要想办法把业务hash展开到多个核上处理。上面那个top的结果就是这种情形。

1.3 配套队列的线程有IO空洞,要通过异步设计把空洞填掉,或者通过在这个队列上使用多个线程把空洞修掉。具体的原理,后面谈分析方法的时候再深入介绍。

2. 如果CPU占用率已经占满了,观察CPU的时间是否花在业务进程上,如果不是,分析产生这种问题的原因。Linux的perf工具常常可以提供良好的分析,比如这样:

这里例子中的CPU占用率已经全部占满了。但时间中只有15.43%落在主业务流程上,下面有大量的时间花在了锁和调度上。如果我们简单修改一下队列模式,我们就可以把这个占用率提升到23.39%:

当我们发现比如schedule调度特别频繁的时候,我们可以通过ftrace观察每次切换的原因,比如下面这样:

你可以看到业务线程执行3个ns就直接切换为Idle了,我们可以在业务线程上加mark看具体是什么流程导致这个切换的(如果系统真的忙,任何线程都应该用完自己的时间片,否则就是有额外的问题引起额外的代价了)

3. 如果CPU的时间确实都已经在处理业务的,剩下的问题就是看CPU执行系统是否被充分利用(比如基于例如Top Down模型分析系统CPU的执行部件是否被充分利用) 或者软件算法是否可以优化了。这个也可以通过perf和ftrace组合功能来实现。

在后面几篇博文中,我们会逐一看看Linux的perf和ftrace功能如何对这些分析提供技术支持的。


==关于流控==

流控是个很复杂的问题,这里没有准备展开,但需要补充几个值得考量的问题。

第一,流控应该出现在队列链的最前面,而不是在队列的中间。因为即使你在中间丢包了,前面几个队列已经浪费CPU时间在这些无效的包上了,这样的流控很低效。所以,中间的队列,只要可能,一般不设置自身的流控

第二,在有流控的系统上,需要注意一种很常见的陷阱:就是队列过长,导致最新的包被排到很后才处理,等完成整个系统的处理的时候,这个包已经被请求方判断超时了。这种情况会导致大量的失效包。所以,流控的开始时间要首先于每个包的超时时间。


==总结==

性能分析应该是一个有针对性的工作,我们大部分情况都不可能通过“调整这个参数看看结果,再调整调整那个参数看一个结果,然后寄望于运气。我们首先必须从一开始就建立系统的运行模型,并有意识地通过程序本身的统计以及系统的统计,对程序进行profiling,并针对性地解决问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/754873.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Electron + vue 搭建桌面客户端

下载Electron 压缩包,放到本地 Electron 压缩包下载地址 cd ~/Library/Caches/electron

Duilib 父窗口无效化和消息传递

文章目录 1、父窗口无效化和消息传递2、EnableWindow()和SetFocus()的含义和用法 1、父窗口无效化和消息传递 当使用duillib界面库时,我们往往需要建立多个窗口,子窗口和父窗口之间有一定的逻辑需要,比如当子窗口弹出时,让父窗口…

2022 Robocom CAIP 国赛 第二题

原题链接: PTA | 程序设计类实验辅助教学平台 题面: 副本是游戏里的一个特色玩法,主要为玩家带来装备、道具、游戏资源的产出,满足玩家的游戏进程。 在 MMORPG《最终幻想14》里,有一个攻略人数最大达到 48 人的副本“…

Office如何通过VSTO进行EXCEL插件开发?

文章目录 0.引言1.工具准备2.EXCEL外接程序创建和生成3.外接程序生成并使用 0.引言 VSTO(Visual Studio Tools for Office )是VBA的替代,是一套用于创建自定义Office应用程序的Visual Studio工具包。VSTO可以用Visual Basic 或者Visual C#扩展…

SPEC CPU 2006 在 CentOS 5.0 x86_64 古老系统测试【3】静态编译 invalid run

上篇 SPEC CPU 2006 在 CentOS 5.0 x86_64 古老系统测试【2】_hkNaruto的博客-CSDN博客 修改gcc41.cfg,全部添加上-static 测试指令 runspec -c gcc41.cfg -T all -n 3 -r 1 -I -i ref all 结果:正常运行并生成报告 invalid run Invalid SPEC CFP2006…

【算法基础】2.1栈和队列(单调栈和单调队列)

文章目录 例题3302. 表达式求值(栈的应用)😭😭😭😭😭830. 单调栈知识点解法 154. 滑动窗口 (单调队列)知识点解法 相关链接 & 相关题目 例题 3302. 表达式求值&…

在进行自动化测试,遇到验证码的问题,怎么办?

1.找开发去掉验证码或者使用万能验证码 2.使用OCR自动识别 使用OCR自动化识别,一般识别率不是太高,处理一般简单验证码还是没问题 这里使用的是Tesseract-OCR,下载地址:https://github.com/A9T9/Free-Ocr-Windows-Desktop/releases 怎么使…

linux centos7 静默安装 oracle 11g,【亲测有效】,包含远程连接、提供安装包

Centos7 安装oracle11g 环境准备 操作系统 centos7 oracle版本 oracle11g 终端软件 MobaXterm 192.168.46.61 oracleMaster 安装包 网盘地址 一、安装前准备 1、关闭selinux [rootoracleMaster ~]# vim /etc/selinux/config修改 SELINUX 为 disabled # This file controls …

网络安全(黑客技术)自学

引言 ✈️网络安全,顾名思义,无安全,不网络。现如今,安全行业飞速发展,我们呼吁专业化的 就职人员 与 大学生 ,而你,认为自己有资格当黑客吗? ✒️本文面向所有信息安全领域的初学者…

希尔排序

希尔排序 排序步骤 1、分组,以任意长度进行分组(这个长度我们称作增量gap);通常以总长度的一半这个数为依据进行分组,每间隔 gap 个数即为一组 2、组内排序;组内使用插入排序法进行排序 3、重新设置间隔…

Wi-Fi 相关概念

Wi-Fi 相关概念 802.11 Wi-Fi 标准及其含义频宽 和 带宽 的概念20MHz与40MHz的区别2.4G 频段2.4G的频道编号和中心频率 5G WiFi 频段中国开放的的5G WiFi频段:5G的频道编号和中心频率: 802.11历史进程一、802.11重要发展二、802.11协议族 参考 802.11 Wi…

阿里云 OSS 静态网站托管

本文节选自我的博客:阿里云 OSS 静态网站托管 💖 作者简介:大家好,我是MilesChen,偏前端的全栈开发者。📝 CSDN主页:爱吃糖的猫🔥📣 我的博客:爱吃糖的猫&…

云计算的学习(六)

六、云计算的发展趋势 1.云计算相关领域介绍 1.1物联网 物联网来源于互联网,是万物互联的结果,是人和物、物和物之间产生通信和交互。 物联网主要技术: RFID技术(射频识别技术)传感器技术嵌入式系统技术 1.2大数据…

SpringBoot+actuator和admin-UI实现监控中心

使用SpringBoot很久了&#xff0c;但是很少使用到SpringBoot的查看和监控&#xff0c;将来八成也不会用到&#xff0c;万一有机会用到呢&#xff1f;所以记录一下以前学习SpringBootactuator和adminUI实现监控中心的方式 Springboot的版本2.0.x <parent><groupId>…

在Linux下做性能分析2:ftrace

介绍 在我们进一步介绍更多模型分析技巧前&#xff0c;我们先要对基本工具有一些了解。这一篇先介绍ftrace的基本用法。 ftrace在内核的Documentation目录下已经有文档了&#xff0c;我这里不是要对那个文档进行翻译&#xff0c;而是要说明这个工具的设计理念和使用策略。细节…

H3C-Cloud Lab实验-链路聚合实验

实验拓扑图&#xff1a; 实验需求&#xff1a; 1、按照图示配置PC3和PC4的IP地址 2、在SW1和SW2的两条直连链路上配置链路聚合&#xff0c;实现链路冗余&#xff0c;并可以增加传输带宽 3、SW1和SW2之间的直连链路要配置为Trunk类型&#xff0c;允许所有vlan通过 4、中断SW…

基于JavaSwing+Mysql的仓库销售管理系统

点击以下链接获取源码&#xff1a; https://download.csdn.net/download/qq_64505944/88049275 JDK1.8 MySQL5.7 功能&#xff1a;管理员与员工两个角色登录&#xff0c;基础数据查找&#xff0c;仓库查找&#xff0c;增删改查仓库信息、商品等 源码数据库文件配置文件课程设…

java单元测试(调试)

文章目录 测试分类JUnit单元测试介绍引入本地JUnit.jar编写和运行Test单元测试方法设置执行JUnit用例时支持控制台输入10.6.6 定义test测试方法模板 测试分类 **黑盒测试&#xff1a;**不需要写代码&#xff0c;给输入值&#xff0c;看程序是否能够输出期望的值。 **白盒测试…

LangChain + ChatGLM2-6B 搭建个人专属知识库

之前教过大家利用 langchain ChatGLM-6B 实现个人专属知识库&#xff0c;非常简单易上手。最近&#xff0c;智谱 AI 研发团队又推出了 ChatGLM 系列的新模型 ChatGLM2-6B&#xff0c;是开源中英双语对话模型 ChatGLM-6B 的第二代版本&#xff0c;性能更强悍。 树先生之所以现…

GitUI汉化

1.下载汉化文件 下载地址 备用下载地址 https://files.cnblogs.com/files/chenghu/git-gui-zh-master.zip https://files.cnblogs.com/files/chenghu/git-gui-zh-master.zip 2.找到git安装路径 C:\Program Files\Git\mingw64\share\git-gui\lib 3.解压出1下载的文件 复制粘…