一、低延迟架构概述:做市系统为什么需要低延迟?
做市系统,说白了就是「抢单」的生意。你报的价比别人快1微秒,这单就是你的。慢1微秒,对手盘就吃掉了你的利润。
我刚开始接触做市系统时,觉得「快」不就是网速快嘛。后来踩了坑才发现,延迟的坑深着呢。CPU调度、内存访问、锁竞争,每个环节都能让你慢上几个数量级。
为什么做市系统对延迟如此敏感?
做市商的核心利润来源是「买卖价差」。你同时挂买单和卖单,赚中间的差价。但问题是,市场是动态的。价格在变,订单在变,你的报价必须跟上。
举个例子:
- 你在买一挂了100块,卖一挂了100.01块
- 突然有人砸盘,最新成交价跌到99.99
- 你的买单还在100块挂着,等于高价接盘
- 你的卖单还在100.01块,根本卖不出去
这时候,你需要在几微秒内撤单、重新报价。慢一丁点,就是亏损。
核心结论:做市系统的延迟,直接决定了你的报价能否「活下来」。延迟越低,你的报价越安全,利润越稳定。
延迟的构成:到底慢在哪里?
很多人以为延迟就是网络延迟。其实不然。我拆解一下一次完整的交易链路:
- 网络延迟:数据从交易所到你的服务器,再从服务器回去
- CPU延迟:CPU处理数据、计算报价、执行逻辑
- 内存延迟:从内存读取数据、写入数据
- 锁延迟:多线程竞争资源时的等待时间
每个环节都有它的「时间成本」。我们一个个看。
1. 网络延迟
这是最直观的。光纤传输速度大约是每公里5微秒。从上海到深圳,物理距离1200公里,光速往返就要12微秒。再加上交换机、网卡的处理时间,实际延迟在50-100微秒左右。
我见过有人为了省这几十微秒,把服务器直接托管在交易所机房隔壁。物理距离缩短到几米,网络延迟降到1微秒以内。
2. CPU延迟
CPU处理一条指令,大概需要0.3-1纳秒。听起来很快对吧?但一次完整的报价计算,可能需要几百条指令。再加上CPU缓存命中率、分支预测失败,实际延迟可能到几百纳秒甚至几微秒。
我记得有一次,我们的策略在测试环境跑得飞快,上线后却慢了3倍。排查了半天,发现是CPU缓存频繁失效。数据在L1、L2、L3缓存之间来回倒腾,白白浪费了几百纳秒。
3. 内存延迟
内存访问延迟大概是100纳秒左右。听起来也不大,但如果你频繁访问内存,累积起来就很可观了。
举个例子:你从内存读取一个订单簿,假设有1000个订单。每个订单读取一次,就是1000次内存访问。1000 × 100纳秒 = 100微秒。这还没算上CPU处理的时间。
我的经验:尽量把热点数据放在CPU缓存里。比如订单簿的头部数据、最新成交价等。用内存映射文件或者共享内存,减少系统调用。
4. 锁延迟
锁是低延迟系统的头号杀手。一个锁的获取和释放,大概需要几十纳秒。但如果发生锁竞争,线程被挂起、唤醒,那延迟就是微秒级别了。
我曾经遇到过一个坑:两个线程同时更新同一个订单簿,用了互斥锁。结果在高并发时,锁竞争导致延迟飙升到几百微秒。后来改成无锁队列,延迟直接降到个位数微秒。
避坑指南:做市系统里,尽量别用锁。用原子操作、无锁数据结构、或者单线程处理热点数据。如果非要用锁,确保锁的粒度足够小,持有时间足够短。
延迟的度量单位:纳秒、微秒、毫秒
做市系统里,我们经常用这三个单位。它们之间的换算关系很简单:
| 单位 | 换算 | 典型场景 |
|---|---|---|
| 1毫秒 (ms) | 1000微秒 | 网络往返、磁盘IO |
| 1微秒 (μs) | 1000纳秒 | 内存访问、锁竞争 |
| 1纳秒 (ns) | 0.001微秒 | CPU指令执行、缓存访问 |
你想想看,一次完整的交易链路,从网络接收到报价发出,如果总延迟在10微秒以内,算是及格。5微秒以内,算不错。1微秒以内,那是顶尖水平。
我见过一些团队,优化了半天,把延迟从100微秒降到90微秒,觉得进步很大。其实呢?90微秒和100微秒,在交易所看来没区别。真正要优化的是那些「大头」——比如锁竞争、内存拷贝、系统调用。
一张图看懂延迟构成
下面这张图,是我自己总结的。它展示了做市系统里延迟的主要来源和优化方向。
总结一下
做市系统需要低延迟,是因为每一微秒都直接关系到盈亏。延迟的构成包括网络、CPU、内存、锁四个环节。度量单位从纳秒到毫秒,每个环节的优化重点不同。
我个人习惯是:先测量,再优化。用性能分析工具找出真正的瓶颈,而不是凭感觉瞎猜。我曾经见过有人花了两周优化网络,结果发现瓶颈在锁竞争上。嗯,这种事还是少干为妙。
一句话记住:做市系统的延迟,不是越快越好,而是「够快」就好。找到你的瓶颈,解决它,然后继续找下一个瓶颈。
公众号:蓝海资料掘金营,微信deep3321