全书术语

全书反复出现的术语。解释是本站自己写的,不是原书词汇表的翻译;中文是本站的译法,可能和译本不同,按英文和节号对。按英文字母排序。

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

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