4. 调度器参数全景:kernel.sched_* 关键参数列表与作用域(sysctl vs cgroup)
在 Linux 进程调度调优中,kernel.sched_* 参数是控制调度器行为的核心旋钮。这些参数分布在两个作用域:系统全局(sysctl) 和 控制组(cgroup)。理解它们的区别、层级关系以及适用场景,是精准调优 MySQL 查询延迟的前提。
核心原则:sysctl 参数设置全局默认值,cgroup 参数在子系统内覆盖或细化调度策略。对于数据库实例隔离场景,cgroup 级别的参数调整比全局修改更安全、更精准。
4.1 参数作用域对比:sysctl vs cgroup
下表从配置范围、生效时机、持久化方式、典型场景四个维度,对比两种作用域的核心差异:
| 对比维度 | sysctl(全局) | cgroup(局部) |
|---|---|---|
| 配置范围 | 整个系统所有进程 | 仅作用于 cgroup 内的进程组 |
| 生效时机 | 立即生效,重启后需重新设置或写入 /etc/sysctl.conf |
写入 cgroup 控制文件后即时生效,重启后随 cgroup 树重建 |
| 持久化方式 | /etc/sysctl.conf 或 /etc/sysctl.d/*.conf |
cgroup 配置文件(如 /etc/cgconfig.conf)或 systemd 单元文件 |
| 典型场景 | 统一调整调度器基础行为(如唤醒抢占、带宽控制) | 数据库容器/虚拟机隔离、延迟敏感型任务分组 |
调优提示:在 MySQL 专用主机上,优先使用 cgroup v2 的
cpu.weight 和 cpu.max 控制数据库进程组的 CPU 份额与上限,避免全局修改 kernel.sched_* 影响其他系统进程。
4.2 关键 kernel.sched_* 参数列表
以下参数是调度器调优的核心集合,按功能模块分组列出。每个参数均标注了作用域(G=全局 sysctl,C=cgroup 可覆盖)和典型值范围。
| 参数名 | 作用域 | 默认值 | 功能描述 | MySQL 调优建议 |
|---|---|---|---|---|
kernel.sched_min_granularity_ns |
G | 3000000 (3ms) | CFS 调度器的最小执行粒度,控制进程被抢占前的最短运行时间 | 对延迟敏感型查询,可适当降低至 1-2ms,减少调度切换开销 |
kernel.sched_latency_ns |
G | 18000000 (18ms) | CFS 调度周期,决定每个进程在周期内至少获得一次调度的总时间窗口 | 高并发 MySQL 场景可增大至 24-36ms,提升吞吐稳定性 |
kernel.sched_wakeup_granularity_ns |
G | 4000000 (4ms) | 唤醒抢占阈值,新唤醒进程需比当前进程虚拟时间小多少才触发抢占 | 降低至 1-2ms 可加速短查询唤醒,但需注意增加上下文切换 |
kernel.sched_migration_cost_ns |
G | 500000 (0.5ms) | 进程迁移代价估算,影响负载均衡器判断是否值得迁移进程 | NUMA 架构下可增大至 1-2ms,减少跨节点迁移导致的延迟抖动 |
kernel.sched_autogroup_enabled |
G | 1 | 自动分组功能,将同一会话的进程自动分配到调度组 | MySQL 专用主机建议关闭(设为 0),避免自动分组干扰手动调优 |
cpu.weight (cgroup v2) |
C | 100 | 控制组内 CPU 权重,决定相对份额 | MySQL 容器设为 200-500,确保数据库进程获得更高 CPU 比例 |
cpu.max (cgroup v2) |
C | max 100000 | 控制组 CPU 使用上限(配额/周期),格式:$quota $period |
设置 80000 100000 限制 MySQL 最多使用 80% CPU,防止突发占满 |
注意:
kernel.sched_autogroup_enabled 在桌面环境或多用户服务器上有用,但在数据库专用节点上,自动分组可能掩盖手动设置的 cgroup 权重效果。建议在调优前确认其状态。
4.3 参数层级关系:从全局到 cgroup 的覆盖链
调度器参数的生效遵循明确的层级覆盖规则。下图展示了从 sysctl 全局默认值到 cgroup 局部覆盖的完整链路:
从图中可以看出:sysctl 全局参数 为整个系统提供基准配置;cgroup v2 控制器 在子系统层面提供更精细的覆盖能力;最终 进程组 根据其 cgroup 配置获得差异化的调度行为。MySQL 进程组通常配置高权重和延迟敏感标记,而后台任务组则使用低权重。
4.4 参数生效验证方法
修改参数后,必须验证其是否按预期生效。以下是针对两种作用域的验证命令:
# 查看 sysctl 全局参数当前值
sysctl kernel.sched_min_granularity_ns
sysctl kernel.sched_latency_ns
sysctl kernel.sched_wakeup_granularity_ns
# 查看 cgroup v2 参数(以 MySQL 容器为例)
cat /sys/fs/cgroup/system.slice/docker-<container_id>.scope/cpu.weight
cat /sys/fs/cgroup/system.slice/docker-<container_id>.scope/cpu.max
# 使用 perf 观察调度事件(验证参数效果)
perf stat -e sched:sched_switch,sched:sched_wakeup -p <mysql_pid> sleep 10
验证要点:修改
kernel.sched_wakeup_granularity_ns 后,使用 perf 观察 sched:sched_switch 事件频率。如果频率显著上升,说明抢占阈值降低生效,但需评估上下文切换开销是否在可接受范围内。
4.5 参数调优的典型组合模式
针对 MySQL 查询延迟优化,以下组合模式经过生产环境验证:
| 调优目标 | sysctl 参数调整 | cgroup 参数调整 | 适用场景 |
|---|---|---|---|
| 低延迟优先 | sched_min_granularity_ns → 1mssched_wakeup_granularity_ns → 1ms |
cpu.weight → 500cpu.uclamp.latency_sensitive → 1 |
OLTP 在线交易,要求 P99 延迟 < 10ms |
| 吞吐优先 | sched_latency_ns → 24mssched_migration_cost_ns → 1ms |
cpu.weight → 200cpu.max → 90000 100000 |
OLAP 分析查询,追求 QPS 最大化 |
| 混合负载隔离 | sched_autogroup_enabled → 0 |
MySQL 组:cpu.weight → 400后台组: cpu.weight → 50 |
同一主机运行 MySQL + 监控/备份任务 |
风险提示:过度降低
sched_min_granularity_ns 和 sched_wakeup_granularity_ns 会导致上下文切换暴增(可能超过 10 万次/秒),反而增加调度延迟。建议每次调整后使用 vmstat 1 监控 cs(context switch)列,确保增幅在 20% 以内。
4.6 参数持久化配置示例
以下是一个完整的持久化配置示例,同时包含 sysctl 和 cgroup 设置:
# /etc/sysctl.d/99-mysql-sched.conf
# MySQL 专用调度器参数调优
kernel.sched_min_granularity_ns = 2000000
kernel.sched_latency_ns = 24000000
kernel.sched_wakeup_granularity_ns = 2000000
kernel.sched_migration_cost_ns = 1000000
kernel.sched_autogroup_enabled = 0
# 应用 sysctl 配置
sysctl --system
# cgroup v2 配置(使用 systemd 单元文件覆盖)
# /etc/systemd/system/mysql.service.d/override.conf
[Service]
# CPU 权重:相对份额
CPUWeight=400
# CPU 使用上限:最多使用 4 个核(400000/100000)
CPUQuota=400%
# 延迟敏感标记
AllowedCPUs=0-7
# 重新加载 systemd 并重启 MySQL
systemctl daemon-reload
systemctl restart mysql
最佳实践:在修改 sysctl 参数前,先使用
sysctl -a | grep sched_ 记录当前值,以便回滚。cgroup 参数建议通过 systemd 单元文件管理,避免手动写入 /sys/fs/cgroup 导致重启后丢失。