操作系统调优:内核参数、中断亲和性、CPU隔离与独占
说到操作系统调优,我见过太多团队把精力全花在代码层面,结果延迟死活降不下来。其实很多时候,瓶颈根本不在你的代码里,而在操作系统这个「管家」身上。它忙着调度线程、处理中断、切换上下文,你的交易信号就在这些「杂务」里被耽误了。
我个人习惯,拿到一台新机器,第一件事不是装软件,而是先做系统调优。今天我们就聊聊三个核心维度:内核参数、中断亲和性、CPU隔离与独占。
内核参数调优:让操作系统「让路」
Linux 内核默认是为通用场景设计的。它要照顾数据库、Web 服务器、桌面应用……唯独没考虑过微秒级交易的需求。所以我们要手动改一些参数,告诉内核:「别管那些花里胡哨的,给我让出最快的路。」
核心思路:减少内核干预,降低上下文切换,优先保障用户态程序。
我常用的几个关键参数,直接上配置:
# /etc/sysctl.conf 追加以下内容
# 减少 swap 使用,避免内存换出导致的延迟抖动
vm.swappiness = 1
# 扩大接收/发送缓冲区,防止突发流量丢包
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
# 启用 TCP 快速打开,减少握手延迟
net.ipv4.tcp_fastopen = 3
# 关闭 TCP 时间戳,减少 CPU 开销
net.ipv4.tcp_timestamps = 0
# 减少 TIME_WAIT 数量,避免端口耗尽
net.ipv4.tcp_tw_reuse = 1
# 调整内核调度器,优先低延迟
kernel.sched_min_granularity_ns = 1000000
kernel.sched_wakeup_granularity_ns = 500000
这里我特别想提一下 swappiness。曾经有个项目,延迟偶尔会突然飙升到几十毫秒,查了半天发现是内存紧张,内核把交易进程的部分内存换到磁盘了。设成 1 之后,问题再没出现过。说白了,交易系统里,内存就是命,别让内核乱动。
小技巧:改完参数后,用 sysctl -p 立即生效。但建议先在一台非生产机器上验证,别上来就改生产环境。
中断亲和性:把中断绑到指定 CPU
网卡中断来了,内核会随机选一个 CPU 去处理。如果你的交易线程刚好在那个 CPU 上运行,就会被中断打断——这就是延迟抖动的常见来源。
解决办法?把中断绑定到特定的 CPU 上,让交易线程跑在「干净」的核上。
具体怎么做?我一般分三步:
- 找到网卡中断号:
cat /proc/interrupts | grep eth0 - 查看当前亲和性:
cat /proc/irq/<中断号>/smp_affinity - 设置亲和性:
echo 1 > /proc/irq/<中断号>/smp_affinity(将中断绑定到 CPU0)
举个例子,假设你的机器有 8 个核(0-7),交易线程跑在核 2-7 上,那你可以把网卡中断绑到核 0 和核 1:
# 将中断绑定到 CPU0 和 CPU1(位掩码 0x03)
echo 3 > /proc/irq/<中断号>/smp_affinity
我曾经在一个高频交易项目中,只做了这一步,平均延迟就降了 15%。你想想看,中断不再抢 CPU 时间,交易线程自然跑得更顺。
注意:有些网卡驱动支持多队列(RSS),每个队列有独立的中断号。这种情况下,你可以把不同队列的中断绑定到不同 CPU,实现负载均衡。但记住,交易线程所在的核,最好别绑任何中断。
CPU 隔离与独占:给交易线程一个「专属跑道」
这是最狠的一招。把某些 CPU 核从内核调度器中「摘」出来,只运行你指定的用户态程序。内核的线程、中断、定时器……统统不许碰这些核。
怎么做?用内核启动参数 isolcpus:
# 在 GRUB 配置中追加
isolcpus=2,3,4,5,6,7
这样核 2-7 就被隔离了。普通进程默认不会跑上去,只有你明确用 taskset 或 sched_setaffinity 绑定的线程才能用。
但光隔离还不够,还要配合 rcu_nocbs 和 nohz_full:
isolcpus=2,3,4,5,6,7 nohz_full=2,3,4,5,6,7 rcu_nocbs=2,3,4,5,6,7
nohz_full:关闭隔离核上的定时器中断,减少周期性打扰rcu_nocbs:把 RCU 回调从隔离核上移走,避免后台任务干扰
嗯,这里要注意。隔离之后,你的交易线程必须手动绑定到这些核上。我习惯用 pthread_setaffinity_np 在代码里绑定,启动时也用 taskset 做双重保险。
实战效果:在我参与的一个期权做市项目中,CPU 隔离后,延迟抖动从 ±20μs 降到了 ±3μs。效果立竿见影。
知识体系总览
下面这张图,是我自己梳理的操作系统调优核心逻辑。你可以把它当作一个检查清单:
避坑指南
最后分享几个我踩过的坑:
- 别把所有核都隔离:至少留 1-2 个核给操作系统和中断处理,否则系统可能卡死。我曾经留了 0 号核给系统,其他全隔离,运行了半年没出问题。
- 隔离后要验证:用
htop或pidstat确认没有其他进程跑到隔离核上。有一次我发现 kswapd 偷偷跑上去了,查了半天是内核参数没配全。 - 中断亲和性要持久化:
/proc下的配置重启就丢了。建议写到/etc/rc.local或 systemd 服务里,开机自动设置。
操作系统调优这件事,说白了就是「抢资源」。把 CPU、内存、中断这些有限资源,尽可能多地分配给交易线程。你做得越彻底,延迟就越稳定。
我的建议:先从内核参数和中断亲和性入手,这两步改动小、见效快。如果还不够,再上 CPU 隔离。别一上来就搞大动作,容易翻车。
公众号:蓝海资料掘金营,微信deep3321