香港服务器调度优化实战:通过EEVDF与NUMA亲和提升多核CPU任务处理效率

香港服务器调度优化实战:通过EEVDF与NUMA亲和提升多核CPU任务处理效率

上周五的凌晨 3 点,我一个人待在中环数据中心的冷风里,盯着 A5 数据香港裸金属服务器的监控大屏。业务峰值突然冲到 300 k RPS,TOP 里 load average 飙到 90+,然而 96 核 AMD EPYC 9654 的 CPU 利用率却只有 40 % 左右——明显是调度瓶颈而不是算力不足。那一刻我决定彻底重构内核调度策略,把多核 CPU 的每一滴性能都抠出来。下面就是我在 48 小时内完成调优、把平均延迟从 28 ms 压到 9 ms 的全过程。

1 . 实验环境与前置条件

组件 规格 备注
机型 A5 数据 Hong Kong BM-E9654-2P 2 × AMD EPYC 9654(96C/192T)、1 TiB DDR5-4800
内核 自编译 Linux 6.9.1 启用 EEVDF(Earliest Eligible Virtual Deadline First)调度器
系统 AlmaLinux 9.4 systemd 254,tuned 2.24
网卡 Mellanox ConnectX-6 Dx 100 GbE 驱动 mlx5 (DPDK 23.11 备用)
BIOS 设定 SMT = Enabled、NUMA = Enabled 关闭 C-State, P-State 使用 performance

注意:如果你仍在 5.x 内核,CFS 也能用同样方法调优;只是 EEVDF 在高并发小任务场景里抖动更小。

2 . 理论基础:Linux 调度器快速复习

调度类(sched_class)

  • SCHED_NORMAL (CFS / EEVDF) — 绝大多数用户态线程
  • SCHED_FIFO / SCHED_RR — 实时线程
  • SCHED_DEADLINE — 硬实时 / 嵌入式
  • NUMA 亲和:任务和内存必须黏在同一个 NUMA node 上,否则跨节点访问会带来 80-150 ns 的额外延迟。
  • 负载均衡周期:调度器周期性扫描 CPU run-queue,把负载迁移到空闲核。代价由 sched_migration_cost_ns 控制。

EEVDF 关键指标

  • 虚拟运行时间 vruntime → vdeadline
  • sched_latency_ns & sched_min_granularity_ns 决定时间片精度
  • 多队列平衡用 sched_slice_ns 替换了旧的 timeslice 概念

3 . 方案设计思路

目标 动作 工具/接口
减少跨 NUMA 任务迁移 设置 numactl --cpunodebindsystemd slice CPUAffinity NUMA API、cpuset cgroup
提升短任务周转 减小 sched_latency_nssched_min_granularity_ns /etc/sysctl.d/95-scheduler.conf
保留专核给软中断/DPDK 内核参数 isolcpus, nohz_full, rcu_nocbs GRUB CMDLINE
降低抢占抖动 调高 sched_migration_cost_ns,启用 sched_autogroup_enabled=0 sysctl
自动 profile tuned-adm profile hpc-sched(自定义) tuned

4 . 实操步骤

4.1 编译 6.9 内核并启用 EEVDF

dnf groupinstall -y "Development Tools"
dnf install -y ncurses-devel elfutils-libelf-devel openssl-devel bc
git clone --depth 1 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
cd linux
make menuconfig     # General Setup → Scheduler → [*] EEVDF CPU scheduler
make -j$(nproc) && make modules_install && make install
grub2-mkconfig -o /boot/grub2/grub.cfg

在 /etc/default/grub 追加:

systemctl set-property --runtime user.slice AllowedCPUs=0-79 \
   AllowedMemoryNodes=0   # 数据库实例只在 NUMA node 0
systemctl set-property --runtime service.slice AllowedCPUs=80-159 \
   AllowedMemoryNodes=1   # Web worker 在线程间更平衡

解释:把最后 32 个逻辑核隔离出来做 DPDK 和 NET-RX softirq,主业务线程跑在 0-159。

4.2 调整调度器 sysctl

# /etc/sysctl.d/95-scheduler.conf
kernel.sched_latency_ns           = 4000000      # 4 ms
kernel.sched_min_granularity_ns   = 1000000      # 1 ms
kernel.sched_wakeup_granularity_ns= 250000       # 0.25 ms
kernel.sched_migration_cost_ns    = 8000000      # 8 ms
kernel.sched_nr_migrate           = 64
kernel.sched_rr_timeslice_ms      = 1
kernel.sched_autogroup_enabled    = 0

即时生效:sysctl –system

4.3 NUMA 绑定与 cgroup v2

systemctl set-property --runtime user.slice AllowedCPUs=0-79 \
   AllowedMemoryNodes=0   # 数据库实例只在 NUMA node 0
systemctl set-property --runtime service.slice AllowedCPUs=80-159 \
   AllowedMemoryNodes=1   # Web worker 在线程间更平衡

如果需要细粒度,直接用 numactl -C 0-19 -m 0 ./my_worker。

4.4 自动化调优 tuned profile

cat >/usr/lib/tuned/hpc-sched/tuned.conf <<'EOF'
[main]
include=throughput-performance

[cpu]
governor=performance
isolated_cores=160-191

[scheduler]
sched_latency_ns=4000000
sched_min_granularity_ns=1000000
sched_wakeup_granularity_ns=250000
sched_migration_cost_ns=8000000
EOF

tuned-adm profile hpc-sched

4.5 可选:实时线程 (低抖动)

chrt -f 50 ./realtime_agent

或使用 systemd:

[Service]
CPUSchedulingPolicy=fifo
CPUSchedulingPriority=50

5 . 性能验证

指标 优化前 优化后 改善幅度
平均 P99 延迟 (ms) 28.3 9.1 -67.9 %
CPU 利用率 40 % 82 % +105 %
上下文切换 / s 540 k 310 k -42.5 %
cross-NODE traffic (MB/s) 8.7 1.2 -86.2 %

测试工具:wrk2 + perf stat -e sched:sched_switch,cache-misses,llc_misses.

6 . 故障排查速查表

现象 判断要点 解决方案
load 高但 CPU 低 进程频繁睡眠,被 CFS 抢占? 调低 sched_wakeup_granularity_ns
某 NUMA node 饥饿 numastat 页面失衡 重新分配 AllowedMemoryNodes
DPDK 收包丢失 隔离核不足 拓宽 isolcpus 区段或升级网卡固件
irqbalance 抢核 检查 /proc/interrupts 禁用 irqbalance,手动 smp_affinity

7 . 实践经验与技巧

  • 先升级内核再调参数——EEVDF 在高并发、小任务环境下的收益远超纯参数微调。
  • 把 NUMA 亲和当作一等公民;不绑定内存的优化都是耍流氓。
  • 隔离软中断核 + nohz_full 可以让业务线程获得“准实时”语义。
  • 针对不同业务写成独立 tuned profile,避免“一刀切”带来的次优。
  • 调优之后务必做基准并留好 rollback;调度类错误可能导致全局死锁。

从那天凌晨到现在,生产集群已经稳定跑了 9 天 12 小时,平均 CPU 利用率常年 80 % 以上,再没出现过调度瓶颈。希望我的这套方法能帮你把香港多核服务器的每一纳秒都榨干。祝你调优愉快!

未经允许不得转载:A5数据 » 香港服务器调度优化实战:通过EEVDF与NUMA亲和提升多核CPU任务处理效率

相关文章

contact