第二章 服务性能监控与分析
2.1 Linux服务器性能监控与分析
2.1.1 通过vmsat深挖服务器性能问题
vmstat是Virtual Meomory Statistics(虚拟内存统计)的缩写,可对操作系统的虚拟内存、进程、CPU活动进行监控。是对系统的整体情况进行统计,不足之处是无法对某个进程进行深入分析。
虚拟内存原理
我们知道,直接从物理内存读写数据要比从硬盘读写数据要快的多,因此,我们希望所有数据的读取和写入都在内存完成,而内存是有限的,这样就引出了物理内存与虚拟内存的概念。
物理内存就是系统硬件提供的内存大小,是真正的内存,相对于物理内存,在linux下还有一个虚拟内存的概念,虚拟内存就是为了满足物理内存的不足而提出的策略,它是利用磁盘空间虚拟出的一块逻辑内存,用作虚拟内存的磁盘空间被称为交换空间(Swap Space)。
作为物理内存的扩展,linux会在物理内存不足时,使用交换分区的虚拟内存,更详细的说,就是内核会将暂时不用的内存块信息写到交换空间,这样以来,物理内存得到了释放,这块内存就可以用于其它目的,当需要用到原始的内容时,这些信息会被重新从交换空间读入物理内存。
linux的内存管理采取的是分页存取机制,为了保证物理内存能得到充分的利用,内核会在适当的时候将物理内存中不经常使用的数据块自动交换到虚拟内存中,而将经常使用的信息保留到物理内存。
要深入了解linux内存运行机制,需要知道下面提到的几个方面:
首先,Linux系统会不时的进行页面交换操作,以保持尽可能多的空闲物理内存,即使并没有什么事情需要内存,Linux也会交换出暂时不用的内存页面。这可以避免等待交换所需的时间。
其次,linux进行页面交换是有条件的,不是所有页面在不用时都交换到虚拟内存,linux内核根据”最近最经常使用“算法,仅仅将一些不经常使用的页面文件交换到虚拟内存,有时我们会看到这么一个现象:linux物理内存还有很多,但是交换空间也使用了很多。其实,这并不奇怪,例如,一个占用很大内存的进程运行时,需要耗费很多内存资源,此时就会有一些不常用页面文件被交换到虚拟内存中,但后来这个占用很多内存资源的进程结束并释放了很多内存时,刚才被交换出去的页面文件并不会自动的交换进物理内存,除非有这个必要,那么此刻系统物理内存就会空闲很多,同时交换空间也在被使用,就出现了刚才所说的现象了。关于这点,不用担心什么,只要知道是怎么一回事就可以了。
最后,交换空间的页面在使用时会首先被交换到物理内存,如果此时没有足够的物理内存来容纳这些页面,它们又会被马上交换出去,如此以来,虚拟内存中可能没有足够空间来存储这些交换页面,最终会导致linux出现假死机、服务异常等问题,linux虽然可以在一段时间内自行恢复,但是恢复后的系统已经基本不可用了。
因此,合理规划和设计linux内存的使用,是非常重要的。
在系统中运行的每个进程都需要使用到内存,但不是每个进程都需要每时每刻使用系统分配的内存空间。当系统运行所需内存超过实际的物理内存,内核会释放某些进程所占用但未使用的部分或所有物理内存,将这部分资料存储在磁盘上直到进程下一次调用,并将释放出的内存提供给有需要的进程使用。
在Linux内存管理中,主要是通过“调页Paging”和“交换Swapping”来完成上述的内存调度。调页算法是将内存中最近不常使用的页面换到磁盘上,把活动页面保留在内存中供进程使用。交换技术是将整个进程,而不是部分页面,全部交换到磁盘上。
分页(Page)写入磁盘的过程被称作Page-Out,分页(Page)从磁盘重新回到内存的过程被称作Page-In。当内核需要一个分页时,但发现此分页不在物理内存中(因为已经被Page-Out了),此时就发生了分页错误(Page Fault)。
当系统内核发现可运行内存变少时,就会通过Page-Out来释放一部分物理内存。尽管Page-Out不是经常发生,但是如果Page-out频繁不断的发生,直到当内核管理分页的时间超过运行程式的时间时,系统效能会急剧下降。这时的系统已经运行非常慢或进入暂停状态,这种状态亦被称作thrashing(颠簸)。
[root@1a01vlb9935zzzz ~]# vmstat 1 10
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 6227816 5272 1458356 0 0 0 1 1 2 1 1 99 0 0
0 0 0 6227772 5272 1458356 0 0 0 0 1463 296 0 0 100 0 1
0 0 0 6227676 5272 1458356 0 0 0 37 484 331 0 0 100 0 0
0 0 0 6227040 5272 1458356 0 0 0 20 753 433 3 1 95 0 1
0 0 0 6226216 5272 1458356 0 0 0 0 494 374 0 0 99 0 0
0 0 0 6225752 5272 1458356 0 0 0 0 925 336 1 0 99 0 0
0 0 0 6226556 5272 1458360 0 0 0 0 626 464 2 1 97 0 1
0 0 0 6225280 5272 1458372 0 0 0 0 775 384 1 1 99 0 0
0 0 0 6226692 5272 1458372 0 0 0 52 1526 458 1 1 97 0 1
0 0 0 6226840 5272 1458384 0 0 0 0 790 459 1 1 98 0 0
vmstat 1 10 ,参数1代表每隔几秒,获取一次服务器数据,参数2代表获取几次
参数说明:
数据类别 | 数据项 | 说明 |
进程procs | r | 表示目前实际运行的指令队列中的数量,有多少任务需要CPU来执行,如果发现这个数据超过了CPU核数,就有可能出现CPU瓶颈了(需要结合CPU使用率数据指标分析),一般该数据超出CPU核数3个时,就比较高了,超过5个就很高了,如果超过10时,就很不正常,服务器状态就很危险。如果运行队列超过CPU核数过多,表示CPU很繁忙,通常会造成CPU的使用率很高。 |
b | 表示目前因为等待资源而阻塞运行的指令个数,比如等待I/O、内存交换,CPU等资源而造成了阻塞,该值如果过高,需要检查服务器上I/O、内存、CPU等资源是否出现了瓶颈。 | |
内存memory | swpd | 表示虚拟内存(swap)已使用大小。swap指的是服务器的物理内存不够用时,会把服务器物理内存中的部分空间释放出来,以供急需物理内存来运行的程序使用,而那些从物理内存释放出来的内容一般是一些很长时间没有什么实际运行的程序,这些内容会被保存到swap中,等这些程序要实际运行时,再从swap中恢复到物理内存中。swap一般使用的磁盘的空间,而磁盘的I/O读写一般会比物理内存慢很多,如果存在大量的swap读写交换,将会非常影响程序运行的性能。 虚拟内存已使用大小也就是已从物理内存切换出来的的内容大小(单位为k)。 需要注意的是,如果swpd的值大于0,并不表示服务器的物理内存不够用了,通常还需要结合si和so这两个数据指标,如果si和so还维持在0左右,那么服务器的物理内存还是够用的。 |
free | 表示空闲的物理内存大小(单位为k) ,也就是有多少物理内存没有被使用,free的数据不包含buff和cache这两列的数值。 | |
buff | 表示Linux系统缓冲区的内存大小(单位为k),一般对块设备的读写才需要缓冲区,一般内存很大的服务器,这个值都会比较大,操作系统会自动根据服务器的物理内存去调整缓存区使用的内存大小,以提高读写的速度 | |
cache | 表示用来给已经打开的文件作为缓存的内存大小,cache直接用来缓存我们打开的文件,把物理内存的一部分拿来作为文件和目录的缓存,这是为了提高程序执行的性能,当程序使用内存时,buffer/cached会很快地被使用;当空闲的物理内存不足时(free的内存不足),这些缓存的内存便会释放出来。 | |
虚拟内存swap | si | 表示每秒从虚拟内存(swap)中读入到内存中的数据或内容的大小,如果这个值长期大于0,则表示物理内存可能已经不够用了 |
so | 表示每秒从物理内存写入虚拟内存的数据或者内容的大小。 | |
磁盘IO | bi | 表示数据块(block)设备每秒读取的块数量,从磁盘读取数据这个值表示每秒读取了磁盘多少个block,这里的块设备指的是系统上所有的磁盘和其他块设备,linux默认块大小是1024字节(Byte) |
bo | 表示块设备每秒写入的快数量,往磁盘里写入数据,这个值表示每秒有多少个block写入了磁盘,bi和bo这两个值越大(如超过1024K),CPU在等待I/O的值也会越大。 | |
系统system | in | 表示每秒CPU的中断(interrupt)次数,包括时钟中断 |
cs | 表示CPU每秒上下文切换次数,如果调用系统函数,就会导致上下文切换,包括线程的切换和进程的上下文切换。这个值的要越小越好,如果太大了,要考虑调低线程或者进程的数量,例如在Nginx,Tomcat这种web服务中到底配置多少个线程和进程呢 ? | |
一般做性能压测时会进行几千甚至几万的并发调用,配置Web服务器的进程数可以由进程数或者线程数的峰值一直慢慢下调,直到性能压测发现cs到一个比较小的值,这时候线程和进程数就是比较合适的值了。系统调用也是如此,每次调用系统函数,我们代码就会进入内核空间,导致上下文切换,这个很消耗资源,要尽量避免频繁调用系统函数。上下文切换次数过多表示CPU大部分时间浪费在上下文切换操作上,导致CPU干正经事(CPU用户模式)的时间少了,CPU没用充分利用,这是不可取的,如果观察到in和cs的这两个指标都非常高,那就需要对系统进行性能调优了。 | ||
cpu | us | 表示用户模式cpu使用时间的百分比,该值一般越高,说明CPU被正常利用的越好。 |
sy | 表示系统内核进程执行占用CPU时间的百分比,sy值高,说明内核消耗CPU资源多,通常in、cs、I/O的操作频繁等过高,都会引起sy指标过高。 | |
id | 表示空闲CPU时间的占比,一般来说cs+us+sy =100,通常可以认为id是空间cpu的使用率,us是用户cpu使用率,sy是系统cpu使用率 | |
wa | 表示I/O 等待时间百分比,wa的值高时,说明I/O 等待比较严重,这可能是由于磁盘大量进行随机访问所造成的,也可能是磁盘出现了瓶颈(块操作非常频繁) | |
st | 表示CPU等待虚拟机调度的时间占比,这个指标在虚拟机中才会有,在物理机中,该值一般维持0。 |
vmstat的其他参数 :
[root@1a01vlb9935zzzz ~]# vmstat --help
Usage:
vmstat [options] [delay [count]]
Options:
-a, --active active/inactive memory # 显示活跃和非活跃的内存
-f, --forks number of forks since boot #显示操作系统从启动到至今的启动过的进程
-m, --slabs slabinfo # 查看slab信息,slab是linux的内存管理的分配器
-n, --one-header do not redisplay header # 只显示头部第一行信息
-s, --stats event counter statistics #显示内存相关的统计信息及多种系统操作发生的次数
-d, --disk disk statistics # 显示每一块磁盘的I/O相关信息
-D, --disk-sum summarize disk statistics # 显示磁盘的I/O汇总信息
-p, --partition <dev> partition specific statistics # 显示磁盘中某个分区的I/O读写信息
-S, --unit <char> define display unit # 使用指定单位显示
-w, --wide wide output # 调整显示方式,以更宽的列显示数
-t, --timestamp show timestamp # 显示时间戳
-h, --help display this help and exit
-V, --version output version information and exit
操作实例 :
[root@1a01vlb9935zzzz ~]# vmstat -a 2 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free inact active si so bi bo in cs us sy id wa st
1 0 0 6224844 416788 1037276 0 0 0 1 2 3 1 1 99 0 0
0 0 0 6224828 416788 1037400 0 0 0 0 364 277 0 0 100 0 0
0 0 0 6224952 416788 1037428 0 0 0 0 510 334 0 0 100 0 0
0 0 0 6224604 416788 1037440 0 0 0 6 1052 381 0 0 100 0 0
0 0 0 6224704 416788 1037440 0 0 0 0 488 358 0 0 100 0 0
[root@1a01vlb9935zzzz ~]# vmstat -f
18668995 forks
[root@1a01vlb9935zzzz ~]# vmstat -m
Cache Num Total Size Pages
isofs_inode_cache 102 102 640 51
xfs_dqtrx 0 0 528 31
xfs_dquot 0 0 488 33
xfs_ili 29760 29760 168 48
xfs_inode 33898 33898 960 34
xfs_efd_item 390 390 416 39
xfs_log_ticket 1056 1276 184 44
bio-3 1173 1428 320 51
.....
[root@1a01vlb9935zzzz ~]# vmstat -n
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 6224928 5272 1461004 0 0 0 1 2 3 1 1 99 0 0
[root@1a01vlb9935zzzz ~]# vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 6222468 5272 1461080 0 0 0 1 2 3 1 1 99 0 0
[root@1a01vlb9935zzzz ~]# vmstat -s
7907324 K total memory
216988 K used memory
1037348 K active memory
416792 K inactive memory
6224032 K free memory
5272 K buffer memory
1461032 K swap cache
4063228 K total swap
0 K used swap
4063228 K free swap
3303852 non-nice user cpu ticks
132 nice user cpu ticks
3443801 system cpu ticks
588923011 idle cpu ticks
41817 IO-wait cpu ticks
0 IRQ cpu ticks
52761 softirq cpu ticks
799968 stolen cpu ticks
445298 pages paged in
6840811 pages paged out
0 pages swapped in
0 pages swapped out
1259940674 interrupts
662750235 CPU context switches
1607132237 boot time
18669798 forks
[root@1a01vlb9935zzzz ~]# vmstat -d
disk- ------------reads------------ ------------writes----------- -----IO------
total merged sectors ms total merged sectors ms cur sec
vda 19780 44 890340 133870 1135292 118893 13682292 31496860 0 4747
sr0 36 0 256 17 0 0 0 0 0 0
dm-0 19017 0 819440 132266 1140638 0 13674052 62533285 0 5865
dm-1 136 0 6520 111 0 0 0 0 0 0
dm-2 174 0 5183 88 4 0 4096 32 0 0
[root@1a01vlb9935zzzz ~]# vmstat -D
5 disks
4 partitions
39143 total reads
44 merged reads
1721739 read sectors
266352 milli reading
2275934 writes
118893 merged writes
27360440 written sectors
94030177 milli writing
0 inprogress IO
10612 milli spent IO
[root@1a01vlb9935zzzz ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/VolGroup00-LVroot 76G 2.9G 73G 4% /
devtmpfs 3.8G 0 3.8G 0% /dev
tmpfs 3.8G 8.0K 3.8G 1% /dev/shm
tmpfs 3.8G 17M 3.8G 1% /run
tmpfs 3.8G 0 3.8G 0% /sys/fs/cgroup
/dev/vda1 497M 294M 204M 60% /boot
/dev/mapper/VGapp-LVapp 50G 33M 50G 1% /app
tmpfs 773M 0 773M 0% /run/user/0
[root@1a01vlb9935zzzz ~]# vmstat -p /dev/vda1
vda1 reads read sectors writes requested writes
243 53061 2061 4144
[root@1a01vlb9935zzzz ~]# vmstat -w -t 1 10
procs -----------------------memory---------------------- ---swap-- -----io---- -system-- --------cpu-------- -----timestamp-----
r b swpd free buff cache si so bi bo in cs us sy id wa st CST
1 0 0 6223760 5272 1461388 0 0 0 1 2 3 1 1 99 0 0 2020-12-22 16:36:23
0 0 0 6224216 5272 1461388 0 0 0 0 1156 373 1 0 99 0 0 2020-12-22 16:36:24
0 0 0 6219640 5272 1461392 0 0 0 16 718 452 1 1 98 0 0 2020-12-22 16:36:25
0 0 0 6219524 5272 1461392 0 0 0 0 848 913 1 1 98 0 0 2020-12-22 16:36:26
0 0 0 6224456 5272 1461400 0 0 0 0 560 495 1 0 99 0 0 2020-12-22 16:36:27
0 0 0 6224584 5272 1461400 0 0 0 0 1549 280 0 0 99 0 0 2020-12-22 16:36:28
0 0 0 6223716 5272 1461400 0 0 0 0 503 350 0 1 99 0 0 2020-12-22 16:36:29
0 0 0 6223716 5272 1461400 0 0 0 0 316 259 0 0 100 0 0 2020-12-22 16:36:30
0 0 0 6223468 5272 1461400 0 0 0 0 628 268 0 0 100 0 0 2020-12-22 16:36:31
0 0 0 6223468 5272 1461400 0 0 0 0 373 242 0 0 100 0 0 2020-12-22 16:36:32
2.1.2 通过mpstat分析服务器性能指标
mpstat是 Multiprocessor Statistics的缩写,是实时系统监控工具。其报告与CPU的一些统计信息,这些信息存放在/proc/stat文件中。在多CPU系统里,其不但能查看所有CPU的平均状况信息,而且能够查看特定CPU的信息。
mpstat直接使用,输出为从系统启动以来的平均值,mpstat 1 10 表示每隔1s获取一次数据,获取10次。
[root@1a01vlb9935zzzz ~]# mpstat
Linux 3.10.0-957.21.3.el7.x86_64 (1a01vlb9935zzzz) 12/22/2020 _x86_64_ (4 CPU)
05:10:46 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
05:10:46 PM all 0.55 0.00 0.58 0.01 0.00 0.01 0.13 0.00 0.00 98.72
[root@1a01vlb9935zzzz ~]# mpstat 1 10
Linux 3.10.0-957.21.3.el7.x86_64 (1a01vlb9935zzzz) 12/22/2020 _x86_64_ (4 CPU)
05:10:54 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
05:10:55 PM all 1.25 0.00 1.25 0.00 0.00 0.25 0.75 0.00 0.00 96.51
05:10:56 PM all 1.75 0.00 1.00 0.00 0.00 0.00 0.25 0.00 0.00 96.99
05:10:57 PM all 0.76 0.00 0.25 0.00 0.00 0.00 0.00 0.00 0.00 98.99
05:10:58 PM all 0.75 0.00 0.50 0.00 0.00 0.00 0.00 0.00 0.00 98.75
05:10:59 PM all 1.50 0.00 1.50 0.25 0.00 0.00 0.25 0.00 0.00 96.50
05:11:00 PM all 3.80 0.00 8.61 0.00 0.00 0.00 2.03 0.00 0.00 85.57
05:11:01 PM all 6.60 0.00 14.21 0.00 0.00 0.25 2.54 0.00 0.00 76.40
05:11:02 PM all 1.50 0.00 0.75 0.00 0.00 0.00 0.75 0.00 0.00 97.00
05:11:03 PM all 0.75 0.00 0.50 0.00 0.00 0.00 0.50 0.00 0.00 98.25
05:11:04 PM all 0.75 0.00 0.25 0.00 0.00 0.00 0.50 0.00 0.00 98.50
Average: all 1.93 0.00 2.86 0.03 0.00 0.05 0.75 0.00 0.00 94.38
[root@1a01vlb9935zzzz ~]#
参数说明 :
- %usr:表示的是用户模式下CPU使用时间的百分比。
- %nice : 表示CPU在进程优先级调度下CPU占用时间的百分比。在操作系统中,进程的运行可以设置优先级的,优先级越高,获得CPU运行的机会越高,这个值一般都是0.00, 但是在系统中如果修改过默认优先级,%nice就会产生占用时间百分比,在linux中执行top或者ps命令时,通常会输出PRI/PR、NI、%ni/%nice这三个指标
[root@1a01vlb9935zzzz ~]# top
top - 17:21:11 up 17 days, 7:43, 1 user, load average: 0.10, 0.07, 0.05
Tasks: 136 total, 1 running, 135 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.8 us, 0.4 sy, 0.0 ni, 98.8 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 7907324 total, 6221880 free, 218764 used, 1466680 buff/cache
KiB Swap: 4063228 total, 4063228 free, 0 used. 7365952 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1320 root 20 0 123684 9964 1404 S 2.0 0.1 175:13.39 OSWatcher7.sh
9 root 20 0 0 0 0 S 0.3 0.0 17:08.33 rcu_sched
1575 root 20 0 128272 5588 3444 S 0.3 0.1 35:02.15 YDService
1 root 20 0 191000 3984 2600 S 0.0 0.1 0:19.46 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.17 kthreadd
3 root 20 0 0 0 0 S 0.0 0.0 0:15.43 ksoftirqd/0
5 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H
7 root rt 0 0 0 0 S 0.0 0.0 0:54.57 migration/0
- PR:表示进程的优先级。值越小,优先级越高,会越早获得CPU的执行权
- NI : 这个表示进程的Nice值,表示进程可被执行的优先级修正数值,PRI值越小会越早被CPU执行,在加入Nice值后,新的PR值= 旧的PR+Nice值。Nice值越小,PR值就会越小,就会越早被CPU执行。在linux操作系统中,如果Nice的值相同,进程uid为root用户进程的执行优先级会更高,通常情况下,子进程会继承父进程的Nice值,在操作系统启动时init进程会被赋予0,其他进程会自动继承这个Nice值。
- %ni:表示改变过优先级的进程占用CPU的时间百分比,即可理解为Nice值影响了内核分配给进程的CPU时间片的多少。
- %sys : 表示系统内核进程执行时间百分比,该值越高,说明系统内核消耗CPU资源越多,和vmstat中的sy数据基本一致。
- %iowait :表示I/O等待时间百分比,该值越高,说明等待越严重,和vmstat的wa数据基本一致。
- %irq:表示用于处理系统中断的CPU百分比,硬中断时间,和vmstat的in数据类似,
- %soft:表示用户软件中断的CPU百分比,软中断时间,
- %steal:表示CPU等待虚拟机调用的时间占比,这个指标在虚拟机中才会用,在物理机中该值一般维持为0
- %guest:表示运行vCPU(虚拟处理器)时所消耗的CPU时间百分比
- %gnice:表示运行降级虚拟程序所使用的CPU占比
- %idle : 表示空闲CPU时间的占比。
vmstat和mpstat 命令的差别:mpstat 可以显示每个处理器的统计,而 vmstat 显示所有处理器的统计。因此,编写糟糕的应用程序(不使用多线程体系结构)可能会运行在一个多处理器机器上,而不使用所有处理器。从而导致一个 CPU 过载,而其他 CPU 却很空闲。通过 mpstat 可以轻松诊断这些类型的问题。
其他使用方式 :
- P : 指定某个CPU查看资源使用情况,ALL表示显示单个和所有的平均,也可指定CPU数字查看单个资源使用情况。
[root@1a01vlb9935zzzz ~]# mpstat -P ALL 2 5
Linux 3.10.0-957.21.3.el7.x86_64 (1a01vlb9935zzzz) 12/22/2020 _x86_64_ (4 CPU)
05:48:36 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
05:48:38 PM all 1.75 0.00 0.75 0.00 0.00 0.00 0.13 0.00 0.00 97.37
05:48:38 PM 0 1.01 0.00 0.50 0.00 0.00 0.00 0.00 0.00 0.00 98.49
05:48:38 PM 1 2.01 0.00 1.01 0.00 0.00 0.00 0.00 0.00 0.00 96.98
05:48:38 PM 2 1.50 0.00 0.50 0.00 0.00 0.00 0.00 0.00 0.00 98.00
05:48:38 PM 3 2.97 0.00 1.49 0.00 0.00 0.00 0.50 0.00 0.00 95.05
[root@1a01vlb9935zzzz ~]# mpstat -P 2 2 5
Linux 3.10.0-957.21.3.el7.x86_64 (1a01vlb9935zzzz) 12/22/2020 _x86_64_ (4 CPU)
05:49:33 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
05:49:35 PM 2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
05:49:37 PM 2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
05:49:39 PM 2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
05:49:41 PM 2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
05:49:43 PM 2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
Average: 2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
2.1.3 通过pidstat发现性能问题
pidstat 是linux操作系统中某个进程进行资源监控的一个常用命令,使用命令可以列出每个进程id占用的资源情况,如CPU,内存、设备IO、任务切换、线程等。
pidstat 直接执行显示系统所有进程的资源使用情况
[root@1a01vlb9935zzzz ~]# pidstat
Linux 3.10.0-957.21.3.el7.x86_64 (1a01vlb9935zzzz) 12/22/2020 _x86_64_ (4 CPU)
08:20:29 PM UID PID %usr %system %guest %CPU CPU Command
08:20:29 PM 0 1 0.00 0.00 0.00 0.00 0 systemd
08:20:29 PM 0 2 0.00 0.00 0.00 0.00 2 kthreadd
08:20:29 PM 0 11 0.00 0.00 0.00 0.00 0 watchdog/0
08:20:29 PM 0 719 0.00 0.00 0.00 0.00 0 irqbalance
08:20:29 PM 81 729 0.00 0.00 0.00 0.00 0 dbus-daemon
08:20:29 PM 0 740 0.00 0.00 0.00 0.00 0 systemd-logind
08:20:29 PM 997 742 0.00 0.00 0.00 0.00 0 polkitd
08:20:29 PM 0 747 0.00 0.01 0.00 0.01 0 watchdog
08:20:29 PM 0 934 0.00 0.00 0.00 0.00 1 atd
08:20:29 PM 0 937 0.00 0.00 0.00 0.00 3 crond
08:20:29 PM 0 1010 0.01 0.00 0.00 0.01 2 tuned
08:20:29 PM 0 1014 0.00 0.00 0.00 0.00 1 rsyslogd
08:20:29 PM 0 1320 0.65 0.05 0.00 0.70 1 OSWatcher7.sh
08:20:29 PM 996 1390 0.00 0.00 0.00 0.00 2 chronyd
08:20:29 PM 0 1511 0.01 0.01 0.00 0.01 2 OSWatcherFM7.sh
08:20:29 PM 0 1575 0.07 0.07 0.00 0.14 3 YDService
08:20:29 PM 0 1632 0.00 0.01 0.00 0.01 3 YDLive
08:20:29 PM 0 2072 0.00 0.00 0.00 0.00 1 sshd
08:20:29 PM 0 2978 0.00 0.00 0.00 0.00 2 python
08:20:29 PM 0 2993 0.09 0.24 0.00 0.34 2 python
... ... ...
- UID:用户ID
- PID:进程ID
- %usr : 进程对用户模式CPU使用时间的百分比
- %system : 进程对系统模式CPU使用时间的百分比
- %guest:进程在虚拟机(运行虚拟机处理器)中占用时间的CPU百分比
- %CPU :指定进程使用CPU时间的百分比
- CPU : 执行指定进程的CPU编号
- Command : 当前进程运行的命令
pidstat的其他使用方法 :
[root@1a01vlb9935zzzz ~]# pidstat --help
Usage: pidstat [ options ] [ <interval> [ <count> ] ]
Options are:
[ -d ] [ -h ] [ -I ] [ -l ] [ -r ] [ -s ] [ -t ] [ -U [ <username> ] ] [ -u ]
[ -V ] [ -w ] [ -C <command> ] [ -p { <pid> [,...] | SELF | ALL } ]
[ -T { TASK | CHILD | ALL } ]
- -d: 显示I/O的统计信息
- -h: 显示所有的活动的任务
- -l: 显示正在执行的命令以及该命令运行所有的参数
- -r: 显示每个进程的内存使用情况,主要是分页错误的内存使用率
- -p <pid> : 显示指定进程id的资源使用情况
- -d -p <pid> : 显示指定进程的I/O的使用情况
- -u :与直接执行pidstat命令获取信息一致
- -w:展示每个进程的cpu上下文切换次数
- -t : 显示进程以及进程对应线程的资源使用情况
- -s:显示每个进程的堆栈使用情况
[root@1a01vlb9935zzzz ~]# pidstat -d
Linux 3.10.0-957.21.3.el7.x86_64 (1a01vlb9935zzzz) 12/22/2020 _x86_64_ (4 CPU)
09:13:44 PM UID PID kB_rd/s kB_wr/s kB_ccwr/s Command
09:13:44 PM 0 1 0.14 0.42 0.05 systemd
09:13:44 PM 0 531 0.00 0.00 0.00 systemd-journal
09:13:44 PM 0 560 0.00 0.00 0.00 lvmetad
09:13:44 PM 0 566 0.01 0.00 0.00 systemd-udevd
09:13:44 PM 0 695 0.00 0.01 0.00 auditd
09:13:44 PM 0 719 0.00 0.00 0.00 irqbalance
09:13:44 PM 81 729 0.00 0.00 0.00 dbus-daemon
09:13:44 PM 0 740 0.00 0.00 0.00 systemd-logind
09:13:44 PM 997 742 0.00 0.00 0.00 polkitd
09:13:44 PM 0 747 0.00 0.00 0.00 watchdog
....
# 指定进程的I/O使用情况
[root@1a01vlb9935zzzz ~]# pidstat -d -p 1
Linux 3.10.0-957.21.3.el7.x86_64 (1a01vlb9935zzzz) 12/22/2020 _x86_64_ (4 CPU)
09:19:20 PM UID PID kB_rd/s kB_wr/s kB_ccwr/s Command
09:19:20 PM 0 1 0.14 0.42 0.05 systemd
- kB_rd/s :进程每秒从磁盘读取的数据大小,单位为KB
- kB_wr/s :进程每秒写入磁盘的数据大小,单位为KB
- kB_ccwr/s :进程写入磁盘被取消的数据大小,单位为KB
[root@1a01vlb9935zzzz ~]# pidstat -r
Linux 3.10.0-957.21.3.el7.x86_64 (1a01vlb9935zzzz) 12/22/2020 _x86_64_ (4 CPU)
09:21:24 PM UID PID minflt/s majflt/s VSZ RSS %MEM Command
09:21:24 PM 0 1 0.12 0.00 191000 3984 0.05 systemd
09:21:24 PM 0 531 0.05 0.00 55460 19820 0.25 systemd-journal
09:21:24 PM 0 560 0.00 0.00 337792 1480 0.02 lvmetad
09:21:24 PM 0 566 0.00 0.00 44848 2396 0.03 systemd-udevd
09:21:24 PM 0 695 0.00 0.00 55508 896 0.01 auditd
09:21:24 PM 0 719 0.20 0.00 21656 1232 0.02 irqbalance
09:21:24 PM 81 729 0.00 0.00 58064 2376 0.03 dbus-daemon
09:21:24 PM 0 740 0.02 0.00 26376 1768 0.02 systemd-logind
09:21:24 PM 997 742 0.00 0.00 538568 10220 0.13 polkitd
....
09:21:24 PM 0 77012 0.00 0.00 108352 1044 0.01 pidstat
[root@1a01vlb9935zzzz ~]# pidstat -r -p 1
Linux 3.10.0-957.21.3.el7.x86_64 (1a01vlb9935zzzz) 12/22/2020 _x86_64_ (4 CPU)
09:21:33 PM UID PID minflt/s majflt/s VSZ RSS %MEM Command
09:21:33 PM 0 1 0.12 0.00 191000 3984 0.05 systemd
- minflt/s:进程读取内存数据是,每秒出现的次要错误的数量。这些错误指的是不需要从磁盘载入内存的数据,一般是虚拟内存地址映射成物理内存地址所产生的page fault(页面数据错误)次数。
- majflt/s:进程读取内存数据时,每秒出现的主要错误的数量,这些错误指的是需要从磁盘(或虚拟内存)载入到内存的数据,当虚拟内存地址映射成物理内存地址时,相应的page数据在swap中,这样的page fault(页面数据错误) 为major page fault(主要页面数据错误),一般在物理内存使用紧张时才会产生。
- VSZ:进程占用虚拟内存大小,单位为KB
- RSS:进程占用物理内存大小,单位为KB
- %MEM:进程占用内存百分比
[root@1a01vlb9935zzzz ~]# pidstat -w
Linux 3.10.0-957.21.3.el7.x86_64 (1a01vlb9935zzzz) 12/23/2020 _x86_64_ (4 CPU)
09:50:38 PM UID PID cswch/s nvcswch/s Command
09:50:38 PM 0 1 0.06 0.00 systemd
09:50:38 PM 0 2 0.00 0.00 kthreadd
09:50:38 PM 0 3 0.20 0.00 ksoftirqd/0
09:50:38 PM 0 5 0.00 0.00 kworker/0:0H
09:50:38 PM 0 7 2.83 0.00 migration/0
09:50:38 PM 0 8 0.00 0.00 rcu_bh
09:50:38 PM 0 9 67.92 0.00 rcu_sched
09:50:38 PM 0 10 0.00 0.00 lru-add-drain
09:50:38 PM 0 11 0.25 0.00 watchdog/0
... ...
[root@1a01vlb9935zzzz ~]# pidstat -w -p 9
Linux 3.10.0-957.21.3.el7.x86_64 (1a01vlb9935zzzz) 12/23/2020 _x86_64_ (4 CPU)
09:50:53 PM UID PID cswch/s nvcswch/s Command
09:50:53 PM 0 9 67.92 0.00 rcu_sched
- cswch/s : 每秒主动进行CPU上下文切换的数量,一般由于需要的资源不可用而发生阻塞时,会自愿主动进行上下文切换
- nvcswch/s : 每秒被动进行CPU上下切换的数量,比如当进程在其CPU时间片内执行,然后由于CPU时间片调度被迫放弃CPU处理器时,会发生被动非自愿的上下文切换。
[root@1a01vlb9935zzzz ~]# pidstat -l
Linux 3.10.0-957.21.3.el7.x86_64 (1a01vlb9935zzzz) 12/23/2020 _x86_64_ (4 CPU)
09:52:25 PM UID PID %usr %system %guest %CPU CPU Command
09:52:25 PM 0 1 0.00 0.00 0.00 0.00 1 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
09:52:25 PM 0 2 0.00 0.00 0.00 0.00 3 kthreadd
09:52:25 PM 0 3 0.00 0.00 0.00 0.00 0 ksoftirqd/0
09:52:25 PM 0 7 0.00 0.00 0.00 0.00 0 migration/0
# 查看进程以及进程对应线程的资源使用情况
[appdeploy@x5-server-web-uat-6886ddc6d9-f2qkp deploy]$ pidstat -t
Linux 4.14.15-1.el7.elrepo.x86_64 (x5-server-web-uat-6886ddc6d9-f2qkp) 12/23/2020 _x86_64_ (48 CPU)
09:54:42 PM TGID TID %usr %system %guest %CPU CPU Command
09:54:42 PM 1 - 0.00 0.00 0.00 0.00 17 sh
09:54:42 PM - 1 0.00 0.00 0.00 0.00 17 |__sh
09:54:42 PM 17 - 0.97 0.38 0.00 1.35 24 java
09:54:42 PM - 19 0.06 0.00 0.00 0.06 21 |__java
09:54:42 PM - 20 0.01 0.00 0.00 0.01 31 |__java
09:54:42 PM - 21 0.01 0.00 0.00 0.01 27 |__java
09:54:42 PM - 22 0.01 0.00 0.00 0.01 3 |__java
09:54:42 PM - 23 0.01 0.00 0.00 0.01 35 |__java
09:54:42 PM - 24 0.01 0.00 0.00 0.01 11 |__java
09:54:42 PM - 25 0.01 0.00 0.00 0.01 33 |__java
09:54:42 PM - 26 0.01 0.00 0.00 0.01 8 |__java
09:54:42 PM - 27 0.01 0.00 0.00 0.01 28 |__java
09:54:42 PM - 28 0.01 0.00 0.00 0.01 9 |__java
09:54:42 PM - 29 0.01 0.00 0.00 0.01 6 |__java
09:54:42 PM - 30 0.01 0.00 0.00 0.01 31 |__java
......
# 查看指定pid的进程和线程的资源使用情况
[appdeploy@x5-server-web-uat-6886ddc6d9-f2qkp deploy]$ pidstat -t -p 17
Linux 4.14.15-1.el7.elrepo.x86_64 (x5-server-web-uat-6886ddc6d9-f2qkp) 12/23/2020 _x86_64_ (48 CPU)
10:00:15 PM TGID TID %usr %system %guest %CPU CPU Command
10:00:15 PM 17 - 0.99 0.39 0.00 1.39 24 java
10:00:15 PM - 17 0.00 0.00 0.00 0.00 24 |__java
10:00:15 PM - 19 0.06 0.00 0.00 0.06 21 |__java
10:00:15 PM - 20 0.01 0.00 0.00 0.01 30 |__java
10:00:15 PM - 21 0.01 0.00 0.00 0.01 23 |__java
10:00:15 PM - 22 0.01 0.00 0.00 0.01 3 |__java
10:00:15 PM - 23 0.01 0.00 0.00 0.01 5 |__java
10:00:15 PM - 24 0.01 0.00 0.00 0.01 33 |__java
10:00:15 PM - 25 0.01 0.00 0.00 0.01 30 |__java
# 查看指定pid的进程和以及进程对应的线程的内存使用情况
[appdeploy@x5-server-web-uat-6886ddc6d9-f2qkp deploy]$ pidstat -r -t -p 17
Linux 4.14.15-1.el7.elrepo.x86_64 (x5-server-web-uat-6886ddc6d9-f2qkp) 12/23/2020 _x86_64_ (48 CPU)
10:04:09 PM TGID TID minflt/s majflt/s VSZ RSS %MEM Command
10:04:09 PM 17 - 37.09 0.00 31764336 3800280 0.72 java
10:04:09 PM - 17 0.00 0.00 31764336 3800280 0.72 |__java
10:04:09 PM - 19 0.99 0.00 31764336 3800280 0.72 |__java
10:04:09 PM - 20 0.14 0.00 31764336 3800280 0.72 |__java
10:04:09 PM - 21 0.13 0.00 31764336 3800280 0.72 |__java
10:04:09 PM - 22 0.10 0.00 31764336 3800280 0.72 |__java
10:04:09 PM - 23 0.17 0.00 31764336 3800280 0.72 |__java
10:04:09 PM - 24 0.16 0.00 31764336 3800280 0.72 |__java
10:04:09 PM - 25 0.19 0.00 31764336 3800280 0.72 |__java
10:04:09 PM - 26 0.17 0.00 31764336 3800280 0.72 |__java
- TGID : 对应是PID ,进程ID
- TID : 指的是进程ID对应的线程ID
# 查看每个进程的堆栈使用情况
[root@1a01vlb9935zzzz ~]# pidstat -s
Linux 3.10.0-957.21.3.el7.x86_64 (1a01vlb9935zzzz) 12/23/2020 _x86_64_ (4 CPU)
10:06:06 PM UID PID StkSize StkRef Command
10:06:06 PM 0 1 132 56 systemd
10:06:06 PM 0 531 132 36 systemd-journal
10:06:06 PM 0 560 132 20 lvmetad
10:06:06 PM 0 566 132 44 systemd-udevd
10:06:06 PM 0 695 132 48 auditd
10:06:06 PM 0 719 132 20 irqbalance
10:06:06 PM 81 729 132 16 dbus-daemon
10:06:06 PM 0 740 132 32 systemd-logind
10:06:06 PM 997 742 132 24 polkitd
10:06:06 PM 0 747 132 132 watchdog
...
- StkSize : 进程保留在内存中的堆栈占用的内存大小,单位为KB,这些堆栈数据并不一定会被进程使用。
- StkRef :进程实际引用的用作堆栈的内存大小(即实际使用的堆栈空间大小),单位为KB。
[root@1a01vlb9935zzzz ~]# pidstat -U
Linux 3.10.0-957.21.3.el7.x86_64 (1a01vlb9935zzzz) 12/23/2020 _x86_64_ (4 CPU)
10:48:24 PM USER PID %usr %system %guest %CPU CPU Command
10:48:24 PM root 1 0.00 0.00 0.00 0.00 0 systemd
10:48:24 PM root 2 0.00 0.00 0.00 0.00 3 kthreadd
10:48:24 PM root 3 0.00 0.00 0.00 0.00 0 ksoftirqd/0
10:48:24 PM root 7 0.00 0.00 0.00 0.00 0 migration/0
10:48:24 PM root 9 0.00 0.07 0.00 0.07 2 rcu_sched
10:48:24 PM root 11 0.00 0.00 0.00 0.00 0 watchdog/0
10:48:24 PM root 12 0.00 0.00 0.00 0.00 1 watchdog/1
10:48:24 PM root 13 0.00 0.00 0.00 0.00 1 migration/1
10:48:24 PM root 14 0.00 0.00 0.00 0.00 1 ksoftirqd/1
....