一、性能优化的系统工程论
1.1 性能即资源利用效率
性能优化的本质不是「让代码跑得更快」,而是在正确的抽象层次上,诊断出系统资源瓶颈并消除之。一个 Linux 系统的性能水位由四大资源共同决定:CPU、内存、I/O(磁盘与网络)以及它们之间的交互效率。忽视任何一维都可能导致「优化悖论」——单点指标全局性能反而下降。
1.2 USE 方法论
Brendan Gregg 提出的 USE(Utilization-Saturation-Errors)方法是从系统而非进程角度切入的利器。对每一个硬件和软件资源,依次问三个问题:利用率是多少?饱和度(排队程度)如何?错误率怎样?当三个指标都处于健康区间时,该资源就不可能是瓶颈。
1.3 性能调优决策树
实际排查时应遵循「从外到内、从粗到细」的路径:应用层耗时剖析 → 系统调用追踪 → CPU 调度与中断分布 → 内存缺页与 NUMA 局部性 → 磁盘 I/O 调度与文件系统 → 网络栈缓冲区与拥塞控制。每一步都需要对应的观测工具,现代 Linux 的核心武器是 perf 与 eBPF。
二、CPU 调度深度分析
2.1 CFS 调度器核心行为
Linux 的完全公平调度器(CFS)不直接分配时间片,而是维护每个进程的虚拟运行时间(vruntime)。红黑树键值为 vruntime,每次调度选取 vruntime 最小的进程投入运行。vruntime 的增长速率与进程权重(由 nice 值映射)成反比:nice 值越低的进程,vruntime 增长越慢,获得的 CPU 时间越多。
CFS 的关键参数位于 /proc/sys/kernel/sched_*:
sched_latency_ns(默认 6ms):一次调度周期内所有可运行进程至少运行一次的预算时间。sched_min_granularity_ns(默认 0.75ms):单次调度的最小时长,避免上下文切换过于频繁。sched_wakeup_granularity_ns(默认 1ms):唤醒抢占粒度,新唤醒进程的 vruntime 需低于当前进程此值才会触发抢占。
2.2 调度延迟诊断
当系统负载高但 CPU 利用率并不饱和时(即 load average 高但 %idle 也高),往往是调度延迟问题。使用 perf sched 全家桶可以直接观测:
perf sched record -- sleep 30 记录 30 秒调度事件,perf sched latency 输出每个进程的平均调度延迟及最大等待时间,而 perf sched map 以矩阵形式展示 CPU 间迁移热点。若某进程 max delay 远超 sched_latency_ns,说明其时间片被过度抢占,需考虑亲和性或 cgroup 隔离。
2.3 CPU 亲和性与 NUMA 优化
在多路服务器上,「逻辑 CPU 近」不等于「内存近」。NUMA 架构下跨节点访问内存延迟可达本地节点的 1.5-2 倍。numastat -p

发表评论 取消回复