CPU
认识CPU
CPU本身的架构和内核调度器的架构这里不做详细讲述,具体可以参考操作系统类书籍。但是仍然需要清楚一些概念:
处理器
核
硬件线程
CPU内存缓存
时钟频率
每指令周期数CPI和每周期指令数IPC
CPU指令
使用率
用户时间/内核时间
调度器
运行队列
抢占
多进程
多线程
字长
针对应用程序,我们通常关注的是内核CPU调度器功能和性能
线程的状态分析主要是分析线程的时间用在什么地方,而线程状态的分类一般分为:
on-CPU:执行中,执行中的时间通常又分为用户态时间user和系统态时间sys。 off-CPU:等待下一轮上CPU,或者等待I/O、锁、换页等等,其状态可以细分为可执行、匿名换页、睡眠、锁、空闲等状态。
如果大量时间花在CPU上,对CPU的剖析能够迅速解释原因;如果系统时间大量处于off-cpu状态,定位问题就会费时很多。
分析方法与工具
在观察CPU性能的时候,按照负载特征归纳的方法,可以检查如下清单:
整个系统范围内的CPU负载如何,CPU使用率如何,单个CPU的使用率呢?
CPU负载的并发程度如何?是单线程吗?有多少线程?
哪个应用程序在使用CPU,使用了多少?
哪个内核线程在使用CPU,使用了多少?
中断的CPU用量有多少?
用户空间和内核空间使用CPU的调用路径是什么样的?
遇到了什么类型的停滞周期?
要回答上面的问题,使用系统性能分析工具最经济和直接,这里列举的工具足够回答上面的问题:
工具 | 描述 |
---|---|
uptime | 平均负载 |
vmstat | 包括系统范围的CPU平均负载 |
top | 监控每个进程/线程CPU用量 |
pidstat | 每个进程/线程CPU用量分解 |
ps | 进程状态 |
perf | CPU剖析和跟踪,性能计数器分析 |
在上述问题中,对调用路径和停滞期的分析可以使用perf工具,也可以使用DTrace等更灵活的工具。
Perf支持跟踪各种内核时间的统计信息,可以使用Perf列表查看这些统计信息。例如,停滞期分析可能非常复杂,需要系统地理解和理解CPU和调度程序体系结构。
停滞周期可能发生在主缓存、辅助缓存或三级缓存中,比如缓存丢失,也可能发生在内存IO和资源IO上的停滞周期中,比如事件perf计数统计中的l1 -dcahce-load、l1 - apache -load等。
实际案例
火焰图帮助分析CPU的调用路径
当我们分析mysql服务器在某个模型上的非就地更新性能时,我们分析了在分析mysql服务器延迟时CPU上的主要函数调用。
使用perf top可以看到调用数量的排序,但是不能显示调用关系。火焰映射清楚地提供了调用关系的视图(这两个图中的比例不同,因为perf顶部添加了-p参数,而火焰映射分析针对整个系统)。
内存
认识内存
正如前面提到的,内存天生就是用来提高效率的。在实时分析问题时,内存中的问题不仅会影响性能,还会影响服务或引起其他问题。还有一些关于记忆的概念需要弄清楚:
主存
虚拟内存
常驻内存
地址空间
OOM
页缓存
缺页
换页
交换空间
交换
用户分配器libc、glibc、libmalloc和mtmalloc
LINUX内核级SLUB分配器
分析方法与工具
Brendan在书中给出了一些问题,如内存总线的余额、内存是否分配到NUMA系统中的适当节点等。在实际分析问题时,这些问题不能作为切入点。连续分析。因此小猪站长将其简化为以下列表:
系统范围内的物理内存和虚拟内存使用率
换页、交换、oom的情况
内核和文件系统缓存的使用情况
进程的内存用于何处
进程为何分配内存
内核为何分配内存
哪些进程在持续地交换
进程或者内存是否存在内存泄漏?
内存的分析工具如下:
工具 | 描述 |
---|---|
free | 缓存容量统计信息 |
vmstat | 虚拟内存统计信息 |
top | 监视每个进程的内存使用情况 |
ps | 进程状态 |
Dtrace | 分配跟踪 |
除DTrace外,所有工具只能回答信息统计、进程内存使用等问题。至于是否发生内存泄漏等,只能通过分配跟踪。
但是DTrace需要对内核函数有深入的了解,用D语言编写脚本来完成跟踪。Perf也有用于跟踪的事件,如cache-miss和page-fault,但它不是直观的。
实际案例
对于内存泄漏,很难从监视和顶层观察中发现问题。通常,它是从底层程序代码进行分析的。在使用各种观察工具和跟踪工具的情况下无法确定原因。这个问题只能通过分析代码来解决。
最后的发现是lua脚本语言能够快速分配内存。在使用包驱动的定期服务时,lua自动回收不能快速释放内存,而是专注于回收。如果频繁回收,可能会带来CPU压力。开发项目团队采用的最后一个解决方案是分阶段回收,每次回收一部分内存,然后全部回收。
IO
逻辑IO vs 物理IO
通常在讨论这个问题时,总是要分析IO的负载。IO的负载通常是指磁盘IO,即物理IO。例如,我们使用iostat获取avgqui -sz、svctm和until等指标。
因为我们的读写最终是从磁盘或到磁盘,所以磁盘的IO情况是非常正确的。但是,当我们执行读写操作时,目标对象不是直接面对磁盘,而是面向文件系统的,除非使用原始io。
下图为一般IO结构图。如果你想知道更多的细节,你可以看第二幅图。我们知道LINUX通过文件系统以文件的形式管理所有硬件设备,甚至网络。例如,当调用read()时,实际上调用vfs_read函数。文件系统将确认请求的数据是否在页面缓存中。在内存中,然后将请求发送到块设备;
此时,内核首先获取物理设备上数据的实际位置,然后将读请求发送到块设备的请求队列。IO调度程序通过某种调度算法将请求发送到磁盘设备驱动程序层,以执行实际的读取操作。
在这个过程中会发生什么?如果应用程序执行大量顺序读取怎么办?当你随机阅读时会发生什么?如果是顺序读取,正确的方法是执行预读,让请求的数据进入内存,并提高读取效率。所以在应用程序启动读取的过程中,从文件系统到磁盘,存在读取放大的问题。
在写操作中也存在类似的情况。应用程序在文件系统上启动IO操作。有时,物理IO和应用程序可能看起来无关、间接、放大或缩小。
无关:
其他的应用程序:磁盘IO来自其他的应用程序,如监控,agent等
其他用户:如同虚拟机母机下的其他用户
其他内核任务:如重建raid,校验等
间接:
文件系统预读:增加额外的IO,但是可能预读的数据无用
文件系统缓冲:写缓存推迟或者合并回写磁盘,造成磁盘瞬时IO压力
放大:
文件系统元数据:增大额外的IO
文件系统记录尺寸:向上对齐等增加了IO大小
缩小:
文件系统缓存:直接读取缓存,而不需要操作磁盘
合并:一次性回写磁盘
文件系统抵消:同一地址更新多次,回写磁盘时只保留最后一次修改
压缩:减少数据量
图片来源: https://www.thomas-krenn.com/de/wikiDE/images/b/ba/Linux-storage-stack-diagram_v4.0.png
文件系统分析与工具
与文件系统相关的术语如下:
文件系统
VFS
文件系统缓存
页缓存page cache
缓冲区高速缓存buffer cache
目录缓存
inode
inode缓存
下图显示了文件系统缓存的结构。页面缓存缓存虚拟内存的页面,包括文件系统的页面,提高文件和目录的性能。Linux将缓冲区缓存放入页面缓存,即页面缓存包含缓冲区缓存。
文件系统使用的内存脏页由内核线程写回磁盘。图中的页面扫描器kswapd是后台页面交换过程。当内存不足时,当超过一定时间(30秒)或脏页太多时,就会触发。磁盘写回来。
文件系统延迟是指从文件系统逻辑请求开始到结束的时间,包括文件系统、内核磁盘IO子系统,以及等待磁盘设备响应的时间。当同步访问时,应用程序阻塞请求并等待文件系统请求结束。在异步模式下,文件系统对它没有直接影响。
而异步访问又分为select、poll、epoll等,即异步阻塞、异步非阻塞。在异步模式下,通常会打印出用户层启动文件系统逻辑IO的调用堆栈,以及调用哪个函数来生成IO。
Linux不提供查看文件系统延迟的工具和接口,但是磁盘指标更丰富,但是在许多情况下,文件系统IO和磁盘IO之间没有直接关系,比如应用程序写文件系统。
但我根本不在乎什么时候把数据写到磁盘上。当将后台数据扫描到磁盘时,磁盘IO负载可能会增加。从磁盘的角度来看,应用程序的写可能会受到影响,但是应用程序不会等待。
文件系统的分析可以试着回答下面的问题:
哪个应用程序在使用文件系统?
在对哪些文件进行操作?
在进行什么样的操作,读写比是多少,同步还是异步?
文件系统的缓存有多大,目前的使用情况?
有遇到什么错误吗?是请求不合法,还是文件系统自身的问题?
事实上,上述问题,除了系统内存,页面缓存和缓冲区缓存大小,可以看到哪些进程读写操作,哪些文件被读取,其他应用程序,如文件系统读取和写入比率,同步还是异步的,没有工具给清楚这些问题。当然,我们可以通过跟踪应用程序的内核调用堆栈来发现问题,或者我们可以在应用程序中输出一个日志来帮助进行分析。
磁盘分析与工具
在理解磁盘IO之前,同样我们需要理解一些概念,例如:
虚拟磁盘
扇区
I/O请求
磁盘命令
带宽
吞吐
I/O延时
服务时间
等待时间
随机IO/连续IO
同步/异步
磁盘接口
Raid
对于磁盘IO,我们可以列出如下等问题来帮助我们分析性能问题:
每块磁盘的使用率是多少?
每块磁盘上有多长等待队列?
平均服务时间和等待时间时多少?
是哪个应用程序或者用户正在使用磁盘?
应用程序读写的方式是怎样的?
为什么会发起磁盘IO,内核调用路径是什么样的?
磁盘上的读写比是多少?
随机IO还是顺序IO?
Linux对磁盘的性能分析工具主要如下:
工具 | 描述 |
---|---|
iostat | 各种单个磁盘统计信息 |
iotop、pidstat | 按进程列出磁盘IO的使用情况 |
perf、Dtrace | 跟踪工具 |
无论磁盘是随机IO还是顺序IO,很多时候我们都没有很好的方法来判断,因为当块设备写回磁盘时,随机IO可能已经被排序为顺序IO。对于磁盘分析,还可以使用perf跟踪事件或DTrace设置探测。
在分析mysql对模型执行非完全缓存非就地更新时,为什么单个实例不能满足机器性能,我们在分析期间跟踪块设备的内核事件。我们比较了多实例非就地更新和单实例非就地更新时磁盘的操作。以下是未进行更新时跟踪的结果
分析结果后,它被认为,当单一实例不是更新的地方,近30%是blk_finish_plug, 70%是blk_queue_bio,和多实例正好相反,大量的blk_finish_plug和少量的blk_queue_bio(当然,这不是为什么表现不满意)原因)。
评论 (0人参与)
最新评论