cfs调度器下kernel.sched_*参数需谨慎设置:sched_latency_ns不低于6ms,sched_min_granularity_ns建议1ms,须通过/etc/sysctl.d/99-sched-tuning.conf配置并用sysctl --system加载,且需结合绑核、numa亲和性及业务特征调优。

kernel.sched_* 参数怎么设才不翻车
直接改 kernel.sched_min_granularity_ns 或 kernel.sched_latency_ns 却没效果?大概率是参数被忽略、或和当前调度器不兼容。CFS(默认调度器)对这些参数敏感,但值设错反而会抬高延迟、加剧抖动。
常见错误现象:sysctl -w kernel.sched_min_granularity_ns=500000 后,top 里进程响应没变快,压测时 r 值(运行队列长度)反而飙升;或者 perf sched latency 显示平均延迟更高了。
- 先确认你用的是 CFS:
cat /sys/kernel/debug/sched_features | grep -o "CFS"—— 没输出说明可能启用了CONFIG_SCHED_FIFO或被chrt强制覆盖 -
kernel.sched_latency_ns不建议低于6000000(6ms),否则小核 CPU 容易过载;高并发 Web 服务可设为10000000(10ms),数据库类 IO 密集型建议保持默认24000000 -
kernel.sched_min_granularity_ns控制“最小调度时间片”,设太小(如100000)会导致频繁上下文切换;生产环境稳妥值是1000000(1ms) -
kernel.sched_migration_cost_ns默认500000,若观察到/proc/sched_debug中 migration 过多,可降至200000,但 NUMA 机器慎调
/etc/sysctl.d/ 下该放哪个文件名
写进 /etc/sysctl.conf 是最常踩的坑——在 Ubuntu 22.04+、RHEL 8+、Rocky 9 等系统中,它会被 /etc/sysctl.d/*.conf 静默覆盖,哪怕 sysctl -p 成功返回也不代表生效。
正确做法是新建独立配置文件,名字必须带数字前缀且按字母序加载:
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
- 推荐命名:
/etc/sysctl.d/99-sched-tuning.conf(数字越大越晚加载,能覆盖其他同名参数) - 内容示例:
kernel.sched_min_granularity_ns = 1000000 kernel.sched_latency_ns = 10000000 kernel.sched_migration_cost_ns = 200000
- 加载命令必须用:
sudo sysctl --system(不是sysctl -p),它会扫描整个.d/目录并合并 - 验证是否生效:
sysctl kernel.sched_min_granularity_ns,再检查/proc/sys/kernel/sched_min_granularity_ns值是否一致
为什么改了参数,perf 或 pidstat 还看不出变化
内核调度参数只影响 CFS 的决策逻辑,不改变进程实际运行行为本身。如果业务本身是单线程阻塞型(比如 Python 同步 HTTP 服务),再细的调度粒度也无意义;同样,如果 CPU 已经被 us 占满,调低 latency_ns 只会让争抢更激烈。
- 真正要看效果的指标:用
perf sched latency -s max查看最大调度延迟;或用pidstat -w 1观察cswch/s(每秒上下文切换)是否下降 - 必须配合业务特征:实时交易系统适合调低
sched_latency_ns;而批处理任务应保持默认,避免干扰吞吐 - 注意硬件约束:ARM 小核、低频 CPU(如 Intel Atom)对
min_granularity_ns 支持差,可能触发内核 WARN - 容器环境要额外确认:宿主机参数不影响容器内 namespace,若用
hostNetwork或privileged,需在容器启动时通过--sysctl显式传递
NUMA 机器上 sched_* 调优的隐藏门槛
在双路 Xeon 或 AMD EPYC 服务器上,单纯调小 sched_latency_ns 可能让进程在跨 NUMA 节点间反复迁移,导致内存访问延迟翻倍——这比调度延迟本身更伤性能。
- 先查拓扑:
numactl --hardware看 node 数量和 CPU 分布 - 关键动作:把关键进程绑核 + 绑内存,例如:
numactl --cpunodebind=0 --membind=0 your_app - 此时
kernel.sched_*参数只需微调(如仅降migration_cost_ns),重点靠numactl或taskset控制亲和性 - 误操作风险:在未绑定的情况下强行降低
sched_wakeup_granularity_ns,可能让唤醒的进程落到远端 node,numastat -p $(pgrep your_app)会显示大量numa_miss
调度参数不是“越小越好”,而是要匹配你的 CPU 架构、NUMA 布局和应用线程模型。一个没绑核的 Java 应用,调再细的 sched_min_granularity_ns 也救不了 GC 停顿带来的毛刺。










