工具类型
性能观测工具可以按照系统级别和进程级别来分类,多数的工具要么基于计数器要么基于跟踪。我们把这些属性放在下图中,连同一些工具一起作为示例:
有一些工具不止适合一个象限,例如,top(1) 还有一个系统级别的视图,DTrace也有进程级别的能力。
还有一些性能工具是基于剖析(profiling) 的。对系统或进程做一系列快照,依次来进行观测。
计数器
内核维护了各种统计数据,称为计数器,用于对事件计数。通常计数器实现为无符号的整型数,发生事件时递增。例如,有网络包接收的计数器,有磁盘I/O发生的计数器,也有系统调用执行的计数器。
计数器的使用可以认为是“零开销”的,因为它们默认就是开启的,而且始终由内核维护。唯一的使用开销是从用户空间读取它们的时候(可以忽略不计)。下面介绍的两类工具的读取分别是系统级别的和进程级别的。
系统级别
下面这些工具利用内核的计数器在系统软硬件的环境中检查系统级别的活动。
- vmstat:虚拟内存和物理内存的统计,系统级别
- mpstat:每个CPU的使用情况
- iostat:每个磁盘I/O的使用情况,由块设备接口报告
- netstat:网络接口的统计,TCP/IP栈的统计,以及每个连接的一些统计信息
- sar:各种各样的统计,能归档历史数据
这些工具通常是系统全体用户可见的。统计出的数据也常常被监控软件用来绘图。
进程级别
下面这些工具是以进程为导向的,使用的是内核为每个进程维护的计数器。
- ps:进程状态,显示进程的各种统计信息,包括内存和CPU的使用
- top:按一个统计数据排序,显示排名高的进程。基于Solaris的系统对应的工具是prstat(1M)
- pmap:将进程的内存段和使用统计一起列出
跟踪
跟踪收集每一个事件的数据以供分析。跟踪框架一般默认是不启用的,因为跟踪捕获数据会有CPU开销,另外还需要不小的存储空间来存放数据。这些开销会拖慢所跟踪的对象,在解释测量时间的时候需要加以考虑。
日志,包括系统日志,可以认为是一种默认开启的低频临的跟踪。日志包括每一个事件的数据,虽然通常只针对偶发时间,如错误和警告。
系统级别
利用内核的跟踪设施,下面这些跟踪工具在系统软硬件的环境中检查系统级别的活动
- tcpdump:网络包跟踪(用于libpcap库)
- snoop:为基于Solaris的系统打造的网络包跟踪工具
- blktrace:块I/O跟踪(Linux)
- iosnoop:块I/O跟踪(基于DTrace)
- execsnoop:跟踪新进程(基于DTrace)
- dtruss:系统级别的系统调用缓冲跟踪(基于DTrace)
- DTrace:跟踪内核的内部活动和所有资源的使用情况(不仅仅是网络和块I/O),支持静态和动态的跟踪
- SystemTap:跟踪内核的内部活动和所有资源的使用情况,支持静态和动态的跟踪
- perf:Linux性能事件,跟踪静态和动态的探针
DTrace和SystemTap都是可编程环境,在它们只是可以构建系统级别的跟踪工具。
进程级别
下面这些跟踪工具是以进程为导向的,基于的是操作系统提供的框架:
- strace:基于Linux系统的系统调用跟踪
- truss:基于Solaris系统的系统调用跟踪
- gdb:源代码级别的调试器,广泛应用Linux系统
- mdb:Solaris系统的一个具有可扩展性的调试器
调试器能够检查每一个事件的数据,不过做这件事情需要停止目标程序的执行,然后再启动。
诸如DTrace、SystemTap和perf这样的工具,虽然更适合归纳到系统级别这一类中,但是它们都支持对单个进程检查。
剖析
剖析(profiling)通过对目标收集采样或快照来归纳目标特征。一个常见的例子就是CPU的使用率,对程序计数器采样,或跟踪栈来找到消耗CPU周期的代码路径。这些样本采集对于所有的CPU都是按固定频率进行的。如100hz或1000hz(每秒)。剖析工具,或者说剖析器(profiler),有时会稍微改变这一频率,避免采样与目标活动同一步步调,因为这样可能会导致多算或少算。
剖析也能基于非计时的硬件事件,如CPU硬件缓存未命中或者总线活动。这可以显示出哪条代码路径负责任,这类信息尤其可以帮助开发人员针对系统资源的使用来优化自己的代码。
系统级别和进程级别
下面是一些剖析器的例子,这些工具所做的剖析都是基于时间并基于硬件缓存的。
- oprofile:Linux系统剖析
- perf:Linux性能工具集,包含有剖析的子命令
- DTrace:程序化剖析,基于时间的剖析用自身的timer tapset,基于硬件事件的剖析用自身perf tapset
- cachegrind:源自valgrind工具集,能对硬件缓存的使用做剖析,也能用kcachegrind做数据可视化
- Intel VTune Amplifier XE:Linux和Windows的剖析,拥有包括源代码浏览在内的图形界面
- Oracle Solaris Studio:用自带的性能分析器对Solaris和Linux做剖析,拥有包括源代码浏览在内的图形界面
监视
最广泛用于监视单一操作系统的工具是sar(1),来源于AT&T的UNIX。sar(1) 是基于计数器的,在预订的时间(通过cron)执行以记录系统计数器的状态。sar(1) 工具支持用命令来行查看这些数据。
观测来源
系统性能统计的主要来源是:/proc、/sys和kstat。后面还会介绍延时核算和微状态核算以及其他的一些来源。
观测来源
Type | Linux | Solaris |
---|---|---|
进程级计数器 | /proc | /proc, lxproc |
系统级计数器 | /proc, lxproc | /kstat |
设备驱动和调试信息 | /sys | /kstat |
进程级跟踪 | ptrace,uprobes | procfs,dtrace |
性能计数器 | perf_even | libcpc |
网络跟踪 | libpcap | libdlpi,libpcap |
进程级延时指标 | 延时核算 | 微状态核算 |
系统级跟踪 | tracepoints, kprobes, frace | dtrace |
/proc
这是一个提供内核统计信息的文件系统接口。/proc包含很多的目录,其中以进程ID命名的目录代表的就是那个进程。这些目录下的众多文件包含了进程的信息和统计数据,由内核数据接口映射而来。在Linux中,/proc还有其他的文件,提供系统级别的统计数据。
/proc由内核动态创建,不需要任何存储设备(在内存中运行)。多数文件是只读的,观测工具提供统计数据。一部分文件是可写的,用于控制进程和内核的行为。
该文件系统是很便利的:这是一个直观的框架,将内核统计数据用目录树的形式暴露给用户空间,编程接口就是众所周知的POSIX的文件系统调用,即open()、read()、close()。而且通过使用文件访问权限,这一文件系统还保证了用户级别的安全。
与进程性能观测相关的文件如下:
- limits:实际的资源限制
- maps:映射的内存区域
- sched:CPU调度器的各种统计
- schedstat:CPU运行时间、延时和时间分片
- smaps:进程状态和统计,包括总的CPU和内存的使用情况
- stat:进程状态和统计,包括总的CPU和内存的使用情况
- statm:以页为单位的内存使用总结
- status:stat和statm的信息,用户可读
- task:每个任务的统计目录
与性能观测相关的系统级别的文件如下:
- cpuinfo:物理处理器信息,包含所有虚拟CPU、型号、时钟频率和缓存大小
- diskstatus:对于所有磁盘设备的磁盘I/O统计
- interrupts:每个CPU的中断计数器
- loadavg:负载平均值
- meminfo:系统内存使用明细
- net/dev:网络接口统计
- net/tcp:活跃的TCP套接字信息
- schedstat:系统级别的CPU调度器统计
- self:关联当前进程ID路径的符合链接,为了使用方便
- slabinfo:内核slab分配器缓存统计
- stat:内核和系统资源的统计,CPU、磁盘、分页、交换区、进程
- zoneinfo:内存区信息
/sys
Linux还提供了一个sysfs文件系统,挂载在/sys,为内核统计提供一个基于目录的结构。与/proc不同的是,/sys经过一段时间的发展,把各种系统信息放在了顶层目录。sysfs最初是设计用于提供设备驱动的统计数据,现在已经扩展到了提供所有的统计类型。
延时核算
开启CONFIG_TASK_DELAY_ACCT选项的Linux系统按以下状态跟踪每个任务的时间。
- 调度延时:等待轮到上CPU
- 块I/O:等待块I/O完成
- 交换:等待换页(内存压力)
- 内存回收:等待内存回收例程
从技术上来说,调度器延时统计源自schedstat,不过是与其他的延时核算数据放在一起的。
其他观测源
- CPU性能计数器:可编程的硬件寄存器,提供低层级的性能信息,包括CPU周期计数、指令计数、停滞周期,等等。
- 进程级别跟踪:跟踪的是用户级别软件事件,如系统调用和函数调用。一般执行的代价较高,会拖慢跟踪的目标。在Linux上有系统调用ptrace() 来控制进程跟踪,strace(1) 同它来跟踪系统调用。Linux还有uprobes来做用户级别的动态跟踪。
- 内核跟踪:在Linux中,tracepoints提供静态的内核探针,kprobes提供动态探针。工具ftrace、perf(1)、DTrace和SystemTap都用到了这两项。
- 网络嗅探:网络嗅探提供了一种从网络设备上抓包的方法,能对数据包和协议的性能做详细的调查。在Linux上,嗅探的功能是通过libpacp库和/proc/net/dev提供的,命令行工具则有tcpdump。
- 进程核算:它以某种形式存在于Liunx系统上,有时能在进程级别对性能分析有欧帮助。
- 系统调用:一些可用的系统调用和库函数调用能提供某些性能指标。其中包括getrusage(),这个函数调用是为进程拿到自己资源的使用统计,包括用户时间、系统时间、错误、消息,已经上下文切换。