3. 操作系统内核调优:让Linux为行情速度而生
行情网关跑在Linux上,内核如果不调,就像开着法拉利却挂着二档跑。我见过太多团队,硬件花了几十万买最好的网卡和CPU,结果内核参数还是默认值——白白浪费了性能。
今天咱们就聊聊四个关键点:内核缓冲区调优、中断亲和性、CPU隔离、大页内存。这四板斧下去,延迟至少能降30%。
3.1 内核网络缓冲区:别让数据包堵在路上
先看两个参数:net.core.rmem_default 和 net.core.wmem_max。
说白了,它们控制着socket接收和发送缓冲区的大小。行情数据一来就是海量包,缓冲区太小,内核会频繁丢包。你想想看,丢一个包就得重传,延迟直接飙升到毫秒级——这在行情系统里是致命的。
我个人习惯这样设置:
# 接收缓冲区默认值,单位字节
net.core.rmem_default = 26214400 # 约25MB
# 发送缓冲区最大值
net.core.wmem_max = 26214400 # 约25MB
为什么是25MB?我在项目中遇到过,某家交易所的行情峰值能达到每秒50万笔。默认的212KB缓冲区,几秒钟就满了。调大后,丢包率从3%降到了0.01%。
3.2 中断亲和性:让网卡和CPU“绑定”
网卡收到数据包,会触发中断通知CPU来处理。默认情况下,中断可能落在任意一个CPU核心上。这就导致一个问题:CPU缓存频繁失效,数据在不同核心间“搬家”,延迟自然就高了。
解决方案?把网卡中断绑定到特定CPU核心上。
具体做法分三步:
- 查看网卡中断号
cat /proc/interrupts | grep eth0
- 查看当前中断亲和性
cat /proc/irq/<中断号>/smp_affinity
- 设置亲和性(比如绑定到CPU 0)
echo "1" > /proc/irq/<中断号>/smp_affinity
这里的“1”是位掩码,表示CPU 0。如果想绑定到CPU 2,就写“4”(二进制100)。
我曾经帮一家券商调优,他们行情网关的延迟抖动特别大。一查,中断在8个核心上乱跳。绑定到2个核心后,延迟从平均50微秒降到了15微秒,而且几乎没抖动。
3.3 CPU隔离:给行情业务“专属跑道”
Linux内核默认会把进程调度到所有CPU上。但行情业务需要的是确定性——我们希望某个核心只跑行情网关,别的进程别来抢。
这就用到 isolcpus 内核启动参数了。
在GRUB配置里加上:
isolcpus=4,5,6,7
意思是:CPU 4-7从内核的调度器中“隔离”出来。普通进程不会跑到这些核心上,只有你手动绑定的进程才能用。
然后,用 taskset 把行情网关绑定到隔离的核心上:
taskset -c 4,5 ./market_gateway
- CPU 0-1:处理网卡中断和系统任务
- CPU 2-3:处理其他非关键业务
- CPU 4-7:隔离出来,只跑行情网关
嗯,这里要注意:isolcpus 只隔离进程调度,不隔离中断。所以中断亲和性设置和CPU隔离要配合使用,缺一不可。
3.4 大页内存:减少TLB miss,加速内存访问
行情网关处理数据时,需要频繁访问内存。默认的4KB内存页,意味着每访问一次内存,CPU都要查页表。页表大了,TLB(页表缓存)就容易miss。
大页内存(HugePages)把页大小从4KB提升到2MB甚至1GB。TLB能覆盖的内存范围大了几十倍,miss率自然就降下来了。
配置方法:
# 分配1024个2MB的大页,总共2GB
echo 1024 > /proc/sys/vm/nr_hugepages
然后,在应用程序里用 mmap 加上 MAP_HUGETLB 标志来分配大页内存。或者,更简单的方式——用 libhugetlbfs 库,透明地让应用使用大页。
大页内存的效果有多明显?我做过对比测试:同样处理100万笔行情,用4KB页时TLB miss率是12%,用2MB大页后降到了0.3%。整体处理时间缩短了40%。
3.5 知识体系总览
下面这张图,把今天讲的四个调优点串起来了:
这四个调优点,说白了就是让硬件资源各司其职:缓冲区管好数据流,中断和CPU隔离管好计算资源,大页内存管好内存访问。配合起来,行情网关才能跑出极限性能。
最后提醒一句:调优参数要逐步调整、持续观察。别一次性全改了,出了问题都不知道是哪一步导致的。我习惯每次只改一个参数,跑24小时看效果,没问题再改下一个。
公众号:蓝海数据掘金营,微信deep3321