第二章:延迟的构成——网络、内核、应用层与硬件

做市系统的延迟,说白了就是数据包从交易所到策略引擎,再回到交易所的完整路径上,每一站消耗的时间总和。

我刚开始做低延迟交易系统时,总觉得延迟是个黑盒。后来我亲手搭了一套全链路监控,才真正看清——延迟不是单一问题,而是多个环节的叠加。你想想看,一个订单从发出到成交确认,中间要经过多少道关卡?

我个人习惯把延迟拆成四层:网络延迟、内核延迟、应用层延迟、硬件延迟。每一层都有它的坑,也有它的优化空间。

2.1 全景图:数据包的完整旅程

先看一张全景图。这张图我画了很多遍,每次给团队培训都会拿出来讲。

数据包从交易所到策略引擎再到订单执行的完整路径 交易所 行情/订单网关 网络 网卡 硬件延迟 内核 内核协议栈 内核延迟 应用 策略引擎 应用层延迟 ▼ 回程路径(订单执行) ▼ 订单生成 应用层延迟 应用 内核协议栈 内核延迟 内核 网卡 硬件延迟 网络 交易所 订单确认 各环节典型延迟范围 🔹 网络延迟: 同城 50-100μs,跨洲 50-200ms 🔹 硬件延迟: 网卡硬件处理 1-5μs,FPGA 加速可降至 100ns 🔹 内核延迟: 标准内核 10-50μs,DPDK 绕过内核降至 1-3μs 🔹 应用层延迟: 策略计算 5-50μs,内存访问 100ns 级 🔹 总往返延迟: 优化前 200-500μs,优化后可降至 10-50μs

这张图我每次看都有新体会。数据包从交易所出发,经过网络、网卡、内核协议栈,最后到达策略引擎。策略算完,订单再原路返回。每一站都有延迟,每一站都能优化。

2.2 网络延迟:物理距离的硬约束

网络延迟是最「老实」的延迟。光速是物理极限,谁也没法突破。

我记得有一次,团队把服务器从纽约搬到新泽西,就为了离交易所的机房更近。搬完之后,延迟从 1.2ms 降到了 400μs。效果立竿见影。

网络延迟主要来自三方面:

  • 传播延迟:光在光纤中传播的速度大约是 2/3 光速。每 100 公里大约 500μs。
  • 传输延迟:数据包大小除以带宽。万兆网卡下,64 字节的小包大约 51ns。
  • 处理延迟:交换机、路由器处理数据包的时间。好的交换机可以做到 1-5μs。

关键认知:网络延迟中,传播延迟是硬约束,你只能通过「搬得更近」来解决。传输延迟和处理延迟可以通过硬件升级来优化。

2.3 内核延迟:协议栈的沉重包袱

内核延迟,说白了就是操作系统帮你处理网络数据时花的时间。

标准 Linux 内核处理一个网络数据包,要走完整的协议栈路径:中断处理、软中断、协议解析、socket 缓冲区、上下文切换……这一套下来,10-50μs 就没了。

我刚开始做优化时,觉得内核挺快的。直到我用 perf 工具一测,才发现内核协议栈占了整个延迟的 40% 以上。嗯,这里要注意——内核延迟往往是最大的优化空间

内核延迟的典型构成:

环节 典型延迟 说明
中断处理 2-5μs 网卡触发中断,CPU 保存上下文
协议栈处理 5-20μs TCP/IP 协议解析、校验和计算
socket 缓冲区 1-5μs 数据从内核态拷贝到用户态
上下文切换 2-10μs 内核态到用户态的切换

优化思路:使用 DPDK、Solarflare 的 OpenOnload 等技术,可以绕过内核协议栈,让应用直接操作网卡。我曾经在一个项目中用 DPDK 把内核延迟从 30μs 降到了 2μs。

2.4 应用层延迟:代码质量决定一切

应用层延迟,说白了就是你的策略代码跑得有多快。

这一层最容易被忽视。很多人觉得「我的策略逻辑很复杂,慢一点正常」。但你想过没有——同样的策略,用 C++ 写和用 Python 写,延迟能差 10 倍以上。

应用层延迟的常见来源:

  • 内存分配:频繁的 malloc/free 会导致延迟抖动。我建议用对象池或预分配。
  • 锁竞争:多线程环境下,锁的争抢会让延迟飙升。用无锁数据结构或者读写锁分离。
  • 日志打印:每条订单都打日志?小心 I/O 成为瓶颈。异步日志是标配。
  • 垃圾回收:Java/C# 的 GC 暂停是噩梦。做市系统我建议用 C++ 或 Rust。

避坑指南:我曾经在一个项目中,发现策略引擎的延迟每隔几分钟就会突然跳到 100ms 以上。排查了两天,最后发现是日志库在缓冲区满时做了同步写入。换成异步日志后,问题消失。

2.5 硬件延迟:选对设备省一半功夫

硬件延迟,包括网卡、CPU 缓存、内存访问、PCIe 总线等各个环节的延迟。

我个人习惯把硬件延迟分成两类:

  • 确定性延迟:比如内存访问延迟,大约 100ns。这个相对固定。
  • 非确定性延迟:比如 CPU 缓存未命中,延迟可能从 1ns 跳到 100ns。这个最坑人。

硬件延迟的典型数据:

硬件环节 典型延迟 优化方向
L1 缓存命中 1ns 数据局部性优化
L2 缓存命中 4ns 减少数据规模
主存访问 100ns 减少随机访问
PCIe 传输 1-5μs 使用 NUMA 绑定
网卡硬件处理 1-5μs 使用 FPGA 或智能网卡

核心原则:硬件延迟的优化,本质上是让数据尽量靠近 CPU。把热数据放在 L1 缓存里,把网卡和 CPU 绑定在同一个 NUMA 节点上——这些细节做好了,延迟能降一个数量级。

2.6 延迟的叠加效应

你想想看,每一层都优化一点,叠加起来效果就很可观。

举个例子:

  • 网络延迟:从 100μs 优化到 50μs(搬机房)
  • 内核延迟:从 30μs 优化到 3μs(DPDK)
  • 应用层延迟:从 20μs 优化到 5μs(代码优化)
  • 硬件延迟:从 10μs 优化到 3μs(NUMA 绑定 + 缓存优化)

总延迟从 160μs 降到了 61μs。这就是做市系统从毫秒到微秒的进化路径。

我个人习惯在做优化时,先做全链路延迟测量,找到最大的瓶颈,然后集中火力解决它。不要一上来就想着「全都要优化」,那样反而容易顾此失彼。


公众号:蓝海资料掘金营,微信deep3321