Linux CPU 隔离与 NUMA 调优:给关键业务独占算力的实战指南

概述 线上跑着一个高频交易系统,P99 延迟平时 2ms,但偶尔飙到 20ms。CPU 使用率不高,内存充足,网络正常。查了一圈,发现是 CPU 调度器把关键线程踢到了另一个核上,L3 缓存全部 miss,延迟直接翻了 10 倍。 这种问题不是靠加资源能解决的。问题出在"共享"——所有进程共享 CPU 核心,调度器自由分配,谁也不知道哪个线程是延迟敏感的。 解决办法就是 CPU 隔离:把关键业务绑到专属核心上,不让别的进程碰。同时做 NUMA 调优,让 CPU 和内存在物理上"就近",避免跨节点访问带来的延迟翻倍。 这篇笔记覆盖从基础概念到生产实操的完整链路:isolcpus 内核参数、cpuset cgroup、taskset 绑核、NUMA 亲和性、中断绑核、以及组合使用的最佳实践。所有命令都在 Ubuntu 22.04(内核 5.15)和 CentOS 8 上实测过。 基础概念:为什么要隔离 CPU CPU 调度器是怎么工作的 Linux 默认使用 CFS(Completely Fair Scheduler,完全公平调度器)分配 CPU 时间。CFS 的设计目标是"公平"——每个进程根据权重获得 CPU 时间片,调度器在所有可用核心之间自由迁移进程。 听起来没问题,但对延迟敏感的场景是个灾难: 上下文切换开销:线程从 CPU A 迁移到 CPU B,L1/L2 缓存全部失效,需要重新从内存加载数据。一次迁移的代价是微秒级的延迟抖动。 缓存污染:其他进程跑在你的目标核上,把你之前缓存的数据挤出去,下次你的线程回来时全是 cache miss。 中断干扰:网卡中断、定时器中断随时打断你的线程。对于要求微秒级响应的系统,一次中断就是一次延迟尖峰。 NUMA 架构是什么 NUMA(Non-Uniform Memory Access,非统一内存访问)是多路服务器的标配架构。简单说就是:每个 CPU 插槽有自己的本地内存,访问自己的内存很快,访问别的 CPU 的内存要跨 QPI/UPI 总线,延迟翻倍。...

July 13, 2026 · 10 分钟 · 2091 字 · 徐保金

cgroup v2 完全指南:从架构原理到生产实践

概述 在云原生和容器化技术全面普及的今天,Linux cgroup(控制组)作为资源隔离和限制的内核基石,其重要性不言而喻。从 Docker 容器的内存限制到 Kubernetes Pod 的 CPU Requests/Limits,底层都依赖 cgroup 机制。然而,cgroup v1 的多层级架构、控制器行为不一致、线程模型混乱等历史包袱,让运维人员在生产环境中频频踩坑。 cgroup v2 作为对 v1 的彻底重构,采用单一层级树(unified hierarchy)架构,从根本上解决了 v1 的设计缺陷。自 Linux 4.5 引入以来,经过多个内核版本的迭代完善,cgroup v2 在 5.x 内核上已趋于成熟稳定。Ubuntu 22.04+、RHEL 9+、Debian 12+ 等主流发行版已默认使用 cgroup v2,Docker 和 Kubernetes 也已全面支持。 我将从 cgroup v2 的架构原理出发,深入讲解核心控制器的工作机制,结合 systemd 集成、Docker 容器限制、Kubernetes 场景等实战配置,最后覆盖 v1 到 v2 的迁移策略,帮助你在生产环境中驾驭这一关键技术。 cgroup v1 vs v2:为什么要重构 v1 的核心痛点 cgroup v1 在设计之初,每个控制器可以独立挂载在不同的层级树上。这带来了灵活性,但也埋下了大量隐患: 问题维度 v1 表现 影响 多层级架构 每个控制器可挂载在独立的层级树 进程在不同控制器中可属于不同 cgroup,管理视图割裂 线程模型 进程的线程可分散到不同 cgroup 资源计量混乱,难以准确归因 控制器间协调 各控制器独立运作 无法做跨资源的统一策略(如 CPU 和内存的联动) 委派安全 子 cgroup 委派权限粗粒度 容器逃逸风险,安全边界模糊 接口一致性 不同控制器文件命名和语义不统一 运维认知负担高,脚本维护困难 v2 的设计哲学 cgroup v2 的核心设计原则是单一层级树(unified hierarchy):整个系统只有一棵 cgroup 树,所有控制器挂载在同一棵树上。一个进程只属于一个 cgroup,该 cgroup 上可以同时启用 CPU、内存、IO 等多个控制器。...

July 23, 2024 · 17 分钟 · 3430 字 · 徐保金

Linux 进程调度器:CFS 原理与调优

概述 进程调度器是操作系统内核的核心组件,它决定了哪个进程在哪个 CPU 上运行、运行多长时间。Linux 自 2.6.23 起采用 CFS(Completely Fair Scheduler)作为默认调度器,经过多年演进,在 6.6 内核中又引入了 EEVDF(Earliest Eligible Virtual Deadline First)替代 CFS。本文深入理解 CFS 的工作原理、nice/cgroup CPU 控制、实时调度、CPU 亲和性等核心主题,并分享生产环境的调优经验。 CFS 调度器原理 设计哲学 CFS 的核心目标是"完全公平"——每个进程按照其权重比例获得 CPU 时间。与传统调度器基于时间片不同,CFS 使用"虚拟运行时间"(vruntime)来跟踪每个进程的 CPU 消耗: vruntime = 实际运行时间 × (NICE_0_LOAD / 进程权重) nice 值为 0 的进程权重为 1024(NICE_0_LOAD) nice 值越低,权重越大,vruntime 增长越慢,获得更多 CPU 时间 CFS 始终选择 vruntime 最小的进程运行 红黑树与调度队列 CFS 使用红黑树维护运行队列,按 vruntime 排序: [vruntime=50] / \ [vruntime=20] [vruntime=80] / \ [vruntime=10] [vruntime=35] 最左节点(vruntime 最小)是下一个被调度的进程 进程运行后 vruntime 增加,被重新插入红黑树 查找、插入、删除均为 O(log N) 调度周期与最小粒度 # 调度周期(目标延迟):所有进程在这段时间内至少运行一次 $ sysctl kernel....

May 29, 2024 · 7 分钟 · 1330 字 · 徐保金

Linux 内存管理机制与调优实战

概述 内存是 Linux 系统中最宝贵的资源之一。理解内核如何管理内存,不仅能帮助你定位 OOM、内存泄漏等线上故障,还能在容量规划和性能调优时做出更准确的决策。从虚拟内存模型出发,覆盖 Page Cache、Swap 策略、OOM Killer 原理、cgroup v2 内存限制、slab/shmem 调优等核心主题,并附带多个生产环境实战案例。 虚拟内存模型 地址空间分层 Linux 采用虚拟内存机制,每个进程拥有独立的虚拟地址空间: 层级 说明 用户态可见 用户空间 0x000000000000 ~ 0x00007FFFFFFFFFFF 是 非规范区 0x0000800000000000 ~ 0xFFFF7FFFFFFFFFFF 否(空洞) 内核空间 0xFFFF800000000000 ~ 0xFFFFFFFFFFFFFFFF 否 64 位系统下,用户空间理论上有 128TB(47 位地址),内核空间同样 128TB。实际可用受 TASK_SIZE 和 mm_struct 限制。 内存_zone 划分 内核将物理内存划分为多个 zone,不同 zone 有不同用途: $ cat /proc/zoneinfo | grep -E "^Node|pages free|high|normal|DMA" Zone 用途 典型场景 DMA 16MB 以下,旧 ISA 设备 DMA 几乎不用 DMA32 4GB 以下,32 位 DMA 设备 老硬件 Normal 4GB 以上,大多数内存分配 主要使用 Movable 可迁移页面,支持内存热插拔 虚拟化/大页 当 Normal zone 内存耗尽时,内核会从 DMA32 zone 借用页面(watermark 机制),但频繁借用会导致性能下降。...

May 9, 2024 · 8 分钟 · 1594 字 · 徐保金

systemd 服务管理深度指南

systemd 架构概述 systemd 是现代 Linux 发行版的事实标准 init 系统,从 2015 年起已取代 SysVinit 成为绝大多数主流发行版的默认 init。它不只是"启动服务的工具",而是一个完整的系统和服务管理器。 核心 unit 类型 systemd 通过 unit(单元)来管理系统资源,每种 unit 类型对应一种资源: unit 类型 扩展名 作用 service .service 系统服务(守护进程) socket .socket IPC 套接字(支持套接字激活) timer .timer 定时任务(替代 cron) target .target 服务组(类似传统 runlevel) mount .mount 文件系统挂载点 device .device 内核设备 path .path 文件路径监控(文件出现时触发服务) slice .slice cgroup 资源分配层级 target 与传统 runlevel 的映射 # 查看当前默认 target systemctl get-default # 通常输出: multi-user.target(对应 runlevel 3,多用户命令行模式) # 切换到图形界面(对应 runlevel 5) sudo systemctl isolate graphical....

February 13, 2024 · 5 分钟 · 935 字 · 徐保金