1. cpupower
可以设置 CPU 为 performance 模式来提高性能。
查看 CPU 支持的模式。
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors
设置为 performance 模式。
cpupower frequency-set -g performance
2. top
top - 12:20:32 up 18:33, 0 users, load average: 0.00, 0.00, 0.00
Tasks: 9 total, 1 running, 8 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 16345516 total, 15938648 free, 273724 used, 133144 buff/cache
KiB Swap: 4194304 total, 4194304 free, 0 used. 15840516 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 1744 1088 1016 S 0.0 0.0 0:00.00 init
7 root 20 0 1764 76 0 S 0.0 0.0 0:00.00 init
8 root 20 0 1764 92 0 S 0.0 0.0 0:00.05 init
9 k 20 0 75332 11712 4500 S 0.0 0.1 0:02.33 zsh
13 k 20 0 58876 5144 2092 S 0.0 0.0 0:00.00 zsh
53 k 20 0 75612 6764 1332 S 0.0 0.0 0:00.00 zsh
54 k 20 0 75596 5424 0 S 0.0 0.0 0:00.30 zsh
56 k 20 0 4536 1000 884 S 0.0 0.0 0:00.94 gitstatusd-linu
94 k 20 0 45728 3712 3228 R 0.0 0.0 0:00.00 top
执行命令
uptime
也能得到与命令top
结果第一行一样的结果。命令w
和命令cat /proc/loadavg
也能得到类似的结果。
2.1 指标说明
A Guide to the Linux “Top” Command
2.1.1 系统时间、正常运行时间和用户会话
12:20:32 up 18:33, 0 users
表示系统时间、正常运行时间和用户会话。
可以使用
who
命令来查看当前那些用户在线。
2.1.2 内存使用情况
KiB Mem : 16345516 total, 15938648 free, 273724 used, 133144 buff/cache
KiB Swap: 4194304 total, 4194304 free, 0 used. 15840516 avail Mem
KiB Mem
和 KiB Swap
后的 total
、 free
以及 used
分别表示系统内存和交换区总大小、可用大小、已使用的大小。
avail Mem
表示不使用交换分区的情况下,可以分配给进程使用的大小。
buff/cache
系统使用的缓冲区和缓存的总和。
buff
表示内核缓冲区使用的内存,cache
表示页缓存和 slab 使用的内存。可以通过
man free
命令来获取详细的说明。
What do the “buff/cache” and “avail mem” fields in top mean?
2.1.3 任务
Tasks: 9 total, 1 running, 8 sleeping, 0 stopped, 0 zombie
在 Linux 中,进程可能处于以下状态:
- 可运行 (R,Runnable):处于这种状态的进程要么在 CPU 上执行,要么出现在运行队列中,准备执行。
- 可中断睡眠 (S, Interruptible sleep):处于此状态的进程正在等待事件完成。
- 不间断睡眠 (D, Uninterruptible sleep):在这种情况下,进程正在等待 I/O 操作完成。
- 已停止 (T, Stopped):这些进程已被作业控制信号(例如按 Ctrl+Z)停止或因为它们正在被跟踪。
- 僵尸(Z, Zombie):内核在内存中维护各种数据结构以跟踪进程。一个进程可能会创建多个子进程,并且它们可能会在父进程还在时退出。但是,必须保留这些数据结构,直到父进程获得子进程的状态。这种数据结构仍然存在的终止进程称为僵尸进程。
D 和 S 状态的进程显示为 sleeping ,T状态的进程显示为 stopped 。僵尸的数量显示为 zombie 值。
top
命令默认显示的是进程相关的信息,可以按SHIFT + H
键切换到显示线程相关的信息。
2.1.4 CPU 使用率
%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
CPU 使用率部分显示了用于各种任务的 CPU 时间百分比:
us, user
是 CPU 在用户空间中执行进程所花费的时间(time running un-niced user processes)。sy, system
是运行内核空间进程所花费的时间。ni, nice
是使用手动设置的 nice 执行进程所花费的时间(time running niced user processes)。Linux 使用 nice 值来确定进程的优先级。具有高 nice 值的进程对其他进程更好,并获得低优先级。同样,具有较低 nice 的进程获得更高的优先级。可以手动更改默认的 nice 值。
id, idle
是 CPU 保持空闲的时间。wa, IO-wait
是 CPU 等待 I/O 完成所花费的时间。hi, hardware interrupts
是处理硬件所花费的时间。si, software interrupts
是处理软件所花费的时间。st, stolen, time
hypervisor 从这个 vm 窃取的时间 (time stolen from this vm by the hypervisor)。在虚拟化环境中,一部分 CPU 资源分配给每个虚拟机 (VM)。操作系统检测到它何时有工作要做,但它无法执行它们,因为 CPU 在某个其他 VM 上很忙。以这种方式损失的时间量是被窃取时间。
2.1.5 平均负载
load average: 0.00, 0.00, 0.00
表示一分钟、五分钟和十五分钟内的系统的平均负载。
在 Linux 上,负载是在任何给定时刻处于 R 和 D 状态的进程数。平均负载值提供了一个相对衡量 CPU 必须等待事情完成的时间。
平均负载的解释也可以通过命令
man uptime
获得:System load averages is the average number of processes that are either in a runnable or uninterruptable state. A process in a runnable state is either using the CPU or waiting to use the CPU. A process in uninterruptable state is waiting for some I/O access, eg waiting for disk. The averages are taken over the three time intervals. Load averages are not normalized for the number of CPUs in a system, so a load average of 1 means a single CPU system is loaded all the time while on a 4 CPU system it means it was idle 75% of the time.
另外,平均负载是一个指数移动平均,意味着之前的负载平均值的一小部分被计入当前值。更多的细节:Examining Load Average。
如何理解 Linux 系统负荷呢?
为便于理解,把 CPU 想象成一个大桥,桥上只有一根车道(相当于 CPU 只有一个核),所有的车辆都要从这根到通过。
- 系统负载为 0,表示车道上一个车都没有。
- 系统负载为 0.5, 表示车道上一半的路段有车。
- 系统负载为 1,表示车道上全是车,但是所有车都能正常顺利的通行。
- 系统负载为 1.7,大桥已经被占满了(100%),后面等着上桥的车辆为桥面车辆的70%。
在多核系统上,需要将负载平均值除以 CPU 内核数以获得类似的度量。
区分 CPU 使用率和平均负载
High CPU utilization but low load average
- 平均负载是衡量一段时间内在内核运行队列中等待的任务数量。
- CPU 利用率是衡量当前 CPU 繁忙程度的指标。
单个 CPU 线程在 1 分钟内保持 100% 的 CPU 使用率可以让 1分钟平均负载
加 1。具有超线程(8 个虚拟内核)的 4 核 CPU 保持 100% 的 CPU 使用率 1 分钟可以让 1分钟平均负载
加 8。
2.1.6 任务区
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 1744 1088 1016 S 0.0 0.0 0:00.00 init
7 root 20 0 1764 76 0 S 0.0 0.0 0:00.00 init
8 root 20 0 1764 92 0 S 0.0 0.0 0:00.05 init
9 k 20 0 75332 11712 4500 S 0.0 0.1 0:02.33 zsh
13 k 20 0 58876 5144 2092 S 0.0 0.0 0:00.00 zsh
53 k 20 0 75612 6764 1332 S 0.0 0.0 0:00.00 zsh
54 k 20 0 75596 5424 0 S 0.0 0.0 0:00.30 zsh
56 k 20 0 4536 1000 884 S 0.0 0.0 0:00.94 gitstatusd-linu
94 k 20 0 45728 3712 3228 R 0.0 0.0 0:00.00 top
PID
进程 ID,一个唯一的正整数,用于标识进程。
USER
启动进程的用户的
有效(effective)
用户名(映射到用户 ID)。Linux为进程分配一个真实用户ID(real user ID)
和一个有效用户ID(effective user ID)
;后者允许进程代表另一个用户进行操作。(例如,非 root 用户可以提升为 root 以安装软件包。)PR 和 NI
NI 字段显示进程的 nice 值。PR 字段从内核的角度显示了进程的调度优先级。nice 值影响进程的优先级。
VIRT、RES、SHR 和 %MEM
这三个字段与进程的内存消耗有关。
- VIRT 是进程消耗的内存总量。这包括程序代码、进程存储在内存中的数据以及已交换到磁盘的任何内存区域。
- RES 是进程在 RAM 中消耗的内存,%MEM 表示该值占可用 RAM 总量的百分比。
- SHR 是与其他进程共享的内存量。
S
一个进程可能处于不同的状态。此字段以单字母形式显示进程状态。
D – 不间断睡眠,I – 空闲,R – 运行,S – 睡眠,T – 被作业控制信号停止,t – 在跟踪期间被调试器停止, Z – 僵尸。
TIME+
进程自启动以来使用的总 CPU 时间,精确到百分之一秒。
COMMAND
进程的名称。
2.1.7 Linux 内存类型
下面的内容意译自 top(1) — Linux manual page 中 Linux Memory Types 部分。
Linux 中有三种类型的内存,其中一种是可选的。
- 物理内存:一种有限的资源,代码和数据在执行或引用时必须驻留在其中。
- 交换文件(可选的):当物理内存不足时,可以存放修改后的(脏)内存并在以后检索的地方。
- 虚拟内存:一种几乎无限的资源,用于以下目标。
- 抽象,不受物理内存地址/限制。
- 隔离,每个进程在一个单独的地址空间。
- 共享,单个映射可以满足多个需求。
- 灵活性,为文件分配一个虚拟地址。
无论内存采用哪种形式,都作为内存页(page)管理(通常 4096 字节)。
每个内存页都被限制为下表中的一个象限中。物理内存和虚拟内存都可以包含这四个中的任何一个,而交换文件只能包含象限 1 和象限 3。象限 4 中的内存在修改后会作为进程自己的专用交换文件。
Private | Shared
1 | 2
Anonymous . stack |
. malloc() |
. brk()/sbrk() | . POSIX shm*
. mmap(PRIVATE, ANON) | . mmap(SHARED, ANON)
-----------------------+----------------------
. mmap(PRIVATE, fd) | . mmap(SHARED, fd)
File-backed . pgms/shared libs |
3 | 4
下面是对 top
命令中一些字段的解释:
%MEM
:RES
的值除以总物理内存。CODE
:象限 3 中pgms
的大小。DATA
:整个象限 1 中的值加上象限 3 中显示mmap
文件支持(File-backed)的内存页大小的和。RES
:任何占用物理内存的东西。从 Linux-4.5 开始,是以下三个字段的总和:RSan
:象限 1 中内存页的大小,包括象限 3 中之前修改过的内存页的大小。RSfd
:象限 3 加上象限 4。RSsh
:象限 2。
RSlk
:RES
中不能被换出内存的部分(所有象限)。SHR
:RES
中排除象限 1 ,但包括象限 2 和象限 4 以及部分象限 3。SWAP
:可能是除象限 4 外的其他象限中的任何内容。USED
:RES
和SWAP
的和。VIRT
:正在使用和/或保留的所有内容(所有象限)。
注意:虽然程序映像和共享库被认为是进程私有的,但在内核中被当做共享的(shared, SHR)。
2.2 关注指标
2.2.1 us
和 sy
us
低 和 sy
高的情况一般有两种:
- 用户态的代码写的很好,都压缩成了系统调用。
- 用户态的代码写的很差,导致全是小的系统调佣。
2.2.2 wa
wa
高表示硬盘或者网络 I/O wait 高。
2.2.3 si
网络压测时,很有可能会出现单个 CPU 的 si
很高的情况。优化思路就是让 si
均衡到多个 CPU 上,方式有:
RSS(Receive Side Scaling)
就是俗称的网卡多队列。需要网卡硬件支持。
把不同的流分散的不同的网卡多列中,至于网卡队列由哪个cpu处理还需要绑定网卡队列中断与 CPU。
队列应不超过机器上 CPU 物理核的数量。
还有一种叫XPS(Transmit Packet Steering)的技术:根据当前处理软中断的cpu选择网卡发包队列,适合于多队列网卡。主要是为了避免 CPU 由 RX 队列的中断进入到 TX 队列的中断时发生切换,导致 CPU cache 失效损失性能。
RPS(Receive Packet Steering)
网卡多队列的软件实现。
单队列网卡或者虚拟网卡,把该网卡上的数据流让多个 CPU 处理。
开启脚本:rps.sh
在 RPS 之上优化的版本叫 RFS(Receive Flow Steering)。
当流量需要传输到用户态处理时,用处理软中断的 CPU 去处理用户态的逻辑。主要是为了避免 CPU 由内核态进入到用户态的时候发生切换,导致 CPU cache 失效损失性能。
使用硬件加速版本的 RFS 叫 Accelerated RFS(Receive Flow Steering)。
Kernel Bypass
Kernel Bypass(内核旁路)是绕过Linux内核(TCPIP协议栈)的技术,不使用Linux内核子系统的功能,采用自己实现的相同功能的代码来处理,从用户空间直接访问和控制设备内存,避免数据从设备拷贝到内核,再从内核拷贝到用户空间。
Kernel Bypass目前主流实现方案有:DPDK、SolarFlare。
其他资料:
3. nmon
3.1 关注指标
3.1.1 内核指标(k
)
Kernel and Load Average ---------------------------------------------------------|
|Global-CPU-Stats----> 0.5% user Load Average CPU use since boottime |
| /proc/stat line 1 0.0% user_nice 1 mins 0.00 Uptime Days Hours Mins |
|100 ticks per second 0.5% system 5 mins 0.00 Uptime 0 17 15 |
|100%=1 CPUcoreThread 1195.6% idle 15 mins 0.00 Idle 0 17 939 |
| 1 RunQueue 0.0% iowait Uptime has overflowed |
| 0 Blocked 0.0% irq |
| 1731.3 Context 0.0% softirq 12 CPU core threads |
| Switch 0.0% steal |
| 0.5 Forks 0.0% guest Boot time 1635930655 |
| 1743.8 Interrupts 0.0% guest_nice 05:10 PM 03-Nov-2021 |
如果 Context Switch
比较高,可能代码中的 syscall
非常多,或者程序中线程非常多。
Interrupts
指标反应了中断的密集情况。
- 如果网络程序压测试,
Context Switch
和Interrupts
都非常高,说明网络发送的都是小包,没有批量发送(writev
)。
4. nload
nload -u H
用于看网卡实时网速。
PageUp
和PageDown
切换网卡。
5. tcpflow
更方便的实时解析网络数据包。比如解析 HTTP 协议:sudo tcpflow -c -e http
。
6. ifconfig
6.1 关注指标
主要关注每个网络下的 RX errors 0 dropped 0 overruns 0 frame 0
和 TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
这几个指标,判断网络是否出现丢包错误之类的。
7. netstat
7.1 关注指标
7.1.1 网络栈统计信息
想看内核网络栈的统计信息应用命令 netstat -s
,其他的方式会有比较大的负担。
统计信息中主要关注的有统计数据中关于重传的数据:netstat -s | grep -i retran
23919133 segments retransmitted
TCPLostRetransmit: 6168959
12901177 fast retransmits
4674395 retransmits in slow start
TCPSynRetrans: 3104
7.1.2 网卡 MTU 和统计信息
netstat -i
Kernel Interface table
Iface MTU RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg
docker0 1500 0 0 0 0 0 0 0 0 BMU
enp4s0 1500 117099502 0 45104 0 109843615 0 0 0 BMRU
lo 65536 323529 0 0 0 323529 0 0 0 LRU
8. ss
8.1 关注指标
8.1.1 连接的统计信息
想看 TCP 各个状态的连接数量:ss -s
。
8.1.2 TCP 连接的 timer 信息
命令 ss -et
可以看 TCP 上 keepalive 相关的信息。
8.1.3 TCP 连接上流量控制和拥塞控制的信息
命令 ss -it
可以看 TCP 连接上流量控制和拥塞控制的信息。
9. strace
sudo strace -p $pid
查看某个进程的系统调用。
10. perf
sudo perf top
是 on-cpu 系统分析工具。
on-cpu 时间即进程获得 CPU 使用权的时间,同理 off-cpu 即进程失去cpu使用权时度过的时间。
更多资料:
11. 其他工具
图片来源 Linux Performance
12. 查看指定进程使用的内存和有多少内存放在了 Swap 中
$ egrep '^(Swap|Size):' /proc/$pid/smaps
Size: 780 kB
Swap: 0 kB
Size: 8 kB
Swap: 0 kB
Size: 24 kB
Swap: 0 kB
Size: 80 kB
Swap: 0 kB
Size: 3460 kB
Swap: 0 kB
Size: 8 kB
Swap: 0 kB
其中 Size 表示进程使用的某块内存的大小,Swap 和 SwapPss 表示该内存被交换到 Swap 中的大小。