【系列三:DevKit性能分析工具】第二讲:手把手带你找出程序中加锁范围不合理的代码【玩转华为云】

举报
炒香菇的书呆子 发表于 2022/11/30 21:09:05 2022/11/30
【摘要】 这堂课的目标是通过这堂课的学习,大家可以掌握基本的系统调优知识,掌握如何使用调优工具对一个程序进行性能分析。这堂课主要分为四个部分,第一个部分就是如何学习性能优化。第二个部分是安装 DEV key 的性能分析工具的步骤。第三个部分就是调优前的一些准备工作,以及第四部分也是我们今天的最重要的一部分。如何对程序进行性能分析首先我们来讲讲如何学习性能优化讲到性能优化,那性能指标肯定是跑不掉的。那高并发和

这堂课是鲲鹏DevKit的性能分析工具的实操课。

image-20220721001724320

这堂课的目标是通过这堂课的学习,大家可以掌握基本的系统调优知识,掌握如何使用调优工具对一个程序进行性能分析。这堂课主要分为四个部分,第一个部分就是如何学习性能优化。第二个部分是安装 DEV key 的性能分析工具的步骤。第三个部分就是调优前的一些准备工作,以及第四部分也是我们今天的最重要的一部分。如何对程序进行性能分析首先我们来讲讲如何学习性能优化讲到性能优化,那性能指标肯定是跑不掉的。那高并发和响应快一定是最先出现在咱们脑海中的两个词,而他们也正对应着咱们性能优化的两个核心指标,吞吐和延时。所以高吞吐和低延时一定是性能优化所追求的。

image-20220721001739944这两个指标是从应用负载的视角来考察性能的,直接影响了产品终端的用户体验。而与之他跟他们对应的,就是从系统资源的视角出发的一些指标,比如说资源的使用率、饱和度等等。想要学习好性能分析和优化,建立整体的系统性能的全局观是最核心的。我也总结了有三点,那首先第一点我们要理解最基本的几个系统知识原理,比如说操作系统四大件, CPU 内存、存储 IO 网络 IO 就这四个维度的一些基本原理知识我们一定要去掌握。还有一些最常用的数据指标我们也要去掌握学习,要不然就算给我们给了我们一份很明确的指出有什么问题的一份报告,我们不知道里面各个指标的含义,那有什么用对不对?我们一定要最基本的原理知识一定要我掌握起来。第二点就是要掌握必要的性能工具,掌握一款好的工具可以帮我们节省很多时间,这个就不用再说了。第三点也是我认为也是很重要的一个点,就是说我们要一定要去进行实操,不断的通过实际的场景来对我们自己去增长各种经验。就说就算我们掌握了再好的性能,优化了一些原理,我们对一些底层知识掌握的再好,如果说我们不去实际去对真实的场景进行一些定位对吧,或者说实践的话,我们的性能优化的知识肯定是处在一个很浅的一个层面的,所以实操是很重要的,我们不要当纸上谈兵的人。

image-20220721001751240嗯接下来来带大家看一张图。这张图大家应该看到过,有些人也没看到过他就是我们性能领域的大师布伦丹格雷格的一个大作。布鲁丹格雷格他是动态追踪工具低 trace 的作者,而且他还开发了许许多多的其他的性能工具给大家使用。
啊这张图是一张很著名的图。 1 首先它看起来很漂亮对吧,很简洁啊。第二,它的作用非常大。怎么说呢,它就是以操作系统为维度,把里面各个组件给排列出来,并且注明了如果说想要采集每个组件中的相关数据,都可以用到哪些插件或者哪些工具,就比如说我想采集 TCP 和 UDP 相关的一些数据,那么我们就可以用这个 unstat 这个工具,或者说用 TCP live 等工具去进行数据采集。就这张图给了我们一个很好的指导作用。但是从这张图我们也可以了解到对吧?如果说我们真的要把性能优化掌握得很好,我们要学习的东西或者说要使用工具有很多很多。那么今天的主角咱们的 devkey 的性能分析工具其实就是可以让大家可以节省很多时间,能快速的来进入一个性能优化,可以,而且学习成本也是相对较低的。接下来我们讲讲安装 DEV key 的性能分析工具的一些步骤。

image-20220721001807274安装我们新的分析工具很简单,首先去下载对应的安装包,然后目前我们支持了三种模式,一种就是浏览器的模式,就是安装好后我们可以直接通过浏览器去使用我们的工具。另外一种就是我们也提供了 ID 开发工具的模式,因为我们作为开发对吧,ID肯定是离不开的。那么我们现在目前就支持了 vs code 和 in 泰链接两种开发工具,有我们可以使用他们对应的插件来进入我们的性能分析工具来进行使用。

image-20220721001822351安装好我们工具库也是比较简单的,因为我们提供了一些很详细的一个安装指导列出了我们各个步骤是怎么做。列出了一些常见的错误,常场景,我们都可以通过我们的指导去指导如何解决第三部分就是调优前的一些准备工作。首先我们安装好工具后,并且第一次使用工具的后时候,他会让我们初始化一下我们管理员账号的一个密码。初始化好后我们就可以直接登录到我们的性能分析工具进行使用了。接下来我们就不再对着我们的这个文档讲了,我们就直接进入一个实操的环节。首先我这边已经安装好性能分析工具了,并且也把管理员的一个密码初始化好了,我们直接登录进去管理员的账号密码好登录进去后我们就来到了我们鲲鹏性能分析工具的一个主页。对吧。大家可以看到其实他是分为四个子工具的,这里我简单的介绍一下。首先就是基础分析里有一个调优助手。调优助手工具主要是通过系统化的组织和分析,性能指标、热点函数、系统配置等信息,就形成系统资源的一个消耗链条,引导用户分析性能瓶颈,并给出具化建议和操作指导,实现快速调优。一般我们什么时候使用调污助手呢?就说我们往往在一个全新的环境,或者说一个平台,或者说我们的一个集群里对吧,我们就可以。刚开始的话我们就可以通过我们这个调助手来做一个全方位的一个摸底,看看我们这个环进对吧,服务器的一些配置合不合理等等之类的。在高级分析的话主要有三个工具。第一个工具就是系统性能分析工具,就是我们今天后面要着重介绍的,他主要是基于咱们操作系统四大件这几个维度去做数据的采集,然后做一些数据的分析。第二个工具就是 Java 性能分析工具,它主要是针对我们的 Java 程序,还有 Java 虚拟机层面做一些数据的采集和分析。第三个就是系统诊断。这个工具通过分析咱们系统运行的指标,识别异常点,比如说内存泄露、内存越界还有网络丢包等情况,我们都可以通过系统诊断工具去做一些数据的采集和分析,而且这个工具也会给出对应的优化建议。同时我们也支持了对系统进行压测,比如网络 IO 方面的压测,以磁以及磁盘 IO 方面的压测,也有对应的功能给大家使用。

image-20220721001846020

接下来我们就只直接来讲讲我们的系统性能分析工具的一些相关功能来我们进去现在我们就来到了我们系统性能分析工具的一个主页面,页面比较简单。那首先第一步,如果说想要使用里面的功能,我们需要创建一个工程,创建工程也比较简单。工程名称我们起一个来,我们就起一个工程,简单一点。第二个就是选择场景,目前的话我们这里提供了五个场景第一个场景也是最常用的就是通用场景,通用场景就是基于操作系统四大件的维度去采集相关的数据,然后进行数据分析。第二个场景就是大数据场景大数据场景的话,我们目前支持了对业内那些使用的比较多的或者比较热的一些大数据组件进行一个定制化的一个数据采集和分析,像hbase 、卡夫卡等等之类的。第三个场景是分布式存储场景,目前我们就是对 safe 这个分布式文件系统做了一些专门的数据采集和分析。

image-20220721001859007第四个场景就是 HPC 场景,我们针对高性能计算这块也是做了一些定制化的数据采集和分析。最后个场景是数据库场景,目前我们支持的数据库有 MySQL 8 和 open 高斯兔这两个版本的数据库,进行一些专门的数据采集。选择号场景后,我们再选择节点节点其实就是说一个节点,它就对应的一个环境或者说一台服务器对吧,就是选择节点,就是说我这个工程它想要采集的程序,它是部署在哪个节点上,就哪个环境上,我们就把对应的节点选择上去就好了。这里是支持多选的,因为我这里只部署了一个节点,所以只能选择一个,然后我们就选择一个通用场景。

image-20220721001906292工程创建好后,下一步就是创建一个任务,这个任务其实它的作用就是对数据进行采集,然后对采集来数据进行分析。任务的创建也是比较简单的。1、首先任务名称,然后任务名称输好后,我们就要选择一个分析对象。分析对象很好理解,它主要是有系统和应用,就是说我们采集的数据只要是针对整个系统的,还是针对某个应用的,我们来根据自己的情况进行选择就行了。然后选择好分析对象后,我们就选择一个分析类型。目前我们这里分为了八个分析类型,我这里就简单的介绍一下八个分析类型分为三组,一个是通用分析通用分析的话第一个就是全景分析,全景分析就是以全局的视角去采集四大件等相关资源的一些数据,然后并进行一个数据分析。还有一个就是进程线程性能分析,只是主要是以进程和线程的维度去采集相关资源的数据。第三个就是热点函数分析热点函数分析就不用说了,主要是针对我们的系统或应用去采集里面的热点函数,并且通过火焰图的方式去展示里面的调用关系。

image-20220721001918556第二个块就是一个系统部件分析。第一个就是微架构分析。微架构分析主要是基于 PMO 事件获取指令在 CPU 流水线上的一个运行情况,快速定位当前应用在 CPU 上的一个性能瓶颈。第二个就是访存分析。那访存分析主要是通过采集缓存和内存的相关的一些事件的数据来进行一个数据的分析。你看我们这边也提供了什么 MIS 事件的分析以及伪共享的一个专项分析第三个就是 IO 分析。 IO 分析主要是针对磁盘 IO 的一些相关操作来采取相应的数据。去看看我们的 IO 有没有性能瓶颈点。

image-20220721001930682第三块就是一个专项分析分析。专项分析主要分为两个功能,第一个就是资源调度分析资源调度分析主要是基于 CPU 的调度事件分析系统资源的一个调度情况。举个例子,如果说我想知道我的程序中各个线程在运行的时候,它被 CPU 调度是呈一个什么状态,或者说是被 CPU 调度是呈一个怎么样的一个节奏的时候,我就会通过这个资源调度分析任务来进行一个采集。

image-20220721001939635还有一个就是所有等索语等待。索语等待其实就是分析所与等待函数的使用情况,他其实主要是从我们各总锁的相关函数为入口点去进行数据的采集和分析。这里讲了八个分析类型,我们就会感到疑惑,那我们到底选哪个分析类型?那去创建任务去数据采集和分析呢?这里就要想想我刚刚前面讲到的就说如果要做性能优化,我们一定要掌握一个全局观。就是说这个其实怎么讲呢?就是说我们在做性能瓶颈点定位的时候,大部分场景下我是不知道我的程序或者系统是出现什么问题的,或者说我也不知道问题点在哪对吧,或者说平台或者更别说集群了。那如果说已经知道的话,那我们就根本不用这种工具去定位了,直接改就行了,是不是直接上,但是我们不知道,那不知道的话我们就要从全局的角度去出发。那如果说知道的话,比如说我已经知道 IO 方面有瓶颈点了,那我们直接用 IO 分析任务就行了呗。对不对?或者是所方面有一点,我们直接通过所有等待分析这个任务去采集数据,看看什么情况了。那如果说我们刚开始是不知道或者说我想看看到底有什么问题的话,我们就可以用通用分析里的相应功能去进行数据的采集和分析。

image-20220721001948689那么首先我们就来创建一个全景分析任务,从全局的视角去看看我们的程序或者说环境有什么问题。在创建任务之前我先去启动我的一个测试程序。我的这个测试程序其实是存在一个问题的,我这不说什么问题,接下来我就通过我们的工具去定位出来这个问题在哪里回去什么样的来创建一个全景分析任务,起名就叫全景分析,前景分析杠1,然后采集时长的话采集 60 秒就够了不用采集那么长,然后直接启动。

image-20220721002004974创建成功后,我们的任务就开始他的一个工作了。这时候我们来我来介绍一下我们工具的一些其他辅助功能。首先就是一个用户管理,我们知道我们创建好安装好我们的工具后,我们就要进行登录对吧?我们会想一个这种工具为什么要进行登录多麻烦。但是其实我们想想我们这个工具针对的就是我们那个公司中的一个定位,就说不是纯给个人用的,个人肯定是能用。但是如果说我们是一个团队,或者说我们是一个大组,对吧,我们有好些开发一块这样的话,如果安装了我们那个分析工具后,大家就可以创建自己的一个账号,然后登录上自己账号,进行一个任务的创建和数据采集。这样的话只要装一个工具,可以大家一块使用。

image-20220721002013730如果说不是这样的话,大家如果说我想做一些数据采集和定位,我得各自安装一下自己本地或者说在服务器上去安装,那很不方便的。我们这边就通过是一个支持多用户一块进行同时采集和分析,而且大家是互不干扰的创建用户也是比较简单。对吧,一个用户名,还有就是必须是得通过管理员去创建用户才行,然后密码去设置一下就行了再一个就是一个节点管理,这个功能没点到我刚刚讲的就是创建工程的时候最后一步要去选择节点对吧,一个节点其实就对应的一个服务器或者说是环境那其实我们现实生活中对吧,真实的征信场景现在都是多节点多台服务器联合操作,或者说集群呐或者说几百几百个节点运作起来的是很正常的。

image-20220721002025873不可能说我是单单服务器对吧,那种场景是有但是不多。这样的话,我们的工具就支持部署远程节点。就是我们不仅可以在我们安装的工具这台环境上去进行数据采集,也可以通过与部署远程节点的方式在我们的另一台环境或服务器上部署,部署起来一个节点。那其实这个节点就对应了一个进程对吧。然后通过进程的话我们去可以发起各种任务去采集数据,然后从而达到这种远程采集数据的一个几一个效果。然后我们这里是通过 SA SA 去的方式去进行一个远程部署节点在安全方面是有保证的,而且我们这里输入口令后也是用完了后就会删除的,不会再进行保留。所以这里侧面讲到了就说部署远程节点的一个要求。就说首先远程的环境要跟我们安装这个性能分析工具的环境网络肯定是要通的。二就是远程环境它是默认支持通过 SSH 去登录的,这里我就不再演示了。我们回来看一下。

image-20220721002034861这时候我们这个全景分析任务已经结束了那首先我们直接点开,我们就会打开我们的全景分析任务的一个任务报告。首先我们会来到总览这个页面有总览页面。首先我们这里在最上面会有一个优化建议的一个地方对吧?如果说我们通过采集出来数据,发现了一些性能瓶颈,我们就会给出对应的优化建议。那比如说这个我们就会发现 CPU 1 的平均利用率较高,而且我们也根据一些数据的类型给出了一个优化建议。这里建议说就是根据我们一个实际场景去打开 CPU 预取这个开关。并且我们会告诉我们的用户这个是否打开这个 CPU 预取它的场景是什么样的?你看就是对于数据比较集中的场景对吧,预取的命中率较高,是否打开,反之就不需要打开。还有整个修改方法也会告诉大家,这样的话我们可以通过优化建议看看是否自己的程序或者系统是否符合这个场景,然后去进行一个调整。

image-20220721002046848然后总览页面主要是下面的一些数据,就是会把我们各个部件的一些基本配置信息给采集出来,供大家展示。你看 CPU 相关的还有一个牛马节点,目前我们这个环境是只有一个牛马节点,它的内存什么情况,还有 new 码节点的距离是什么样对吧,它的一些 new 码平衡的开关有没有开启,还有些内存方面的一些配置,网络方面的一些配置都在里面。我们这个因为是个虚拟机,所以网卡是采集不出来的,但是网口是可以看对吧,它的网口是什么样,它各个配置什么样,还有一些之类的都在里面。我们通过总览我们就是说想看哪个部件的一些配置都可以在里面找到,是十分方便的。第二个 tab 就是一个 PCIe top 信息。首先因为我们是虚拟机环境,所以这个 P 每个 CPU 的 PCIe 的一个结构图我们是查不出来的。如果说是物理机的话,我们就可以把每个 CPU 里的一个 PCIe 的一个架构图以一个树形状的方式可以展示出来。然后接下来就是说我们还可以把 top 10 进程的一个饱和情况也可以展示出来了,我们也可以看看。

image-20220721002055648第三的话就是我们会把硬中断的一个数据列出来对吧,硬中断它的一个在采集期间是什么情况?还有就是说我们会结合硬中断和软中断,把它的一个分布频率通过一个柱状图的形式去把它展示出来,这是以 CPU 的维度去展示出来,去看看各个 CPU 它的一个中断情况是什么样的。

image-20220721002103252接下来我们就来看看我们的全景分析,最重要的一块就是他性能, tab 首先默认会进来这个一个以图表的展示我们各个资源的一个数据是通过时从时间状态是什么样的对吧,我们可以去看一下像这个 CPU 的使用率平均负载内存使用情况是什么样的?来接下来我们把它切到这个表格模式,我们主要就看看表格模式里面的数据,我把它给缩起来,大家看看。

image-20220721002110909首先其实大家很清晰可以看到这里就是以操作系统四大件的维度去展示不同的数据。还有这里就是我额外多了个能耗吗,可以给大家去看一下我们能耗什么样的。那首先我们来看看这个 CPU 这块,这里我们是以 CPU 每个和的 CPU 为维度去展示出来,他在采集期间的各个使用率是什么样的对吧?来我们给他进行一个排序。先,我们以那个用户的使用率排序排起来。这里我们会发现我们可以看到 ACP UE 它的用户态的使用率是最高的,达到 60% 多对吧,你比其他都高很多。排名第二的就是一个 CPU 0 和 30% 多,比 CPU 1 是一类一半的是吧。这个正好跟我们总览页面刚刚给的一个优化建议是对得上的对吧。 CPU 1 的平均利用率较高。然后这里我们就讲讲 CPU 利用率的几个关键的一个数据折。首先就是这个 user 这个其实就是一个用户态的一个 CPU 使用率,二就是这个 CIS 就是一个就是内核态的一个 CPU 使用率。就这两个指标是很关键的。就通过这两个指标我们可以看看就是我们的 CPU 使用率是什么样的。

image-20220721002118685二就是说我们的程序或者系统,他在这段期间大部分是 CPU 他用在了什么地方。像用户态的话,他可能主要是在做我们各个程序,他自己做了一些事情。像内核态的话主要是指内核在做一些操作系统相关的事情。所以我们就通过这两个指标去可以定位一下。二就是一个 IO 对吧,就是我们 CPU 在等待 IO 的时候,它的一个使用率是多少?我们如果说说 IO 的这个 IO wait 很高的话,我们就可以得出一个结论,就 IO 层面存在一个平均点,你想像其他的话就是相对来说就是也可以知道一下,像这个就是硬中断的一个使用率,还有软中断的一个使用率课是多少。

image-20220721002126142如果说在某些场景下,我们发现应用中断和软中断的 CPU 的水率较高,它也是个瓶颈点,因为我们就可以通过各种中断类型去逆推,到底是哪块出现了问题。这也是以如果说我们发现应用的软熔断使用率较高,也可以从这里去出发,这里就什么空闲,我们就不说了。然后我们可以排序。首先这里我们发现 CPO 1 的用户端使用率较高,达到 67% 对吧?那 CPU 0 达到 30% 多,那这两个加起来基本上 100% 了是吧。然后看看内核态的,内核态最高也就 3% 是吧,其实也属于一个正常情况,那 LV 的话也很低,基本上就没有百分之零点几没啥了。还有就 CPU 这块我们会把平均负载给列出来,就是像过去 15 分钟 5 分钟 1 分钟的平均负载是什么样的这里看了一下,平均负载也是很低的。
看完 CPU 方面的,我们看看内存方面,像这里内存的话,也就是把内存各个维度的数据都采集出来,然后给大家看一下。首先就是内存使用率情况,就最最重要的一个指标就是内存使用率的百分比,一般我们就看这个指标,如果说这个指标很大。或者说接近 100% 的话,我们就可以认为这段期间我们那个系统的在内存使用情况是很吃紧的对吧,或者说内存是不是不够用了等等之类的。我们看这个内存使用率,像其他话就是各个维度的一些内存使用情况了,像广东区,catch都在里面,还有一些像一些分页情况也在里面对吧,像这个数据也是看起来是比较正常的是吧,像这些都是0。这里可以说一点就是我们这里你基本上是针对每个指标都有一个比较,直白的说明让大家很可以知道这个指标是干嘛用的就是一个 sweb 情况对吧,它的交换出交换进来是什么样的?这里都会零,说明在这段期间没有进行一个交换内存的一个交换情况。还有一个就是一个我们会把基于 new 码节点去把它的内存各个使用情况给列出来。这里可以稍微讲一下就是 new MA new MA 这个架构是为了帮助我们让跨和使用或者访问内存的时延减少,就是能更高效地去把握内存,尤其是出现跨合的情况。

image-20220721002136877好吧,这里的话因为我们这个环境只有一个节点,但是我们可以去看看里面的关键指标。首先就是这两个 new maforing 和 new MA miss 是最重相对来说最重要的指标。怎么说 new maforing 它的意思就是说本来我这次内存访问应该是从 new MA note 0 这个 new MA 节点上去访问的,但是因为某些情况我没有访问到对吧,所以我要不得不去其他节点去访问了,所以她 new one for you 也很直接,就是去其他的了去我要去国外了对吧,买东西中国买不到,我要去国外牛妈 miss 就是跟牛妈夫人相对应的对吧,我不应该在这个节点访问的,但是因为某些原因,我只能在这个节点去把握内存了,那一样的对不对?我本来应该买进口的,但是因为原因我不得不买本地的了对吧?所以说这两个指标就体现了说我们这个跨牛马访问的一个情况。
如果说这个 new Marine 和 new MIS 这两个指边指标较高的话就可以说明跨 new 访问的情况有或者说比较严重,这是我们不想看到的,因为一跨 new 访问的话内存的一个时延就会较高,但从这里我们会看出都是 0 对吧,所以在采集期间没有出现跨尼玛访问的情况。
第三块就是这个存储 IO 存 IO 其实就是把各个一个存储块都列出来,读写速率是什么样,TPS怎么样这里最重要的指标就是这个 wait 对吧,他的磁盘 IO 他的一个等待情况是什么样的,号是什么样的?如果我们发现这个位置很高,我相对来说挺高的对吧,这里的单位是毫秒,或者说是秒级别的,或者说十几秒是一个不重要的现象。
再就是一个就是这个使用率也是一个很重要的一个指标。就是往往的话我们可以先看这个使用率对吧。如果我们发现我们这个磁盘使用率很大了 100% 了,那说明磁盘实景了,告警了是有瓶颈的,是不是磁盘不够用对不对?所以说这个磁盘使用率还有这个 wait 这两个指标是我们最要优先关注的,尤其是这个磁盘使用率是最能反映一个情况的对吧?然后这个位的话还得去结合一下我们具体的情况,看看是不是符合正常的,还是说只是一个瞬时状态对不对?并不是一个长期的状态,像其他的指标的话我们也可以去相应的去看一下结合起来看接下来就是一个网络。

image-20220721002147997网络这块其实就是以我们每个网卡为维度,去把它的一个读写的 PPS 然后展示出来。这是一个读的 PPS 是多少,写的 PPS 多少,还有就是每秒的读写大小是多少,都给列出来。如果说我们发现某个网卡它的一个 PPS PPS 很高,而且它的服务或者写的每秒的字节大小也很高,那我们就得看看它到底有没有一个瓶颈点了。这里可以大给大家说,并不说这个数据大它就有瓶颈点,而是我们要去综合考虑一下。如果说像网络传输很,这些数据都很大,但是他也没有出现一些问题,就是网络传输多的话,她的网络中断也会相应较多。那我们可以结合一下看看对应的一些软硬中断,它的一些使用率是什么样,要结合起来看并不说数据指标大,我们只能说他的这块是有相应的动作在里面的。
最后一块就是能耗对吧,就是仅供大家去看一下了,因为我们这个虚拟机它能耗没有采出来,我们这里就不用关注它了。行。那么通过这个全景分析,我们目前得出一个结论就是我们 CPU 1 的用户态使用率较高,还有就是 CPU 0 它的相对来说用户态使用率也比较高,那其他 CPU 都是比较低的,像内核态的,还有其他的内存方面的,存储的,网络方面比较都是相对正常的基本上是通过这份数据我没有看出什么问题。
那接下来我们就来创建第二个任务。我们从全局发现,这个 CPU 方面是有一定的一个压力的对吧?我们看看具体是哪个进程或县城是共线的对吧?那我们就可以创建第二个任务,就是通用分析里的进程线程性能分析任务来我们直接取个名字,叫 PT 杠1,然后采集时长采集 1 分钟。然后这里采集类型就默认全选,用它全选就行。然后直接走起。然后再在这个任务执行期间,我们来介绍一下一些小功能。
首先就是说我们在创建任务的时候发现这里有一个导入模板,这里怎么空的?这个导读模板是干嘛呢?就是说我们往往我们在做性能分析的时候是一个周期性的,是一个持续性的动作。对吧?往往说我这个月可能去采集这些数据,下个月我还会采集。那我可能我们创建的任务都是相似的或者说一模一样的,这样的话我们就可以通过这个模板的功能去创建一个任务模板对吧。我们举个例子叫模板任务一对吧。这个模板我都我想选择热点函数,我这啪啦啪啦,我都我我写一些东西的。这路径成可能杠 home 之类的。然后我这保存一个模板,模板取个名字叫模板一杠一。这还不让取要 test 杠一取一个。
我这个模板保存好了,然后我这里在导入模板的时候就发现有了刚刚我们保存的那个任务的一个模板了对吧?如果说我们的性能调优或采集任务是比较多的对吧?而且是分不同的程序的,或者说是分不同的环境的话,我们就会创建对应的任务模板,让我们去快速地进行一个创建任务。然后我们的模板创建好后的话,我们可以来到这边我们那个模板管理,然后在这里就可以对我们那个模板进行一个删除,也就说我这个模板不想要了对吧,我就可以直接把它删掉就可以了。来我们再看看我们的任务怎么样了。我们的那个技能性能分析任务已经完成了,来我们点一下,我们就可以进入这个报告。那首先我们来看看总览。总览页面也是一样,我们就在最上面如可以看看,也提供了两个优化经验。首先他就告诉我线这个线程 ID 为 984734 这个线程他有存在一定的一个 new 码访问情况,就是说最好给这个线程设置一个 new 码亲和性的一个动作然后怎么去设置,他也告诉我们了,然后怎么样这里。但是而且这里也告诉我们一个知识点,大家可以稍微关注一下。

image-20220721002156873就是说我们内存访问了,时延从高到低,它是呈这么一个情况对吧,跨 CPU 是最大的。然后我说怕牛马,但是不怕 CPU 它相对来说是好一点的。然后就是一个牛马内进行访问,它的时间是最低的。所以说刚刚讲到牛马这个设计,就是让我们那个访问 CPU 的一个效率更高。看看第二个一个建议,就是说也是这个跟上面一样的线程,CPU占用率过高。然后他的建议也给我们,就是说让这个线程的计算任务分解到其他线程或者说增加一个线程数。
接下来我们就看看具体这个 CPU 是属于,哪个程序对不对?属于哪个进程呢?首先我们也来看一下,这个也看到了,首先就是以 CPU 维度我们来给他排个去,因为我们前面已经知道的是用户态,使用率较高对吧。我们把它排个序,我们会发现这个 PID 为 984732 的这个程序,它的用户的使用率达到了99.28%,基本上 100% 了。而且我们把它点开来看发现这个 984734 这个线程不就是前面优化建议提到的线程吗?的确,他的用户在 CPU 使用率达到了百分之九十九九十七点九九基本上 100% 了。而且我们还可以观察到,就说这个程序他在采集期间还有另外一个线程在运行。那这个线程的 CPU 使用率就相对来说低了,你看才百分之一点多两个线程对吧,而且他们的内国态很低,1%都不到。还有就是这个等待的一个使用率这个94733,他百分达到了百分之三点多也不算高。然后这个这个 4g34 基本没什么等待。那说明在采集期间我们的 CPU 使用率都是这个它贡献的,还有我们看看它这个进程的一个启动命令是吧。

image-20220721002205654A 他是这个其实可以讲到,刚刚我不是起到了一个测试程序对吧,其实我这个测试程序这个就是我刚刚启动的一个测试程序他就是这样,我的测试程序就是这个,因为你看一下这个就是我们测试程序的一个二级制对吧,启动程序就他也是我正好是一个目标程序,我的目标程序用户态怎么那么高对不对?第二点,我们来看,可以看看我们这个进程线程一个内存使用率其实在全景分析里我们可以分析到其实但内存情况没什么刺激,这里我们也可以大概看一下。

image-20220721002213452也是虚拟内存排下序,这里也没干嘛对吧,这里你看一下是这个程序,但是这个程序我们在前面放到它的 CPU 损率是不高的,然后或者说我们再排一下以那个物理内存对吧,你看其实这是不高的,因为他的这个 KB 相对来说你像这个 KB 的话其实也就才多少。而且他的一个是一看是,启动是一个 gdk 相关的一个东西,还有它的一个占用率是很低的。最高的才1%,对内存情况没什么问题,这样磁盘 IO 我们也可以大概扫一眼对吧,我们就是看这个 IO delay ,等待的一个延迟时间。最大的一个程序,它的时间也就是零点零零点六四个始终周期,我可以基本认为是没有的。

image-20220721002225873好吧,然后我们再来看看上下文。因为我们刚刚前面这里讲到上下文切换的话,我这里主要讲两个指标。就在上下文切换中,由他两个最重要的指标就是一个是这个主动上下文切换。主动上下文切换就什么意思呢?就是说我们的任务或者说我们的线程或者进程,他因为在 CPU 调度过程中,因为得不到某些资源,或者说某些资源不足的情况下对吧,他不得不让出了一个 CPU 的使用权,这个这这个行为叫主动上下文切换还有叫被动上下文切换。就是说我的线程或进程就是按正常的情况下,我的 CPU 给他的时间片用完了对吧,那就应该结束了,需要给另一个线程或进程使用了,这种情况叫被动上下网切换。
所以一般来说我们很最先关注的就是这个主动上我们切换对不对?他是因为一些系统资源不足,像 IO 或者内存不足。被动的切换的吗?像主动对不好意思说错了,是主动上下文切换。如果说被动上下文切换也很高的,我们只能说明这个进程内他的一个可能在采集期间,咱们 CPU 的资源使用的抢占较频繁,这里的话我们可以直接去看看我们的目标程序对不对我们刚刚目标程序它这叫984732,我们可以看一下,先给这个 PID 排个序,9847。大家玩切换排个序,984732。
没有,我们发现其实根本没有。那么我认为其实我们的目标程序上和切换就是在采集间没有发生或者说发生的很少,所以我们的采集数据就没有把它采集出来。通过我们的进程性能切换,我们已经找到了定位到了 CPU 水率最高的那个程序,就是我们这个目标程序。刚刚我请了对吧,那接下来我们应该接下来应该怎么办呢?我们发现了目标程序后,我们应该接下来创建什么任务去定位呢? 1 我们就可以总结一下。

image-20220721002234962首先我们发现说他目前情况是目标程序 CPU 内核用户带 CPU 使用率很高,90%多 100 对不对?但是它的内存呐存储 IO 磁盘 IO 都没问题。而且我们发现在采集期间它是有有两个线程是一直在运行的,而且其中一个线程在采集的数据中是贡献了绝大多数的一个 CPU 使用率。
那么我我应该从哪些方面定位呢?对吧?你说因为内存,IO都没有,没没啥问题,我也没法用对吧?那其实我们可以用一下这个资源调度,因为我们说了还有两个线程在运行对不对?而且其中一个的他的一个 CPU 使用率很高。那我们就可以看看 CPU 到底是怎么调度的,就这两个线程到底是怎么一个运作方式?资源调度五杠一。
采集时间也是一分钟就够了,我们开始那采集期间我这也是再介绍一下其他功能。就是我们在创建任务的时候,我们这里有个开关叫预约定时启动,这个功能是干嘛的对吧?这个开关就是为了满足我们自己需求,就是往往我们的一些程序出现的问题的时候的时间点是比较尴尬的,就说要么很晚,大家都要睡觉,凌晨或者说是某一个固定的时间点对吧,或者说是周期性的出现,这样的话我们就可以通过这个任务这个小功能开起来对吧。

image-20220721002242311设置一下我们这个任务是想在未来的一进行一个周期性的采集,或者说在未来某个时间点进行采集,设置一下就行了。这样的话我们就不用说专门到那个时间点对吧,把自己拉起来对,然后去采集数据,然后看看数据到底有没有问题之类的。然后我们的预约任务的话,也可以在这里去进行一个管理主要是进行一个修改,还有一个删除动作,还有可以看看他这个状态是什么。然后我们看看我们的任务怎么样了。还得已经在分析了,稍微等一下。那这样我再介绍一个功能。就说我们这里有一个导入导出,他大概的意思就是说我们想把一些任务做一些备份,我们就会通过这个导出的功能去把某共享某个任务给导出出来对吧,导出出来后我们就可以保存到自己的电脑上了,或者下次我们就可以把他这个东西给另外一个人。
你也可以用我们这个同样的工具去分析一下对吧?或者说我们怕因为我们一个环境,因为我怕有些重启了或干嘛对吧?我们的环这个工具被卸载了,我们任务丢了也可以导出来做一个备份,是很方便的功能。还有就是对应的就挡不住。好,我们的资源调度分析任务已经结束了,这里我们就可以看一下。首先我们去看总览页就行了。 1 这里就是会把每个线程的它的切换的运行时长切换次数平均调度时间给列出来。这里的话我们就可以直接去搜索一下我们刚刚那个目标程序的相关线程了。那我们可以稍微看一下。首先我们可以得到一个结论就是目标程序它有两个线程在运行,一个是4g33,一个是 4g34 我们把刚刚的我们那个打开来再回顾一下,排个序 34734 他的线程 ID 还没有变对吧,而且运行时长,也是不短对吧?那我们认为其实我们这两次任务采集的是同一个,可以理解为同一个线程对吧?而且这个 33 的一个切换,这个期间我发现它的切换次数比较高,达到了 4 万多次,然后三次他只有 6000 多次。

image-20220721002250042而且我们发现 34 他的 CPU 使用率是较高的,然后 33 的比较少对吧?所以可能就 331 直没有对他切换次数那么多,可能是因为他一直因为一些原因呗对吧,没有得到这个 CPU 的一个使用权对吧?这里我们可以看一下,然后我们也可以看到这里就是把每个线程的牛马的一个切换次数你给列出来来了,我们排个序来发现都是0,所以说没有出现什么牛马节点的一个切换情况。然后接下来我们就可以切到这个进程线索调度的一个这个页签稍微等一下,因为可能数据比较多,他要渲染一下。我们可以看到,因为这里边刚刚在总览页我们已经过滤出来了,所以这里进程线程调度会直接把它给联动带过来。我们发现我们目标程序的两个线程,它在采集这个一分钟的时间内,它调度情况是这样的。
1 首先我发现在这一分钟时间内他根本没有交集,对不对?是错开的,就是是错开的。 2 我发现三四线程在这一分钟之内,你看大部分的 CPU 都在调度它,而且那调度的和都是 1 CPU 1 这个 CPU 那我们看现在 33 这个线程在这一分钟之内,只有在前面的人这个 10 秒 CPU 在调度他了,而且是调度他的这个是 CPU 0,然后在后面的话就是他一直没有被调度对吧,而是在 CPU 1 这是这这这个线程 34 在被调度,而且调度的 CPU 是 1 就很奇怪为什么呢?因为首先为什么在这后面的 50 秒 CPU 不调度它呢?而且他们我们发现他们是没有交集的。
为什么没交集呢?我们如果说没有交集的我们会不会有这种场景?我们都是被一个 CPU 在调度,所以说一个 CPU 一次只能被一个线程去占用去执行。但是我发现他都是 CPU 1 在调度他 CPU 0 或者说其他 CPU 是没有在是是是调度这个线程的。那为什么其他其其他的 CPU 不去调度这个三三现场,而且在 50 秒内它都是一直属于一个对吧,或者等待或者说属于一个 it 状态。
为什么呢?那我们首先其实我们可以再创建一个比较长的资源调度任务,去看更长的一个情况。但从这里我们可以就可以脑补脑脑洞一下是吧,是什么原因呢?一他是他们两个线程之间是不是存在一种等待关系,或者说他们需要同时去占有一个系统资源,对吧,说都要获一个文件同一个文件资源号,就是我们可以常常我们在开发中会使用的锁,全局锁会不会说我们需要有一种并发同步的关系对吧?一些业务我都要去做去抢占这把锁对吧,哪个线程抢占到了,然后去做相应的操作,那另一个线程没抢占到就只能等待了,是不是呢?这只是一个推论对不对?那这样的话我们可以接下来我们到底怎么去论证呢?或者说我们的目标程序到底在干了什么呢?对吧?而且他的 CPU 使用率那么高,到底是做了什么事情呢?接下来我们来创建第四个任务。
第四个任务就是我们通用分析里面的一个热点函数分析对吧?前面讲到了这热点函数分析是一个很实用的一个功能,就说往往的话我们做性能平行点的时候,我们可以先使用热点函数分析,看看我们的在采集期间,我们的程序运行期间,我们的系统运作期间它的热点函数是什么。一般来说找到热点函数,并且我们真的能对热点函数进行一个优化的话,那我们对我们的一个程序或者系统是一个很好的提升。这里我们来创建一个热点函数任务采集时长 30 秒就够了也是一样。在这个采任务执行期间,我来介绍一下一些功能。
就是首先我们这里有一个联动分析,那联动分析这个是干嘛用的呢?她其实做的事情就是做任务之间的对比。因为我们在做数据性能定位的时候,往往会对不同时间段的一个性能数据或者说采集来的相关的一些数据进行一个对比工作对吧,这是很正常的事情。那如果说一般来说如果说数据量少还好,那如果说数据量很多,数据指标很多,这个对比工作就是很麻烦的,而且还怕出错。那我们这个联动分析就是解决这个问题。我们这边就是提供了横向分析和侧向分析。横向的话就是说在同一个功能下,不同的节点之间起一个结果对比。然后纵向的话就是说不同的任务之间的两个节点之间的数据进行一个对比,然后大家根据实际情况去使用就行。然后目前对比对象的话就这是两种,一个是全景的相关数据,二就是热点函数的一个相关数据。我们来看看我们那个热点函数分析任务已经结束了,这里我们可以很快的看到。 1 首先就是会把一个时政周期还有指令数给列出来。二就是一个 IPC 是什么样的?然后这边也有个优化建议也达到了。就说我们的 C 加 B 和 C 加程序的 CPU 利用率较高对吧?那我们看看到底是谁呢?那我们直接就看看那个 top 10 热点函数列表。
1 首先我们发现排名第一的是这个 func 函数,它占时钟周期占比达到82%,那它肯定是最热的。那第二名是你看是一个占了才百分之六点多看一下。其实这个是我们工具的采集数据的时候占用的一些操作。排名第一的,而且看一下它模块,也正好,这是我们属于我们测试程序。那肯定的,因为我们前面已经定位出来了,我们的测试程序,它的 CPU 占用率最高。然后我们可以看这个火焰图稍微等一下他在渲染。
就说火焰图的话,我可以就讲讲。一般来说我们看热点函数的火焰图怎么看呢?尤其是一些大火焰图,对大程序的火焰图它是很大对吧,有很多像我这个还比较少,它怎么看呢?其实很简单,大家不要被这个火焰头的复杂度给蒙蔽了。就说我们只要看这个火焰头的顶部,它是否是比较宽越宽,说明它就可能是属于热点。就是热点函数如果说是尖或者很少的话,很很很窄的话,它就不属于热点。如果我发现我采的火源头都是尖,那么其实就是没有什么热点,热点函数现在就在采集期间是这样的。然后我们这里可以看到我们这个放个函数跟前面我们在总览上给出的它就是排名第一的那个热点来说,正好是对应上了,它是最宽的对吧,我们看到它的一个调用关系。 1 首先它是我们是我们那个测试成绩出来的。 2 我们可以看到这两个放个方法是属于不同的线程出来的。嘿这里有没有发现我们前面就不是说了,我们的测试程序在采集的多个任务,发现一直有两个现场在跑对吧?我们现在也可以发现这两个线程其实是做了同样的事情,他最终都去调了这个放个方法,而且他们的占比都是很高的。
从热点火焰图上这样从我们刚刚的结论可以看出,这两个县城做的事情是有关联的,最起码她们做的是相同类似的事情是吧?那接下来我们再回到这里,我们找到这个热点函之后,我们就点进去,我们就可以看到这个热点函数的一个源码了。我们的工具是说,如果说我们的那个程序如果没有做了一些特殊限制,我们是可以把这些热点函数的源码直接给采取出来给大家看这个是很方便的一个事情。然后在代码流中,我们可以直接点到这个暗红色这块,它就会直接定位到我们这个热点函数中。这个最热的一个操作对吧,是开平方去调去开启一个开平方的一个操作。那接下来我们就分析一下这个热点函数。放这个方法做了什么事情呢?我们大概因为它不长,我们可以解读一下。首先它这有一个循环操作,那个 G count 那肯不是局部变量,就是个全局变量进行一个循环。当。的确我们这个热点函数有锁的操作,你看获取一个全局锁。然后对这个 G num 它这个全局变量做一个 D 灯操作低增操作做完后,你看一下这几行。
我们发现这几行其实做的事情就是对一个局部变了 S 做一个循环操作,然后 N 肯定应该是个全局变量对吧,因为这不是局部变量,然后 N 循环操作不断地进行开平方,然后做一个累加的操作。但是其实 46 行到 50 行这几部我操作他就是个局部操作。而且相对来说这里面的他的一个花费的时间跟这个我们四十四行这个具有并发同步场景的这个操作,他的时间是大很多的对吧。首先一个开平方根肯定是比他这个递增大很多了,而且他这个循环的。那而且这里我们就发现问题了,为什么会要把这一个比较耗时的一个局部操作放在我们这个锁的一个范围之内,是不合理的对不对?因为首先我们这个并发场景的话,我们去获取一个全局锁,就是其他的线程肯定要等待的,对不对?那如果说我们想要的结果是等待时间越短越好是吧,不可能等待时间越长。那我为什我们又把一个局部的比较耗时,这个操作又放到我们这个锁的范围里面了,是不合理的,完全是可以放到外面的,也是不影响我们的业务操作的。
对不对?通到这里,其实我们跟前面的我们这个资源调度这个图我们是不是可以对应起来了?为什么会出现这种情况呢?调度情况对吧?为什么他们会这一个很长的一段时间内,我们的力其中有一个线程在一直不会调度,可我们发现他们并不是说因为是被调度的是同一个 CPU 所以才导致另一个线程一直没有被调度,而是不同 CPU 那我们再对一下这个热点函数,它对,那个一个代码不就出来了吗?那么我们另外一个线程肯定是在等了,为什么会等那么长呢?很可能就是因为他这个局部比较耗时的操作造成的。
那接下来我们就能找到我们的热点函数,的确有问题,对吧,那我们继续进行优化呗。那我们这个场景优化比较简单,就是把这步操作给移出来,那我们这边就开始操作一下。那首先我们把这块这个就是我的测试程序的一个源码操作。那我们对,就是我们的测试程序改一下它代码对吧,我们打开就直接通过文档打开了。这里就是我们测试程序的一个全部代码。我们看一下发现我们当时的这个聚娜的确是全局变量,还有这个迭代的次数,这多少我们看一下个十百千万十万万千万亿,这里要循环一亿次,所以我们这个测试程序会执行比较长。第二个我们去看一下这个局部变量,它的循环次数多少,这个 N 是多少?
N 在这 N 是一二三四五六十万次。你看这里做 10 万次的开平方根做累加,跟这个四次上比起来真的差太多了对吧,根本不是量级的。所以我们刚刚为什么资源调度那边会出现那种情况出来了?这里的确会比较长的一个时间。那我们怎么优化呢?这里优化就比较简单,这个东西移到外面来就成了,改好后我们这里重新编译一下,然后重新执行一下。
执行好后,我们这里就在在创建一个资源调度对吧。因为首先我们刚刚这种优化方法并不会降低我们的 CPU 使用率对吧?只不能说我们把这个锁的范围变小了,把一些不必要的一些局部操作移除到我们的锁的范围之内了。这样的话我们最想看到的就是说它的调度是更加合理的,而不需要等那么长,我们去再创建一个 CPU 调度的一个任务资源调度杠二点叫做 line 我们 30 秒,这里弄个 30 秒看看就行了。
我在等的过程中我可以就讲讲,就是说我们如果说我们的程序的确需要去获取那种全局锁,做一些并发操作,这样的话我们像这种场景我们应该注意什么几个点呢?1、我们的锁里面的范围最好是保证它里面的操作都是有全局就是并发同步的场景的,就是一些局部变量或者说一些,非并发场景不要放在锁的范围里面,我们要让我们锁的范围里面的逻辑执行得够快对吧,足够简单。
第二就是往往我们在像这种场景我们会开一些,往往会开一些多个性能去做,就说这个线程数一定要控制好,并不是越多越好,也不是越少越好,得根据我们那个实际情况去看,因为 CPU 越多的话,尤其是并发场景的话,这个抢单资源就比较严重,是不是还有一个就是说我们尽可能的话把我们的任务进行一个拆解,不要说我们在一个县城里做太多的事情,尤其是涉及到这些并发场景的,把它拆开,这样的话更合理。
好。我们再来看看我们优化后的程序运行后他这个资源调度情况。那我们这边你看看,我们就找到刚刚。这里没有吗?我瞅一眼这里,我们去搜索一下做我们的目标呈现。那首先我们看一下就是这个切换次数没有,就是像刚刚我们前面创建的那个资源调度,我可以对比一下,就切换次数没有说差异性那么大了。原先是因为那个锁抢断锁等的时间比较长,所以一个线程可能被切换的次数会较多,你看是吧,但这里的话你看基本上没有差距那么大了,属于同一个数量机。那我们看看这个这里,它的 CPU 调度这个图是什么样的呢?这里我们就稍微等一下,因为这里的话渲染会花一天的时间出来了。
大家看一下这两个就是我们的目标线程,有没有发现他这个调度跟前面那个任务的调度是天壤之别,是不是?首先两个线程就互相等待的时间减少了太太多了。而且我们基本可能可以让认为这个如果说优化后的代码在就是我们的执行逻辑上就是合理的很多,所以它的调度是更合理的。
最起码我一个线程没有因为这个锁了,资源抢占不到,没有长期的等待,而且是这种交替的对吧,实际上他们是应该交替的,但是因为这个交替的时间就是等的时间比较短,所以我们看起来是有交集的,其实实际上是没有交集的,是这样的一个调度情况,这是一个比较合理的。
那今天其实我们这个测试程序它的一个整个定位过程,就那我结束了,我这里就是给大家稍微做快速总结。首先我们在不知道来到这里,在不知道我们的程序或者系统有什么问题的时候,我们就可以通过通用分析里的相关功能。首先就是我们可以让他默认顺序,通过全景分析来把全景的数据采集和分析,看看到底是哪块的资源出现问题了,或者说哪个部件。 2 就说我们再去看看具体是哪个进程或线程是贡献这些瓶颈点的对吧。第三,我们去看看一些热点函数到底是什么样的,是否能跟我们那个前面的数据去关联起来。再就是我们去后面就是根据我们的一些实际情况,我们发现了 IO 的确有问题,那我们就可以通过这个 IO 分析这个任务去分析一下,或者说我发现锁是吧,有没有的确怎么样?我去可以分析一下。或者说我去通过资源调度也是以很好的一个功能,我们去看看我们的各个现场各个 CPU 它的调度情况是否是比较合理的。正常的话就是一个城区内各个现成的 CPU 调度情况是应该出现那种交替状的出现,并不应该出现那种一个线程等了一个等待时间比较久才被调离出来。除非说那个线程它的逻辑是做完一些执行后,它一直在 sleep 对吧,那样是可以理解的。但如果说没有这种操作,就像我们今天的一个测试程序一样对吧,是有一个全局锁的获取,有个并发操作,他竟然等那么长,太不合理了。

image-20220721002303397

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。