top命令解析
top命令解析
在进压测,排查性能问题时,我们需要通过各种命令对系统情况进行检查排错,最常用的命令即是 top,通过对 top 信息的分析与处理,能够排查掉大部分的性能瓶颈问题
top 命令是系统自带的系统排查命令
每一行都显示了不同的系统信息
先来看第一行
第一行的数据通过
uptime
也可以拿到同样的数据
这里的数据分四列:
第一列为系统时间
第二列为该机器的运行时间,如上面的第二列说明 系统已经运行了 971天,18小时38分
第三列为目前系统登陆的用户数
这里看到目前登陆的 2 个用户,这里我们用
who
命令也可以看到
登陆了两个用户
这里 pts 表示使用的 ssh 远程登陆上来,后面那一列表示是 登陆时间
其他类似的还有
w
命令可以看到相关登陆用户的更多信息
这里我们看到最后 what 有个 -bash 说明 这个 log 用户在执行命令,但是具体执行什么命令 因为权限问题 我们是看不到的,但在取得超级管理员权限后可以看到每个用户此刻在执行的命令。
另外如果需要查看 log 用户的命令执行历史,除了用
history
之外,我们还可以直接观察
vim ~/.bash_history
文件获取每个用户的操作记录
top 命令第一排第四列是平均 Load 值,从左到右分别为 Load1 Load5 Load15 ,解释为 一分钟,五分钟,十五分钟 Load 的平均值
这里来看看 Load 是什么
Load load average表示CPU处理队列的长度
以单核 cpu 举例,单核 cpu 的 Load 满载为 1 ,表示一个处理时刻 cpu 处理一个任务
Load 是可以大于 1 的,说明一个处理时刻,cpu 需要处理的任务数大于 1 个,这时候机器已经在超负荷运行了
这些场景类似于 高速公路收费站,同一时刻只能让一辆车通过,如果这时候后面还有车需要通过,那只能等待
4核 cpu 则 Load 满载为 4 ,Load 为 8 则表示同一时刻,有 4 个任务在处理,有 4 个任务在等待。
我们在 xflush 上面也同样可以看到 机器的 Load 参数
Load 参数表明了 目前系统的运行情况,通常情况下,几核的 cpu 的 Load 最大负载就是几,8 核的 cpu 最大 Load 负载就是 8 ,超过 8 说明此时机器已经在超负荷运行。
看完 top 的第一行,继续来看看 top 的第二行
第二行是 系统此时的进程情况
total 是目前系统所有进程数, running 是目前运行的进程数,sleeping 是目前sleep 的进程数, stopped 为中断进程数, zombie 为僵尸进程数
在观察 cpu 情况时,如出现过多的 僵尸进程或中断进程,需考虑系统是否存在调整过优先级的进程或进程设计是否存在问题,出现这样的情况建议直接联系 PE 重启机器
第三行为 cpu 的各类信息
在 top 的 man 释义中可以看到各个 参数的具体解释
在 top 的展示下,我们直接按数字键盘的 1 ,可以看到该 cpu 的核数,以及每个 cpu 核的具体情况
我们一个个来看下
第一个 us 和第二个 sy 需要一起看,us 是指 用户空间占用 cpu 的时间百分比,sy 是指 系统空间占用 cpu 时间的百分比
这个怎么理解,我们先来看个图
将 linux 系统 分为三部分, 最底下是硬件配置,中间是系统空间,最上面是用户空间
进程在执行用户自己的代码时,则称其处于用户运行态,此时耗费的cpu的百分比为 us
而一个任务(进程)执行系统调用而陷入内核代码中执行时,称进程处于内核运行态,此时耗费cpu的百分比为 sy
用户代码与系统代码在内存中是 分开存储的,一般而言,系统代码存放在 内存的高位中。
在举个具体的事例而言,例如 我们要调用 java 的 httpclient 发送 http 请求,那么对 httpclient 代码的处理,参数的填写,这些动作的执行,都算是 用户空间的cpu耗费,而最后需要调用网卡驱动去发送网络信号,这些,则算是系统空间的 cpu 耗费。
再举一个网上的事例,如下图所示:
我们在cp文件时,需要先将文件拷贝到 内核空间的 Buffer 上,在拷贝到用户空间的 buffer 上,在返过来,从用户空间的 buffer上,到系统空间的 buffer 上,在到磁盘上。
而在这个过程中,在系统空间耗费的cpu时间片 就是sy,而在用户空间的耗费则是 us 。
然后是 ni, ni我们看到了 全称是 nice ,用户进程空间内改变过优先级的进程占用CPU百分比,这个怎么理解,我们知道 现在的 cpu 是按照时间片来完成多任务的执行的,若每个进程的优先级相同,则每个进程执行的时间片分配的都是一致的,但实际情况是往往会有低优先级与高优先级的进程区分。
ni 对每个进程而言也是一个固定的值,负值表示高优先级,正值表示低优先级,数值从-20 (最高优先级)到 19 (最低优先级),我们可以通过改变进程的 ni 值 使之获取更多的 cpu 时间片,这个ni值默认是 0 。
而top第三行中 ni util% 指的就是 用户进程空间内改变过优先级使优先级变高的进程占用CPU百分比
the "nice" CPU percentage is the % of CPU time occupied by user level processes with a positive nice value
这个 ni 后面还要讲,这里先点到为止。
wa 是等待磁盘读写消耗的cpu时间,在 磁盘写入时,cpu需等待磁盘写入完成才可以进行下一部操作
上图为在做 大文件拷贝时的 wa 资源消耗
那么也就是说 如果发现 top 命令下 wa 的比例特别高,需要考虑下 磁盘的写入是否特别大,针对业务来讲就是要看下日志输出是否过多,引起的 cpu 消耗过多
然后是 hi si ,hi si 是硬中断软中断耗费的 cpu 时间。
硬中断是由外部硬件发起的 cpu 中断信号,由中断控制器提供,如网卡来数据了,键盘按键了之类都算是硬中断,硬中断的cpu消耗是正常的,但不会过大,出现了硬中断大量的时间消耗,一般是计算机硬件出问题了,需要 PE 关注或更换机器。
cat /proc/interrupts | grep eth0
上图是每个cpu核处理的网卡中断的数目,eth0 为网卡中断的标识, 可见只有 cpu 的第 0 核在处理网卡中断请求,若网络请求较大时, cpu0 的中断耗时也将增加
mpstat -I SUM -P ALL 5
上图是 cpu 每秒的中断数,包括软中断和硬中断
以下为网卡硬中断分cpu均衡的网络摘抄,作为辅助理解
在网络非常 heavy 的情况下,对于文件服务器、高流量 Web 服务器这样的应用来说,把不同的网卡 IRQ 均衡绑定到不同的 CPU 上将会减轻某个 CPU 的负担,提高多个 CPU 整体处理中断的能力;对于数据库服务器这样的应用来说,把磁盘控制器绑到一个 CPU、把网卡绑定到另一个 CPU 将会提高数据库的响应时间、优化性能。合理的根据自己的生产环境和应用的特点来平衡 IRQ 中断有助于提高系统的整体吞吐能力和性能。
至于软中断,只是比硬中断少了一个硬件发送信号的动作,其他与硬中断基本类似,
当前正在运行的代码(或进程)才会产生软中断。这种中断是一种需要内核为正在运行的进程去做一些事情(通常为I/O)的请求。
也就是说,系统中的 硬中断,软中断的cpu消耗是正常的,但如果大量的cpu消耗,则需要重点排查。
id 为空闲时间时间占比
st 这个项只有主机是虚拟机的时候,才会存在,全称为 steel ,意味着虚拟机从宿主机获取cpu时间片的耗时百分比
如果这个值过多,则需要查看宿主机的是否过多的分配虚拟机,引起资源不足
具体内容可以查看我的这篇文章:
http://www.atatech.org/articles/64560
top 的最后两行是与内存相关的信息
第一行 Mem 显示的是机器的真实内存数
第二行 Swap 显示的是交换内存数
Mem中,total 显示的是内存的总量, 这里的单位是大K , 也就约是 4g 左右内存总数,used 表示已使用内存数,free 是空闲内存数,buffer 是 buffer 内存数,chache 为 cache 的内存数。
Swap 中, total ,used ,free 三个参数的表示内存交换空间中的总量,已使用内存与空闲内存。
接下来一个个来整理下, total 内存总数, used+free = total ,前三个很好理解,无论是真实内存还是交换空间内存都一样,我们重点来看下 buffers 和 cache 这块的内存占用如何说明。
used 的内存占了将近 3.3g ,并不意味着机器内存全部被耗完,windows 下用多少申请多少内存,但 linux 下则不然,内存总是不嫌多的,linux 会将读取过的数据都缓存起来,以便下次读取时减少读取的时间。即使你的程序运行结束后,内存也不会自动释放。这就会导致你在 linux 系统中程序频繁读写文件后,你会发现可用物理内存变少。
而 cache 与 buffer 就属于linux系统的缓存内存,这部分的缓存内存在其他程序真实需要使用内存的时候,则会释放。所以程序真实使用的内存数应该是 used - buffer - cache ,就上图而言,应该是 3227588 - 76944 - 658276 = 2492368 大约是 2.4g 左右。
在 linux 上我们使用
free -m
同样可以看到这些信息,我们看第二行,第一列表示 used - cache - buffer ,第二列表示 free + cache + buffer
cache 与 buffer 的用途不同,cache 表示从硬盘中读取文件中到内存的缓存
例如 vim 打开一个 92 M 左右的问题
可以看到 cached 的增加了正好是 vim 打开文件的大小,而 free 也正好减少了打开文件的大小。
而 buffer 是用以处理两个系统间速度不均衡的缓存
网络上有人举的例子非常好,引用如下
OS处理网络数据的速度远超过网卡接收数据,因此需要一个Buffer,等存满了一次性交给OS
又比如从数据库获取数据很慢,所以对于不经常修改的数据,就一次性取出,放入Cache,将来就不去数据库取了
Buffer是待处理的数据,Cache是处理结果
top 最后一行是系统中所有系统的进程情况
我们来看下每一列的具体含义
PID 是进程的 进程号
USER 是启动进程的用户
pr 和 ni 都是与进程优先级相关的
ni 我们在之前已经讲过了,全称是 nice ,pr 的全称是 Priority
一个进程的整体运行优先级是 pr 值与 ni 值 相加
优先级 = ni + pr ,pr 默认值是20(默认权重因子) ,ni 的范围是-20至19,默认是 0
nice 的值可以按照命令或进程进行修改,使用 nice,renice 修改
优先级数值越小,优先级越高
使用
ps -axl
可以看到目前进程的优先级
renice -5 -p pid
可以修改已经存在进程的优先级
然后继续看
VIRT 表示 Virtual Memory 虚拟内存
RES 表示 Resident Memory 驻留内存
SHR 表示 shared memory 共享内存
RES 表示 进程占用的 物理内存数,实际使用数,而非申请的内存数
这里的 java 进程 res 占用是 1.1g 实际申请的内存大小是 1.7g
VIRT 表示 进程占用的 虚拟内存数
SHR 表示 进程共享的库的内存占用数,计算某个进程所占的物理内存大小公式:RES – SHR
S 是该进程的状态。其中S代表休眠状态;D代表不可中断的休眠状态;R代表运行状态;Z代表僵死状态;T代表停止或跟踪状态
%CPU 表示进程占用的 cpu 百分比
%MEM 表示进程占用的 内存 百分比
一些有用的 top 参数
top -H
可以显示所有的线程
top -Hp pid
可以显示指定进程的线程, 我们在对java进程进行排错的时候,也可先找到有问题的线程id,再通过 jstack 寻找问题,如下图所示