全书术语
全书反复出现的术语。解释是本站自己写的,不是原书词汇表的翻译;中文是本站的译法,可能和译本不同,按英文和节号对。按英文字母排序。
active benchmarking主动基准测试
基准跑着的时候就用观测工具看系统,确认它测的确实是想测的东西,并找出限制它的瓶颈。和它相对的是跑完才看数字的被动基准测试。
第 12 章 §12.3.2
await平均 IO 时间
iostat 的一列:每次 IO 从进入块层到完成的平均时间(毫秒),包括在系统里排队和在设备上的时间。r_await、w_await 分开读和写。
第 9 章 §9.6.1
backlog (SYN / listen backlog)连接队列
Linux 给每个监听套接字两个队列:握手没完成的在 SYN 队列,握手完成、等应用 accept() 的在 accept 队列。后者的上限是 listen() 的 backlog 参数,会被 net.core.somaxconn 截断;满了内核就丢 SYN,客户端要等重传(Linux 上首次重传在 1 秒后,之后间隔加倍,也就是第 1、3、7 秒……)。
第 10 章 §10.3.7
bandwidth / throughput带宽 / 吞吐
带宽是链路、总线或控制器的传输速率上限;吞吐是此刻实际每秒传了多少。磁盘的吞吐 = IOPS × 平均 IO 大小。全双工网络两个方向各算各的。
第 9 章 §9.1;第 10 章 §10.1
BPF (extended BPF, eBPF)BPF
原本是加速 tcpdump 包过滤的内核小虚拟机,后来扩展成通用、安全的内核执行环境:程序加载前要过验证器,挂在 kprobe、uprobe、跟踪点、perf 事件上运行,用映射存结果。BCC 和 bpftrace 都建在它上面。
第 1 章 §1.7.3;第 3 章 §3.4.4
BPF mapBPF 映射
BPF 程序在内核里的存储,可以带键当哈希表用。bpftrace 里以 @ 开头,可以赋成 count()、hist() 这类汇总函数,程序结束时自动打印。
第 15 章 §15.2.4
BTF (BPF Type Format)BPF 类型格式
内核数据结构的类型信息,在 /sys/kernel/btf/vmlinux。fentry 探针和 libbpf-tools(CO-RE)都靠它,有了它就不用在机器上装内核头文件。
第 15 章
cache hit ratio缓存命中率
请求里在缓存中找到的比例。命中和未命中的耗时可以差两三个数量级,所以命中率差几个百分点,平均延迟就能差好几倍。
第 2 章 §2.3.14;第 8 章 §8.6.12
cgroup (control group)控制组
限制并统计一组进程用多少 CPU、内存、IO、进程数。cgroup v2 是一棵统一的树,每个 cgroup 一个目录(/sys/fs/cgroup/…),限额和用量都在目录里的文件里。
第 3 章 §3.2.16;第 11 章 §11.3.3
coefficient of variation (CV)变异系数
标准差除以均值,用一个数表示波动有多大。比较两次基准结果时,差别小于波动就说不出谁快。
第 2 章 §2.8.4
congestion window (cwnd)拥塞窗口
TCP 发送方自己估计的、不等 ACK 最多能有多少数据在路上。丢包后缩小,具体怎么涨怎么缩由拥塞控制算法决定(Linux 默认 CUBIC)。
第 10 章 §10.3.9
context switch (voluntary / involuntary)上下文切换(自愿 / 非自愿)
CPU 从一个线程换到另一个,要换寄存器和栈,换进程时还要换地址空间。自愿的是线程自己去等(锁、IO、睡眠);非自愿的是它还想跑却被换下(时间片用完、被抢占),CPU 饱和时大量出现。/proc/PID/status 和 pidstat -w 分开数这两种。
第 3 章 §3.2.2;第 16 章 §16.1.7
counter / statistic / metric计数器 / 统计 / 指标
计数器是软件里不断累加的整数;隔段时间读两次算出的速率、平均、百分位是统计;挑出来长期记录、画图、告警的统计是指标。业内三者常混用。
第 1 章 §1.7.1;第 4 章 §4.2.1
CPU bandwidth throttlingCPU 带宽限额与节流
每个周期(默认 100 毫秒)给一组进程一份 CPU 时间,所有线程合用,用完就停到下个周期。cgroup v2 写在 cpu.max,被掐的次数和时间在 cpu.stat 的 nr_throttled、throttled_usec。
第 11 章 §11.3.3
delay accounting延迟统计
内核开了 CONFIG_TASK_DELAY_ACCT 时,按任务记录等 CPU(调度延迟)、等块 IO、等换页、等内存回收的时间,用户态经 taskstats(基于 netlink)读出,iotop 的 IO% 就来自它。Linux 5.14 起默认关闭,要用启动参数 delayacct 或 sysctl kernel.task_delayacct=1 打开。
第 4 章 §4.3.3
direct I/O直接 IO
用 O_DIRECT 打开文件,读写绕过页缓存,直接变成块 IO;缓冲区、偏移、长度要对齐。它不等于同步写,没有 O_SYNC 那样的落盘保证。测盘本身时要用它。
第 8 章 §8.3.8
direct reclaim直接回收
空闲内存掉到最低水位时,申请内存的线程自己去回收、被阻塞,延迟直接算在请求上。sar -B 的 pgscand/s 和 drsnoop 能看到。
第 7 章 §7.3.2
dynamic instrumentation动态插桩
程序运行中修改内存里的指令,插入观测例程,可以插在几乎任何函数上。内核里是 kprobes,用户态是 uprobes。
第 1 章 §1.7.3
false sharing伪共享
两个不相干的变量落在同一条缓存行里,两个 CPU 各改各的,也会互相作废对方的缓存。办法是填充,让每个变量独占一条缓存行。
第 5 章 §5.2.5
flame graph火焰图
把采样得到的调用栈合并画成的图:每格是一个函数,下面是它的调用者,宽度是它出现在多少个样本里。横轴按函数名排序,不表示时间。
第 6 章 §6.7.3;第 5 章 §5.4.1
frame pointer帧指针
x86-64 上的 RBP、ARM64 上的 x29,把一个个栈帧串成链表,perf 和 BPF 工具默认靠它回溯调用栈。编译器优化掉它以后栈就断了,用 -fno-omit-frame-pointer 保留,或改用 DWARF 回溯。不建帧的叶子函数会让它的调用者从栈里消失。
第 5 章 §5.6.2;第 13 章 §13.9.3
FtraceFtrace
内核自带的一组剖析器和跟踪器,接口是 tracefs 下的文件:echo 写控制文件,cat 读结果。板子上没有 BPF 时,只要内核开了 ftrace 就能用。
第 14 章 §14.1
futexfutex
Linux 上用户态的锁、条件变量要阻塞或唤醒时用的系统调用。strace、off-CPU 剖析里大量的 futex 可能是锁竞争,也可能只是空闲线程在条件变量上等活儿(书里 MySQL 的例子是后者),要看调用栈分辨。
第 5 章 §5.4.2、§5.5.1
hist trigger直方图触发器
往跟踪事件的 trigger 文件写 hist:keys=…,内核按键累加,cat hist 读汇总。没有 BPF 时按进程、系统调用、内核栈计数就靠它。
第 14 章 §14.10
huge pages / THP大页 / 透明大页
2 MB 等大尺寸的内存页,扩大 TLB 的覆盖范围;可以预先配置,也可以由透明大页(THP)自动合并。
第 7 章 §7.6.2
I/O scheduler / blk-mqIO 调度器 / 多队列块层
块层里给 IO 排序、合并的部件(mq-deadline、BFQ、kyber、none)。blk-mq 按 CPU 分提交队列。
第 9 章 §9.4.4
I/O waitIO 等待
CPU 空闲、同时有线程在等磁盘 IO 的时间比例。它是 CPU 空闲的一部分,CPU 一忙就被挤掉,不能当磁盘的指标。
第 9 章 §9.3.11
interrupt中断
设备异步通知 CPU,打断当前执行,去跑一小段内核代码。Linux 把处理拆成上半部(尽快做完)和下半部(软中断等)。
第 3 章 §3.2.4
IOPS每秒 IO 次数
每秒完成的读写次数。单独一个数没意义,要连同 IO 大小、随机还是顺序、读写比和并发一起说。
第 9 章 §9.3.7
IPC (instructions per cycle)每周期指令数
一段时间里执行的指令数除以经过的 CPU 周期数,倒数是 CPI。低说明 CPU 多半在等内存,高说明指令跑得顺。高低的界线看处理器。
第 6 章 §6.3.7、§6.5.5
kprobe / kretprobe内核动态探针
可以挂在任意内核函数的入口、返回或指令偏移上,取参数和返回值。这些函数不是稳定接口,会随内核版本改名、被内联,脚本升级内核后可能失效。
第 4 章 §4.3.6;第 14 章 §14.6
latency延迟
等待花掉的时间。严格说是等着被处理的那段,也常指整个响应时间,说延迟时要讲清量的是哪一段。单位是时间,能相加、能相减,所以能估算去掉某一段之后加速比的上限。
第 1 章 §1.6;第 2 章 §2.3.1
latency outlier延迟离群值
延迟远高于大多数的个别请求或 IO。平均值里看不见,要看直方图、百分位或逐个跟踪。
第 2 章 §2.8.6;第 9 章 §9.1
Little’s lawLittle 定律
系统里的平均请求数 = 到达率 × 平均停留时间(L = λW),已知两个可以推出第三个。
第 2 章 §2.6.5
load average负载平均
正在用资源和排队等资源的任务数,做成 1、5、15 分钟的指数衰减平均。Linux 上还包括不可中断睡眠(D 状态)的任务,所以不只代表 CPU。
第 6 章 §6.6.1
logical / physical I/O逻辑 IO / 物理 IO
应用发给文件系统的 IO 和文件系统发给磁盘的 IO。因为缓存、预读、写回、日志和别的进程,两者常常对不上,会缩水、膨胀或间接发生。
第 8 章 §8.3.12
macro- / micro-benchmark宏基准 / 微基准
基准测试施加人造负载,量系统的反应。宏基准模拟真实的客户端请求;微基准只测一种操作(一种系统调用、一种 IO、一个函数),简单、好重复,但要自己判断它和真实负载的哪一部分有关。
第 1 章 §1.8;第 12 章 §12.2.1
MTU / MSS最大传输单元 / 最大报文段长度
MTU 是一帧最多多大,以太网常见 1500 字节,巨帧约 9000。MSS 是扣掉头部后一个 TCP 段能装的数据量。
第 10 章 §10.3.4
multimodal / bimodal distribution多峰 / 双峰分布
分布有两个以上的峰:缓存命中和未命中、快路径和慢路径。这时平均值落在谷里,谁也不代表,要看直方图或百分位。
第 2 章 §2.8.5;第 8 章 §8.6.18
mutex / adaptive mutex互斥锁 / 自适应互斥锁
只有持有者能进;拿不到的线程睡下,不占 CPU。自适应的先自旋一会儿,等不到再睡。
第 5 章 §5.2.5
namespace命名空间
内核按类别(PID、挂载、网络、主机名、用户等)过滤一组进程能看见的东西,是容器隔离的主要手段。容器里的 1 号进程在宿主上是另一个 PID。
第 11 章 §11.3.1
netlinknetlink 套接字
AF_NETLINK 地址族的套接字:用 send、recv 收发二进制结构向内核要信息,比解析 /proc 的文本麻烦,但效率更高,还能接收通知。ss、ip 都用它,比如 ss 走的是 NETLINK_SOCK_DIAG。
第 4 章 §4.3.4
noisy neighbor吵闹的邻居
同一台宿主机上大量占用共享资源的其他租户(虚拟机或容器),让你的服务跟它抢 CPU、缓存、磁盘。测试环境里常常没有,上线后常有。
第 11 章 §11.1.5
NUMA非一致内存访问
多插槽机器上每颗 CPU 挂着自己的内存,访问别的节点的内存更慢。numastat 看分配命中,numactl 绑定。
第 7 章 §7.3.1
observability可观测性
靠看来理解系统,不改变负载:计数器、剖析、跟踪三类工具。和施加负载的实验相对,生产环境先用观测。
第 1 章 §1.7
off-CPU analysisoff-CPU 分析
线程被切下 CPU 时记下栈和时刻,切回时算出睡了多久,按栈累加,可以画成 off-CPU 火焰图。开销跟着切换次数走;结果常被闲着等活儿的线程占满,要先滤掉。
第 5 章 §5.4.2
on-CPU / off-CPU在 CPU 上 / 不在 CPU 上
线程时间的两大块:在 CPU 上跑(用户态、内核态),和不在 CPU 上(排队、等 IO、等锁、睡眠)。CPU 剖析只采得到前一块。
第 5 章 §5.4.2
OOM killerOOM 杀手
内存实在腾不出来时,内核挑一个进程杀掉,dmesg 里会留下 Out of memory。cgroup 到了内存限额,也会在组内触发。
第 7 章 §7.3.2
overcommit过量分配
允许申请超过物理内存加 swap 的总量,靠按需分页兜着。malloc 很少失败,代价是真用不起时由 OOM 杀手收场。
第 7 章 §7.2.4
page cache页缓存
内核拿空闲内存缓存文件内容,命中时几微秒返回,应用要内存时再回收。free 里算在 buff/cache。
第 8 章 §8.4.3
page fault (minor / major)缺页(次缺页 / 主缺页)
访问还没映射的页时触发。不读盘的是次缺页,按需分配新页的次缺页就是 RSS 增长的足迹;要读盘的是主缺页。
第 7 章 §7.2.3
percentile百分位
p99 是 99% 的值都不超过它的那个数,用来量最慢的那一小撮;p50 是中位数。
第 2 章 §2.8.3
PMC (performance monitoring counter)硬件性能计数器
处理器里可以编程来计数的寄存器:周期、指令、缓存命中和未命中、分支预测失败等。perf stat 读的就是它们。虚拟机里常常拿不全。
第 4 章 §4.3.9;第 6 章 §6.4.1
profiling剖析
描绘目标的行为。CPU 剖析多用定时采样:每秒若干次记下正在运行的调用栈,统计时间花在哪些代码路径上。只能看到在 CPU 上的时间。
第 2 章 §2.3.13;第 6 章 §6.5.4
PSI (pressure stall information)压力停顿信息
Linux 4.20 加入的接口,在 /proc/pressure/ 下按 CPU、内存、IO 分别给出任务因等待资源而停顿的时间比例(10 秒、60 秒、300 秒的平均)。只反映饱和,不反映利用率。
第 6 章 §6.6.1;第 7 章 §7.5.2
PSS (proportional set size)按比例分摊的驻留大小
私有页加上共享页除以共享它的进程数。各进程相加不会重复计算,看 /proc/PID/smaps_rollup 或 pmap -X。
第 7 章 §7.2.9
random / sequential I/O随机 / 顺序 IO
按相邻两次 IO 在盘上的位置是否接续来区分。机械盘的随机 IO 要寻道加等旋转,比顺序 IO 慢得多;闪存的随机读和顺序读通常差不多。
第 9 章 §9.3.4
RED methodRED 方法
对每个服务查请求率(Rate)、错误(Errors)、耗时(Duration,看分布)。请求率能看出是负载问题还是服务自身的问题。
第 2 章 §2.5.10
response time响应时间
操作从发出到完成的全部时间,等于排队等待加上服务时间。
第 2 章 §2.1
RSS (resident set size)驻留集大小
进程此刻在物理内存里的页。包含共享库,所以各进程的 RSS 加起来会超过总内存。
第 7 章 §7.2.3
RTT (round-trip time)往返时间
一个包在两端之间来回一趟的时间。ping 量的是它的近似,ss -ti 的 rtt 是内核对每条连接的估计。
第 10 章 §10.3.5
saturation饱和度
资源的工作排不过来、在排队的程度。利用率到 100% 之后,多出来的需求就表现为饱和:队列长度、等待时间。
第 2 章 §2.3.12;第 6 章 §6.3.10
scheduler latency调度延迟
线程从可以运行到真正被调度到 CPU 上所等的时间,也叫运行队列延迟。CPU 饱和时它会变大,直接加到请求的延迟上。
第 6 章 §6.2.3、§6.6.16
socket buffer套接字缓冲区
每个连接各有一个发送缓冲区和一个接收缓冲区。ss 的 Send-Q、Recv-Q 是里面此刻还排着的字节数(应用写入后对端还没确认的、收到后应用还没读的),不是缓冲区的大小。Linux 在 tcp_rmem、tcp_wmem 给的范围内自动调整大小。
第 10 章 §10.3.6
softirq软中断
中断处理里推迟执行的下半部,网络收包主要在这里跑。mpstat 的 %soft 是它占的 CPU,/proc/softirqs 是各类软中断的计数;集中在一个核上说明收包没有摊开;量大时交给 ksoftirqd 内核线程。
第 3 章 §3.2.4;第 6 章 §6.6.18
stack trace调用栈
一串函数调用,通常当前函数(叶子)在上、根在下。系统调用期间分成用户栈和内核栈两截。
第 3 章 §3.2.7
swapping换出
Linux 指把匿名内存页换到 swap 设备或文件;传统 Unix 指把整个进程换出。vmstat 的 si、so 持续不为零是内存压力的信号。
第 7 章 §7.2.5
symbol table / debuginfo符号表 / 调试信息
把指令地址翻成函数名、行号要用的信息。发行版的二进制常被 strip,剖析里只剩十六进制地址;可以另装 -dbg、-dbgsym 包。
第 5 章 §5.6.1
synchronous write同步写
用 O_SYNC、O_DSYNC 打开文件,或者调 fsync,等数据落盘才返回。每次都要付一整次存储延迟,攒一批再 fsync 能分摊。
第 8 章 §8.3.7
system call系统调用
用户程序请内核做特权操作(IO、建进程等)的接口。每次都要进出内核一趟(模式切换),会阻塞的那些还会引起上下文切换。
第 3 章 §3.2.3
TCP retransmitTCP 重传
丢包后重发:一种是定时器超时后重发(之后指数退避),一种是收到重复 ACK 后快速重传;握手阶段的 SYN 重发从 1 秒起。重传是网络延迟离群值的常见来源。
第 10 章 §10.5.7
thread state analysis线程状态分析
把线程的时间分进几种状态(书里分九种),看哪种最多,再决定是剖析还是查等待。Linux 内核的状态较少,要靠 /proc 和几样工具拼出来。
第 5 章 §5.4.5
TIME_WAITTIME_WAIT 状态
主动关闭连接的一方要等一段时间,免得迟到的包被认成新连接的。短连接很多、目标又固定时,会占满本地的临时端口。
第 10 章 §10.5.7
tracefstracefs
Ftrace 的接口文件系统,挂在 /sys/kernel/tracing(挂了 debugfs 时也在 /sys/kernel/debug/tracing)。控制和输出文件都在里面,通常只有 root 能进。
第 14 章 §14.2
tracepoint跟踪点
内核开发者预先写进代码的静态观测点(系统调用进出、调度、块 IO……),带有名有类型的字段。接口相对稳定,换内核版本不容易失效,有跟踪点时优先用它。
第 4 章 §4.3.5;第 14 章 §14.5
tracing跟踪
按事件记录,保存下来或当场汇总。有专用的(strace、tcpdump),也有通用的(Ftrace、BCC、bpftrace),后者靠静态和动态插桩取事件。
第 1 章 §1.7.3
uprobe / uretprobe用户态动态探针
可以挂在任意用户程序或库函数的入口、返回上。每次触发都要陷入内核,比内核探针贵得多,被测函数很快时量出来的耗时会偏高。
第 4 章 §4.3.7;第 14 章 §14.7
USDT用户态静态跟踪点
程序作者预先埋在自己代码里的观测点,名字稳定,相当于用户态的跟踪点,靠 uprobe 激活。程序编译时要带上。
第 4 章 §4.3.8
USE methodUSE 方法
对每种资源(CPU、内存、磁盘、网络……)查利用率(Utilization)、饱和度(Saturation)、错误(Errors)三项,在排查早期找系统性的瓶颈。从资源清单出发,查不到的指标也留在清单上,提醒自己那是盲区。
第 2 章 §2.5.9
utilization利用率
一段时间里资源忙碌的比例(按时间算),或者已用容量的比例(按容量算)。CPU 的利用率要按每个核看,平均值会藏住单个满载的核;能并行处理请求的设备(SSD、阵列)忙到 100% 也未必饱和。
第 2 章 §2.3.11;第 6 章 §6.3.8
VFS虚拟文件系统
内核里各种文件系统共用的一层接口,也是统一观测文件系统操作的位置。
第 8 章 §8.4.2
virtual memory虚拟内存
每个进程自己的一片地址空间,第一次访问时才映射到物理内存页,所以虚拟大小可以远超物理内存。
第 7 章 §7.2.1
working set size (WSS)工作集大小
一段时间里实际被访问的数据量。比内存小时测到的主要是缓存,存储类基准必须写明这一项;工具一般只报 RSS,量 WSS 要专门的办法。
第 7 章 §7.2.10;第 12 章 §12.2.1
workload characterization负载特征分析
只看施加的负载:谁在压、为什么、压的是什么样、怎么随时间变。最大的收益常来自去掉不必要的工作。
第 2 章 §2.5.11
write amplification写放大
闪存只能按整块擦除再写,比擦除块小的写会引起额外的数据搬移,实际写到闪存的量大于主机写的量。
第 9 章 §9.4.1
write-back caching写回缓存
写进缓存就算完成,之后再异步写到介质(页缓存由 flusher 线程写回;磁盘、RAID 卡也有自己的回写缓存)。快,但掉电会丢还没写下去的数据。
第 8 章 §8.3.6;第 9 章 §9.2.2