logo头像
Snippet 博客主题

rust高性能撮合引擎的设计

代码层面设计

交易对消费的实现

  1. 单线程消费,避免锁竞争的问题
  2. cpu 核隔离,isolcpus,单独用来做撮合操作.
  3. cpu 核绑定,core_affinity

2和3的操作避免系统进程抢核导致的业务处理抖动。

下单逻辑梳理crossbeam_channel

类似内存的消息组件,crossbeam Multi-Producer Multi-Consumer:多生产者、多消费者。

系统调优

实时优先级(SCHED_FIFO

原理

SCHED_FIFO(先进先出)是 Linux 内核的一种严格实时调度策略。在此策略下,任务按优先级排队;一旦获取 CPU,该任务将持续独占运行直至主动放弃或被更高优先级任务抢占,没有时间片限制。消除 OS 定时器中断导致的延迟尖峰

配置

配置系统限制

编辑 /etc/security/limits.d/[用户信息].conf

1
2
3
4
kerns    soft    rtprio    99
kerns hard rtprio 99
kerns soft memlock unlimited
kerns hard memlock unlimited

配置项 含义
rtprio 99
允许设置实时调度优先级(配合 chrt -f 99 用 SCHED_FIFO)
memlock unlimited
允许锁定内存(避免关键页换出导致延迟尖峰)

使用 chrt 启动

1
2
# 优先级 99 = 最高实时优先级
sudo -u kerns chrt -f 99 taskset -c 2,3 /usr/local/bin/kerns-matcher

验证实时调度

1
2
3
4
PID=$(pgrep kerns-matcher)
chrt -p $PID
# 期望输出:pid xxx's current scheduling policy: SCHED_FIFO
# pid xxx's current scheduling priority: 99

IRQ 中断迁移

将网卡等硬件中断迁离撮合核,避免中断抢占撮合线程。

查看 IRQ 分布

1
2
cat /proc/interrupts | head -5
cat /proc/interrupts | grep -i eth

绑定 IRQ 到非撮合核(如 core 0)

1
2
3
4
5
# 假设网卡 IRQ 号为 128,绑到 core 0(bitmask 0x1)
echo 1 | sudo tee /proc/irq/128/smp_affinity

# 多个核的 bitmask:core 0,1 = 0x3
echo 3 | sudo tee /proc/irq/128/smp_affinity

cpu隔离 isolcpus:

原理

  1. 独占计算资源:防止系统调度器将其他普通后台进程或线程随机分配到被隔离的 CPU 上,保障关键任务(如高频交易系统、实时音视频处理、工业控制等)获得 100% 的硬件算力。
  2. 减少上下文切换与缓存污染:避免由于其他任务频繁进出 CPU 导致的 CPU 缓存(Cache)被刷新或覆盖,从而提升程序执行的命中率。
  3. 降低抖动(Jitter):通过避免不必要的中断和调度切换,将系统抖动降至最低,通常结合 taskset 或 pthread_setaffinity_np 将特定线程强制绑定到该核心上执行。如果不设置,操作系统的任务调度会干扰业务系统,导致业务抖动。

配置

修改 GRUB 启动参数

编辑 /etc/default/grub

1
sudo vim /etc/default/grub

GRUB_CMDLINE_LINUX 中追加(按实际核号调整):

1
isolcpus=2,3 nohz_full=2,3 rcu_nocbs=2,3 intel_pstate=disable processor.max_cstate=1 idle=poll
参数 作用
isolcpus=2,3 核心 2、3 不参与普通进程调度
nohz_full=2,3 关闭这些核上的定时器 tick
rcu_nocbs=2,3 RCU 回调不在这些核执行
intel_pstate=disable 禁用变频(Intel,可选)
processor.max_cstate=1 限制 CPU 深度睡眠(可选)

AMD CPU 将 intel_pstate=disable 换为 amd_iommu=off 等按厂商文档调整。

更新 GRUB 并重启

Ubuntu / Debian:

1
2
sudo update-grub
sudo reboot

RHEL / Rocky / CentOS:

1
2
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
sudo reboot

重启后验证

1
2
3
4
5
6
7
8
# 确认内核参数已生效
cat /proc/cmdline | tr ' ' '\n' | grep isolcpus

# 在隔离核上启动测试进程,应只有手动 taskset 的进程
taskset -c 2 sleep 3600 &
taskset -c 2 pgrep -a sleep # 应能看到进程

# 普通进程不应自动跑到 core 2(除非手动 taskset)

代码地址

rust-trade-match