Linux多核调度需按业务特征调优:taskset绑定物理核+numactl限定NUMA节点可提升吞吐15%+;vm.zone_reclaim_mode=1和sched_migration_cost_ns调高至2000000分别降低跨节点延迟与迁移开销;chrt实时策略须慎用并配RLIMIT_RTTIME。

Linux默认的CFS(完全公平调度器)在通用场景下表现均衡,但面对数据库、实时计算或AI推理等负载时,多核利用率常出现“有的核跑满、有的核空闲”——这不是CPU不行,而是调度没对齐业务特征。
taskset绑定核心:为什么不能随便绑,又为什么必须绑
把关键进程固定到特定CPU核心(如数据库worker线程),能避免跨核迁移导致的L1/L2缓存失效,实测可提升15%+吞吐。但误绑会引发严重问题:
- IO密集型进程(如
rsync、pg_dump)绑在超线程逻辑核上,反而因共享ALU资源加剧争用 - 未排除中断(IRQ)占用的核心,会导致绑定后响应延迟飙升——建议先用
cat /proc/interrupts查高频率中断分布 - 绑单核却运行多线程程序(如Java应用未设
-XX:+UseParallelGC),线程仍会被调度器踢到其他核
推荐做法:用taskset -c 0-3绑定物理核(非逻辑核编号),再配合numactl --cpunodebind=0 --membind=0限定NUMA节点内存访问。
NUMA感知调度:跨节点内存延迟是隐形杀手
在4路以上服务器或国产鲲鹏/飞腾平台,跨NUMA节点访问内存延迟可达本地的2–3倍。单纯靠taskset不够,必须让进程和它用的内存“同地而居”:
- 用
numastat -p检查进程内存是否真的落在绑定节点上;若numa_hit占比低于85%,说明内存分配未对齐 - 启动时强制本地内存分配:
numactl --membind=1 --cpunodebind=1 ./app(注意--membind比--preferred更严格) - 内核参数
vm.zone_reclaim_mode=1可减少跨节点回收压力,但仅适用于内存充足场景,否则引发频繁OOM killer
某政务云平台通过ACPI参数acpi_enforce_resources=lax配合numactl,使跨节点延迟下降43%——这步常被跳过,却是高并发OLTP的分水岭。
sched_migration_cost_ns调优:别让调度器“过度热心”
内核默认认为进程迁移成本很低(/proc/sys/kernel/sched_migration_cost_ns约500000ns),于是频繁把轻量级线程在核间搬来搬去。这对缓存敏感型负载(如Redis、ClickHouse)极为不利:
- AI推理场景中,将该值调高至
2000000,可减少30%上下文切换开销,推理延迟下降22% - 调整前务必确认负载类型:Web服务(短连接+高并发)适合保持默认;长时计算任务(如FFmpeg转码)建议设为
1000000–3000000 - 临时生效:
echo 2000000 > /proc/sys/kernel/sched_migration_cost_ns;永久写入/etc/sysctl.conf需搭配sysctl -p
这个参数没有“标准值”,只看perf stat -e sched:sched_migrate_task输出的迁移事件频次——降到每秒个位数才算合理。
chrt设置实时策略:慎用SCHED_FIFO,但关键路径值得
对延迟敏感的进程(如高频交易网关、工业PLC通信模块),用chrt -f 50 ./gateway启用SCHED_FIFO可绕过CFS时间片限制,获得确定性调度。但风险极高:
- 一旦该进程陷入死循环或长时间不主动让出CPU,整个系统可能假死(连
Ctrl+C都无响应) - 必须搭配
RLIMIT_RTTIME限制其最大运行时间,例如在systemd服务中加RuntimeMaxSec=5 - 普通数据库(MySQL/PostgreSQL)不建议用实时策略——其内部已通过异步I/O和连接池规避了调度延迟
真正该用它的,是那些自己管理线程模型、且能保证不阻塞的用户态程序。用错比不用更糟。
多核调度不是“绑得越死越好”,而是让调度器理解你的负载意图:是缓存局部性优先?还是内存带宽优先?或是确定性延迟优先?看清/proc/cpuinfo里的core id和physical id映射,比盲目调参重要得多。











