一、全书概览
性能调优常被称为"黑色艺术"——你得同时理解硬件架构、操作系统内核、应用程序行为以及它们之间的相互影响。这本书把这件"黑色艺术"拆成了五块拼图:操作系统原理 → 监控工具 → Benchmark 工具 → 瓶颈分析 → 系统调优。
赵永刚的背景是网络出身(思科 CCNA/CCNP),后来转向 Linux(红帽 RHCE/RHCA),所以这本书在操作系统原理的讲解上比较扎实,尤其在文件系统、I/O 子系统和网络子系统的细节上花了大量篇幅。
全书 5 章、约 280 页,结构很清晰:
| 章节 | 内容 | 实用度 | |------|------|--------| | 第1章 深入理解 Linux 操作系统 | 进程、内存、文件系统、I/O、网络原理 | ★★★★☆ | | 第2章 监控工具 | top/vmstat/iostat/sar/tcpdump 等 17+ 种工具 | ★★★★★ | | 第3章 Benchmark 工具 | CPU2006/STREAM/Bonnie++/Netperf | ★★★☆☆ | | 第4章 分析性能瓶颈 | CPU/内存/磁盘/网络四大子系统的瓶颈定位 | ★★★★☆ | | 第5章 调整操作系统 | 四大子系统的具体调优参数和方案 | ★★★★☆ |
客观评价: 这本书出版于 2015 年,以 Linux 2.6 内核和 RHEL 6 为蓝本,技术栈确实偏老。但性能优化的底层逻辑——进程调度、内存管理、I/O 电梯算法、TCP 流控——这些核心机制在后续内核版本中虽然实现有变化,原理并没有颠覆。书中的方法论(建立基线 → 定位瓶颈 → 逐个变量调整)到今天依然是正确的思路。把它当作 Linux 性能原理的入门教材,比当作实战手册更合适。
二、逐章要点
第1章:深入理解 Linux 操作系统
"进程是在处理器上执行的一个实例,进程可以使用任意资源以便内核可以处理完成任务。"
这一章是全书的基石,用将近 200 页的篇幅把 Linux 五大子系统从原理层面讲了一遍。不是那种泛泛的"概念介绍",而是真正深入到内核实现层面。
进程管理部分从 task_struct 进程描述符讲起,完整覆盖了进程的生命周期(fork → exec → exit → wait),线程的三种实现(LinuxThreads → NPTL → NGPT),以及进程优先级、上下文切换、中断处理的机制。进程状态机(RUNNING/STOPPED/INTERRUPTIBLE/UNINTERRUPTIBLE/ZOMBIE)讲得清楚,特别是僵尸进程的成因和清理方式,这是很多人容易忽略的知识点。
内存体系结构部分讲到了几个关键概念:页帧分配(4KB 为单位)、虚拟地址空间布局(32 位 3G 用户 + 1G 内核)、伙伴算法(2 的幂次方分块)、LRU 分页回收、swap 机制。swappiness 参数的调优建议(默认 60,建议 1-10)是实际运维中非常实用的知识点。
文件系统从 VFS 虚拟文件系统层讲起,逐个分析了 Ext2/3/4、XFS、Btrfs、JFS、ReiserFS 的设计差异。Ext4 的延迟块分配、多块分配、在线碎片整理等特性讲得比较详细。
磁盘 I/O 子系统把从 write() 系统调用到磁盘硬件执行写入的完整链路拆解了七步,这是理解 I/O 性能问题的基本框架。I/O 电梯调度算法(CFQ/Deadline/NOOP)的选择建议也很实际:桌面用 CFQ,数据库用 Deadline,SSD/SAN 用 NOOP。
网络子系统涵盖了 TCP/IP 栈、socket buffer、NAPI 机制、Netfilter、Offload 技术和 Bonding 模块。
性能度量标准这一节实际上是一个"指标速查表",列出了 CPU、内存、块设备、网络接口各自的关键度量指标,和第2章的监控工具形成对照关系。
| 子系统 | 关键原理 | 调优抓手 | |--------|----------|----------| | 进程 | task_struct、CFS 调度器、nice 值 (-20~19) | 进程优先级、CPU 亲和性 | | 内存 | 伙伴算法、LRU 回收、swappiness | swap 策略、大页内存 | | 文件系统 | VFS 层、日志机制、延迟分配 | 文件系统选型、挂载参数 | | I/O | 七步写入链路、电梯调度 | 调度算法选择、RAID 配置 | | 网络 | TCP/IP 栈、socket buffer、NAPI | 内核参数调优、网卡绑定 |
- [x] 理解进程从 fork 到 exit 的完整生命周期
- [x] 掌握伙伴算法和 LRU 分页回收机制
- [x] 了解 Ext3 三种日志模式的差异(全日志/顺序/回写)
- [x] 理解 I/O 电梯调度算法的选择依据
- [x] 了解网络数据从应用到网卡的完整路径
第2章:监控工具
"性能优化的第一步不是调优,而是观测。你无法优化你看不见的东西。"
这可能是全书最实用的一章。17 种工具逐一讲解,从最基础的 top、ps 到比较进阶的 sar、tcpdump、strace,每个工具都给出了命令示例和输出字段解读。
系统级工具:
- top/htop:实时查看 CPU 使用率、进程列表。书里强调了 top 中
%us(用户态)、%sy(内核态)、%wa(I/O 等待)的区别——很多人看到 CPU 使用率高就以为是计算瓶颈,实际上可能是在等 I/O。 - vmstat:系统性能诊断的"瑞士军刀"。procs(r/b 列)显示等待运行和被阻塞的进程数,这是判断系统负载是否健康的直接指标。
r值持续超过 CPU 核数就是过载信号。 - mpstat:多 CPU 场景下的细粒度分析工具,能看到每个 CPU 核的使用情况,定位是否存在单核热点。
- free:书中特别提醒,不要被"可用内存少"吓到——Linux 会把空闲内存用作 page cache,
free命令的-/+ buffers/cache行才是真正可用的内存。
I/O 工具:
- iostat:磁盘性能监控的核心工具。
%util超过 80% 意味着磁盘已经饱和,await(平均 I/O 等待时间)超过 20ms 通常说明存在性能问题。书中的解释比 man page 直白得多。 - sar:系统活动报告工具,可以收集历史数据并做趋势分析。配合 gnuplot 画图,是建立性能基线的好方案。
网络工具:
- netstat/ss:连接状态统计、socket 信息查看。ss 是 netstat 的现代替代品,速度更快。
- tcpdump/Wireshark:抓包分析的黄金组合。书里给出了常见过滤表达式的用法,这对排查网络延迟和数据包丢失问题很有帮助。
- iptraf:基于 ncurses 的实时网络流量监控。
进程级工具:
- strace:跟踪进程的系统调用。当应用程序响应变慢,但系统资源看起来正常时,用 strace 看它到底在等什么系统调用返回,往往能直接定位问题。
- ltrace:类似 strace,但跟踪的是库函数调用。
- pmap:查看进程的内存映射,帮助分析内存使用细节。
| 工具 | 用途 | 适用场景 | |------|------|----------| | top/htop | 实时进程监控 | 快速查看系统整体状态 | | vmstat | 系统级综合指标 | 判断 CPU/内存/I/O 瓶颈方向 | | iostat | 磁盘 I/O 统计 | 磁盘性能诊断 | | sar | 历史数据收集和趋势分析 | 建立性能基线 | | tcpdump | 网络抓包 | 排查网络问题和延迟 | | strace | 系统调用跟踪 | 应用程序性能分析 | | numastat | NUMA 内存统计 | 多路服务器内存访问优化 |
- [x] 掌握 vmstat 各字段的含义和诊断方法
- [x] 学会用 iostat 判断磁盘是否饱和
- [x] 了解 sar 的数据收集和历史回溯能力
- [x] 能用 strace 分析应用程序的系统调用行为
- [x] 掌握 tcpdump 常用过滤表达式
第3章:Benchmark 工具
"没有基准数据,你永远不知道优化到底是进步了还是退步了。"
Benchmark 是性能优化的参照物。没有基准数据,所谓的"优化"只是凭感觉。
CPU2006(SPEC CPU)是业界标准的 CPU 性能测试套件,包含了整数和浮点两套测试集。书中详细讲了安装、runspec 命令的使用和配置文件的编写。CPU2006 的测试结果以SPECint和SPECfp分数表示,是跨平台比较 CPU 性能的标准方式。
STREAM 专门测试内存带宽,测量可持续的内存复制速率。它测试四种操作:Copy、Scale、Add、Triad。在 NUMA 架构下,STREAM 的结果对评估内存访问模式特别有价值——远程内存访问的延迟可能是本地的 2-3 倍。
Bonnie++ 是磁盘和文件系统性能的综合测试工具,能测试顺序读写、随机读写、元数据操作(文件创建/删除)等多种场景。
Netperf 是网络性能测试的专业工具,支持 TCP_STREAM(批量数据传输)、TCP_RR(请求/响应模式)、UDP 等多种测试场景。书中花了大量篇幅讲 Netperf 的配置和使用,包括 CPU 使用率的计算方式、全双工测试等。
| 工具 | 测试对象 | 核心指标 | |------|----------|----------| | CPU2006 | CPU 计算能力 | SPECint / SPECfp | | STREAM | 内存带宽 | MB/s(Copy/Scale/Add/Triad) | | Bonnie++ | 磁盘 I/O | 顺序/随机读写速率、元数据操作 | | Netperf | 网络吞吐和延迟 | 吞吐量(MB/s)、事务率(TPS) |
这一章在实际工作中的使用频率不算高(大多数开发者不会经常跑 SPEC CPU2006),但建立"一切优化都要有数据支撑"的意识是这本书传达的重要理念。
- [x] 理解 Benchmark 测试的基本原理和意义
- [x] 了解 SPEC CPU2006 的测试方法和评分体系
- [x] 掌握 Bonnie++ 测试磁盘性能的用法
- [x] 学会用 Netperf 测试不同场景的网络性能
第4章:分析性能瓶颈
"高 CPU 使用率并不总是意味着 CPU 忙于工作,它可能在等待另一个子系统。"
这一章是方法论的核心,讲的是"如何系统化地找到性能问题的根源"。
瓶颈分析的流程:
- 了解你的系统:硬件配置、OS 版本、运行的服务、工作负载特征
- 备份:调优之前先备份,这是铁律
- 监控和分析:建立性能基线,收集数据
- 缩小范围:从 CPU/内存/磁盘/网络四个方向定位
- 逐一验证:每次只改一个变量,观察效果
书中给出了一套"问题收集问卷"——当有人报告服务器性能问题时,你应该问的十几个问题:什么症状?何时开始?能否复现?是间歇性还是持续性?做了什么变更?这些问题的框架在实际运维中非常实用。
四大子系统的瓶颈分析方法各有侧重:
CPU 瓶颈:先用 top 看谁是 CPU 消耗大户,再用 vmstat 看上下文切换频率(cs 列),高上下文切换率(> 几万/秒)往往意味着线程过多或锁竞争激烈。解决手段包括:renice 调整优先级、taskset 绑定 CPU 核、关闭不必要的服务。
内存瓶颈:重点看 swap 使用量和 page fault 频率。频繁的 swap in/out 会导致严重的性能劣化。调整 swappiness、使用 HugePages(对数据库类应用尤其有效)、限制单用户的资源使用。
磁盘瓶颈:这是生产环境中最常见的瓶颈类型。用 iostat 看 %util 和 await。解决手段包括:升级到更快的磁盘(SSD)、增加 RAID 中的磁盘数量、使用 LVM 条带化、添加内存增加 cache。
网络瓶颈:从物理层(网卡速率、双工模式匹配)到传输层(TCP 参数调优)逐层排查。网卡绑定(Bonding)提高带宽和冗余,调整 socket buffer 和 TCP 队列长度应对高并发。
| 子系统 | 关键指标 | 危险阈值 | |--------|----------|----------| | CPU | 上下文切换率(cs/s) | > 50000/s | | CPU | 运行队列长度(r) | > CPU 核数 | | 内存 | swap 使用量 | > 0(持续增长) | | 内存 | page fault | > 1000/s(major fault) | | 磁盘 | %util | > 80% | | 磁盘 | await | > 20ms | | 网络 | 重传率 | > 0.1% |
- [x] 掌握"建立基线 → 定位瓶颈 → 逐一调整"的方法论
- [x] 学会用 vmstat 的 cs 列判断上下文切换是否过高
- [x] 能用 iostat 的 %util 和 await 判断磁盘是否瓶颈
- [x] 了解网络瓶颈的逐层排查思路
第5章:调整操作系统
"绝不在生产服务器上开始调整设置。绝不在调整过程期间改变一个以上的变量。"
最后一章是全书的"操作手册",给出了四大子系统的具体调优参数。
调优原则(这是全书最有价值的几段话之一):
- 先评估、再调整;先备份、再动手
- 绝不在生产环境直接调优
- 每次只改一个变量——同时改两个参数,你永远不知道哪个起了作用
- 记录每一次变更和效果
处理器调优:进程优先级调整(renice)、CPU 亲和性绑定(taskset)、中断均衡(IRQ affinity)、NUMA 优化。NUMA 系统中,跨节点内存访问的延迟可能是本地的 2 倍以上,对数据库这种内存敏感型应用影响巨大。
内存调优:内核参数调优集中在 /proc/sys/vm/ 目录下。swappiness 控制 swap 倾向(0-100,推荐 1-10),dirty_ratio 和 dirty_background_ratio 控制脏页刷新策略,overcommit_memory 控制内存超分配策略。HugeTLBfs 对 Oracle、PostgreSQL 等使用大页内存的数据库应用有明显效果。KSM(Kernel Same-page Merging)在虚拟化环境中可以节省 10-30% 的内存。
磁盘调优:I/O 调度器的选择(CFQ/Deadline/NOOP/Anticipatory)取决于工作负载类型。文件系统选型方面,XFS 适合大文件和高并发 I/O,Ext4 适合通用场景,Btrfs 有快照和压缩功能但稳定性仍需关注。挂载参数(noatime、data=writeback 等)也能带来可测量的性能提升。
网络调优:这是参数最多、最复杂的部分。网卡绑定(Bonding)的七种模式(0-6),巨帧(MTU 9000 vs 默认 1500)的选择,socket buffer 大小的调整(net.core.rmem_max、net.core.wmem_max),TCP 连接队列(net.core.somaxconn、net.ipv4.tcp_max_syn_backlog),TCP keepalive 参数,BBR 拥塞控制算法的选择(虽然书中未涉及 BBR,但拥塞控制算法的选择确实重要)。
资源限制:ulimit、cgroup 等机制可以限制单个用户或进程的资源使用,防止"吵闹的邻居"问题。
| 子系统 | 关键参数 | 调优方向 | |--------|----------|----------| | 内存 | vm.swappiness | 降低 swap 倾向 | | 内存 | vm.dirty_ratio | 脏页刷新策略 | | 内存 | vm.overcommit_memory | 内存超分配控制 | | 磁盘 | elevator= | I/O 调度算法 | | 磁盘 | mount -o noatime | 减少元数据写入 | | 网络 | net.core.rmem_max/wmem_max | socket buffer 大小 | | 网络 | net.core.somaxconn | TCP 连接队列 | | 网络 | net.ipv4.tcp_tw_reuse | TIME_WAIT 复用 |
- [x] 牢记"每次只改一个变量"的调优铁律
- [x] 掌握 swappiness、dirty_ratio 等核心内存参数
- [x] 了解不同 I/O 调度算法的适用场景
- [x] 学会网络子系统的基本参数调优
- [x] 理解资源限制(ulimit/cgroup)的使用场景
三、关键概念速查
1. CFS(Completely Fair Scheduler)
Linux 2.6.23 引入的进程调度器,用"虚拟运行时间"(vruntime)来保证公平。每个进程的 vruntime 按实际运行时间除以权重递增,调度器总是选择 vruntime 最小的进程运行。O(1) 调度器是其前身,用优先级数组实现常数时间调度。
2. 伙伴算法(Buddy System)
Linux 物理内存分配的核心算法。将空闲内存按 2 的幂次方分成 11 个链表(1/2/4/8/.../1024 个页块),分配时找最小能满足需求的块,释放时与相邻空闲块合并。好处是分配/释放快、外部碎片少,缺点是内部碎片(请求 3 页会分配 4 页)。
3. LRU 分页回收
内核维护活跃和非活跃两个 LRU 链表。当内存紧张时,kswapd 内核线程从非活跃链表尾部开始回收页面。swappiness 参数决定回收时更倾向于回收文件页(低值)还是匿名页(高值)。swapiness=1 表示尽量不 swap,swapiness=60(默认)是平衡策略。
4. I/O 电梯调度(I/O Elevator)
内核块层对 I/O 请求的排序策略。CFQ 为每个进程维护独立队列,适合桌面/多媒体(公平性好);Deadline 保证请求在一定时间内被处理,适合数据库(避免 I/O 饥饿);NOOP 纯 FIFO,适合 SSD/SAN(设备本身有调度能力,内核再排就是画蛇添足)。
5. NUMA(Non-Uniform Memory Access)
多路服务器架构中,每个 CPU 节点有本地内存,访问本地内存快、访问远端内存慢。Linux 的 numactl 和 numastat 可以查看和绑定 NUMA 策略。对内存密集型应用(数据库、大数据),NUMA 感知的部署能带来显著的性能提升。
6. TCP 三次握手与 TIME_WAIT
TCP 连接关闭时,主动关闭方会进入 TIME_WAIT 状态(默认持续 60 秒×2 = 2MSL)。高并发短连接场景下,大量 TIME_WAIT 会耗尽端口。调优手段:tcp_tw_reuse=1 允许复用 TIME_WAIT 连接,tcp_tw_recycle(已被弃用,不建议使用)。
7. 脏页刷新(Dirty Page Flushing)
进程写入文件时,数据先写入 page cache(脏页),由内核线程(pdflush/flush)异步刷回磁盘。vm.dirty_ratio(占内存百分比,默认 20%)是脏页的硬上限,达到时进程会被阻塞同步写入。vm.dirty_background_ratio(默认 10%)是后台刷写的触发点。
四、核心框架/模型
USE 方法(Utilization, Saturation, Errors)
虽然书中没有明确提到 USE 方法这个名称(这是 Brendan Gregg 提出的),但全书的分析方法论本质就是 USE:对每个资源(CPU、内存、磁盘、网络),检查三个维度:
┌─────────────────────────────────────────────────┐
│ USE 分析模型 │
├──────────┬───────────────────────────────────────┤
│ 利用率 │ 资源忙碌时间的百分比(如 CPU %us+%sy) │
│ 饱和度 │ 资源的排队长度(如 vmstat 的 r 列) │
│ 错误数 │ 错误事件计数(如网络丢包、磁盘 I/O 错误)│
└──────────┴───────────────────────────────────────┘
性能优化闭环
建立基线 → 监控告警 → 定位瓶颈 → 制定方案 → 实施变更 → 验证效果
↑ │
└────────────────────────────────────────────────────┘
书中的五步流程和 USE 模型配合使用,构成了一个完整的性能工程方法论。
四大子系统诊断决策树
系统变慢
├── CPU:top 看 %us/%sy/%wa
│ ├── %us 高 → 应用程序计算密集
│ ├── %sy 高 → 内核态开销大(锁竞争/系统调用频繁)
│ └── %wa 高 → I/O 等待(实际是 I/O 问题)
├── 内存:free 看 available,vmstat 看 si/so
│ ├── available 低 → 内存不足
│ ├── si/so 高 → swap 频繁
│ └── page fault 高 → 缺页严重
├── 磁盘:iostat 看 %util 和 await
│ ├── %util > 80% → 磁盘饱和
│ ├── await > 20ms → I/O 延迟高
│ └── avgqu-sz 大 → 请求排队
└── 网络:netstat/ss 看连接状态,sar 看流量
├── 重传率高 → 网络质量问题
├── TIME_WAIT 多 → 短连接风暴
└── 丢包 → 缓冲区溢出或带宽不足
五、金句摘录
-
"性能调优有时被称为'黑色艺术',因为有效地调整一个系统,要求具有更深层次的知识,且需要了解一个系统的硬件和软件组成以及系统之间的相互作用。" — 全书开篇,定义了性能优化的难度和本质。
-
"高 CPU 使用率并不总是意味着 CPU 忙于工作,它可能在等待另一个子系统。当执行适当的分析时,要整体来查看系统和所有子系统。" — CPU 使用率的"欺骗性",很多新手会误判。
-
"绝不在生产服务器上开始调整设置。绝不在调整过程期间改变一个以上的变量。" — 调优的两条铁律,违反它们就是在给自己挖坑。
-
"管理虚拟内存的默认规则:分配所有有效空闲内存空间作为磁盘缓存。" — 解释了为什么 Linux 的"空闲内存"总是很少,以及为什么这不是问题。
-
"磁盘子系统是最常见的瓶颈。" — 作者根据实战经验给出的判断。十次性能问题里,至少有三四次最终指向磁盘 I/O。
-
"宁可在缩小分页缓存,也不改变分页移出进程拥有的分页。" — 内核的 swap 策略偏好:先回收文件缓存,最后才动进程的匿名内存。
-
"一个进程可以间接通过使用 nice 级别来修改实时优先级,高实时优先级的进程可以更多地占用 CPU 时间。" — nice 值不是"友好",是优先级调节。
六、行动清单
每天
- [ ] 登录服务器时快速扫一眼
uptime和free -h,建立对系统负载和内存状态的直觉 - [ ] 遇到"服务变慢"的反馈,先用
top和vmstat 1看 30 秒,判断瓶颈方向 - [ ] 检查
dmesg | tail看有无硬件错误或内核告警
每周
- [ ] 审查
sar历史数据,关注 CPU、内存、磁盘的趋势变化 - [ ] 检查磁盘使用率(
df -h)和 I/O 性能(iostat -x 1 3) - [ ] 检查网络连接状态(
ss -s),关注 TIME_WAIT 和 ESTABLISHED 数量 - [ ] 审查系统日志中的 OOM Killer 事件和 I/O error
每月
- [ ] 更新性能基线文档,记录系统配置变更和对应的性能变化
- [ ] 审查
swappiness、dirty_ratio等关键内核参数是否符合当前工作负载 - [ ] 检查文件系统碎片率(
e4defrag或xfs_db),必要时执行在线碎片整理 - [ ] 评估磁盘 I/O 调度器是否仍然适合当前存储设备(特别是做了 SSD 迁移之后)
- [ ] 检查
ulimit和 cgroup 配置,确认资源限制仍然合理
七、一句话总结
这本书的核心价值不在于具体的调优参数(那些会过时),而在于它建立了一套系统化的性能分析方法论——理解原理、建立基线、定位瓶颈、逐一验证——以及"不要猜,要测量"的工程态度。
八、读者热议
"内容有料但翻译感太重" 多位读者提到这本书的行文风格像是英文硬翻过来的,读起来不够流畅。不过考虑到作者的技术背景(网络工程师转型 Linux),这个问题可以理解。建议当工具书翻阅,不必通读。
"基于 RHEL 6 太老了,但原理不过时" 2015 年出版、基于 Linux 2.6 内核,确实和当前的生产环境(5.x/6.x 内核)有差距。CFS 调度器已经经历多次改进,I/O 调度器从 CFQ/Deadline/NOOP 演进到了 BFQ/mq-deadline/none,Btrfs 已经稳定可用。但进程管理、内存管理、文件系统的基本原理没有变,作为入门教材仍然有价值。
"更像红帽 EX442 考试参考书" 有读者指出这本书的内容结构和红帽 RHCA 中的 EX442(Red Hat Enterprise Performance Tuning)考试高度吻合。如果你正在准备这个考试,这本书确实是个不错的补充教材。但如果你已经是有经验的 SRE,可能会觉得内容偏基础。
"监控工具章节最实用" 这是得到最多正面反馈的部分。17 种工具的详细用法和输出解读,在日常运维中直接用得上。特别是 sar + gnuplot 的历史数据可视化方案,比很多现代监控工具的默认图表更灵活。
笔记生成:2026-04-28 by 喵喵 🐈
相关笔记
同作者仅有此篇 同主题: