Akemi

CPU亲和性与平衡中断

2025/05/20

CPU亲和性

指定CPU绑定进程,此举可以减少上下文切换,隔离关键任务

比如内存密集型进程限制为一个或两个cpu,可以增加缓存命中的机会从而提升性能

cgroup+systemd设置

现在systemd还没有集成cpuset工具

常规就是通过在service下设置CPUAffinity

也可以通过executepost中进行设置

1
2
3
4
5
6
[Service]
CPUAffinity=0 2 # 绑定到核心 0 和 2(用空格分隔)
# 或
CPUAffinity=0-3 # 绑定到核心 0 到 3(连续范围)
# 或
CPUAffinity=0,2 # 逗号分隔(等效于空格)

cgroup命令行工具

工具/机制 作用对象 管理粒度 适用场景
taskset 单个进程 进程级别 临时绑定单个进程的 CPU
numactl 单个进程 进程级别 + NUMA 绑定进程的 CPU 和内存节点
cpuset (cgroups) 进程组(容器等) 组级别 + 层级化 容器资源隔离、批量进程管理

cpuset本质上是cgroup的一个控制器,所以他具有cgroup所有好用的特

cgroup定义的参数是强制性的,需要在将任务移动到cgroup之前设置

1
2
3
4
5
6
7
8
9
10
11
12
13
内核可调项:

cpuset.cpus
该参数指定了cgroup中任务可以访问的cpu数量。列表可以用逗号分隔,也可以
用“-”分隔,也可以用“-”和“-”组合。

cpuset.mems
该参数指定cgroup中的任务可以访问的NUMA内存节点。列表范围可以用“-”分
隔,也可以用“-”和“-”的组合分隔。

cpuset.cpu_exclusive和cpuset.mem_exclusive
该参数指定除了当前的cpuset及其父节点和子节点之外,cpuset是否可以共享为该cpuset指定的CPU和内存节点。该参数为可选参数,
默认值为“0”,表示不允许共享CPU和内存节点。设置为1可以在父节点和子节点之间共享CPU和内存节点。cpuset.mems在没有NUMA架构的系统上,参数的值为0。

httpd设置cpu亲和性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 定义一个脚本先
vim /usr/local/bin/cpuset0

#!/bin/bash
# 创建cgroup组
mkdir -p /sys/fs/cgroup/cpuset/cpuset0
# 设置cgroup
echo 2-8 > /sys/fs/cgroup/cpuset/cpuset0/cpuset.cpus
echo 0-1 > /sys/fs/cgroup/cpuset/cpuset0/cpuset.mems
# 将httpd的PID都放入列表
for PID in $(pgrep httpd); do
echo ${PID} > /sys/fs/cgroup/cpuset/cpuset0/tasks
done

# 脚本在服务运行之后运行
vim /etc/systemd/system/httpd.service.d/cpuset.conf
[Service]
ExecStartPost=/usr/local/bin/cpuset0

# 重载服务
systemctl daemon-reload
systemctl restart httpd

CPU平衡中断

CPU 平衡中断(或称为 中断负载均衡)是指将硬件设备产生的中断请求(IRQ)合理地分配到多个 CPU 核心上,以避免单个 CPU 核心因处理过多中断而成为性能瓶颈。这是系统优化中非常重要的一部分,尤其在多核系统中,合理的中断分配能显著提高系统整体性能和响应速度。

中断请求如果全都集中到某个CPU,那性能就会下降,所以要分开给不同CPU发起中断

  • 避免单核过载:如果所有中断都由一个 CPU 核心处理,该核心可能因频繁处理中断而无法执行其他任务,导致系统整体性能下降。
  • 提高并行性:多核系统的优势在于并行处理,合理分配中断可充分利用所有 CPU 核心。
  • 降低延迟:均衡中断可减少某个核心的排队延迟,提升实时性要求高的任务(如网络数据包处理)。

自动中断平衡

Linux 提供了一个名为 irqbalance 的后台服务,它会动态调整中断在各 CPU 核心之间的分配。

管理员在/etc/sysconfig/irqbalance文件中,IRQBALANCE_ONESHOT设置为yes, irqbalance服务在启动后休眠一分钟,重新平衡一次中断,然后退出。这个变量对于避免每10秒唤醒服务的开销非常有用

手动平衡中断

通过修改 /proc/irq/<IRQ号>/smp_affinity/sys/class/irq/<IRQ>/smp_affinity 文件,指定处理该中断的 CPU 核心掩码。

调优nginx服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
yum -y install nginx tuna
systemctl enable nginx --now

# 查看当前调优状态
tuna -t nginx -P
thread ctxt_switches
pid SCHED_ rtpri affinity voluntary nonvoluntary cmd
42442 OTHER 0 0xfff 1 0 nginx
42443 OTHER 0 0xfff 4 0 nginx
SCHED_(调度策略)
rtpri(实时优先级)
affinity(CPU 亲和性)
voluntary:线程主动让出 CPU 的次数
nonvoluntary:线程被强制剥夺 CPU 的次数

# CPU亲和性绑定
mkdir /etc/systemd/system/nginx.service.d/
cat /etc/systemd/system/nginx.service.d/10-CPUAffinity.conf
[Service]
CPUAffinity=0

systemctl daemon-reload
systemctl restart nginx.service
tuna -t nginx -P
thread ctxt_switches
pid SCHED_ rtpri affinity voluntary nonvoluntary cmd
56507 OTHER 0 0 1 0 nginx
56508 OTHER 0 0 11 1 nginx
56509 OTHER 0 0 4 0 nginx

# 调整自动的CPU平衡中断
vim /etc/sysconfig/irqbalance
IRQBALANCE_BANNED_CPUS=00000001
指定CPU1不允许处理中断

00000001 → CPU0
00000002 → CPU1
00000003 → CPU2
以此类推

systemctl restart irqbalance.service

# 内核层面为每个中断分配CPU
systemctl disable irqbalance --now

for IRQ in /proc/irq/*/smp_affinity; do
> echo 2 > ${IRQ} 2>>/dev/null
> done

将中断绑定到CPU1
这样CPU0就可以专心处理nginx
特性 irqbalance 配置 直接修改 smp_affinity
控制方式 动态自动均衡 静态手动绑定
持久性 永久生效(需重启服务) 临时生效(重启后丢失)
灵活性 自动分配剩余 CPU 固定到指定 CPU
适用场景 多核负载均衡 特定中断的 CPU 绑定(如网络优化)
维护成本 低(配置一次即可) 高(需脚本或工具持久化)
与 irqbalance 共存 是(需服务运行) 需关闭 irqbalance 避免覆盖
CATALOG
  1. 1. CPU亲和性
    1. 1.1. cgroup+systemd设置
    2. 1.2. cgroup命令行工具
    3. 1.3. httpd设置cpu亲和性
  2. 2. CPU平衡中断
    1. 2.1. 自动中断平衡
    2. 2.2. 手动平衡中断
    3. 2.3. 调优nginx服务