一、撮合引擎概述:什么是订单撮合、撮合引擎在交易系统中的地位、主流撮合引擎对比
大家好,我是老张。今天咱们聊聊撮合引擎。
说实话,我入行那会儿,撮合引擎还是个挺神秘的东西。那时候我在一家小券商做开发,老大扔给我一份文档,说「小张,你去把撮合核心搞一搞」。我一看,好家伙,几千行C++代码,全是锁和队列。后来我才明白,这东西就是交易系统的灵魂。
1.1 什么是订单撮合?
订单撮合,说白了就是「匹配买卖双方」的过程。
你想想看,张三想用10块钱买1股茅台,李四想用10块钱卖1股茅台。系统得把他们俩凑到一起,完成这笔交易。这就是撮合。
但实际场景比这复杂得多。比如:
- 价格不同怎么办?张三出10块,李四要10.01块
- 数量不匹配怎么办?张三买100股,李四只卖50股
- 同时来了几百个订单怎么办?谁先成交?
嗯,这里要注意:撮合的核心就是「价格优先、时间优先」。这是所有交易所的基石规则。
核心定义:订单撮合是指交易系统根据预设的规则(通常是价格优先、时间优先),将买单和卖单进行匹配,生成成交记录的过程。
我在项目中遇到过最头疼的事,就是订单顺序搞乱了。有一次因为消息队列的时序问题,导致一个买单明明先到,却被后到的单子抢了先。排查了整整两天,最后发现是Kafka的分区策略没配好。从那以后,我对订单的「时间戳」和「全局序号」就特别敏感。
1.2 撮合引擎在交易系统中的地位
撮合引擎是什么地位?我打个比方:
- 订单系统是「前台接待」——收单、验单
- 风控系统是「保安」——检查有没有违规
- 清算系统是「财务」——算账、划款
- 撮合引擎是「裁判」——决定谁赢谁输
没有撮合引擎,交易系统就是一盘散沙。所有的订单进来,最终都要到撮合引擎这里「见真章」。
为什么它这么重要?三个原因:
- 性能瓶颈——撮合是交易链路中最耗CPU的操作。我见过一个系统,撮合引擎占了整个交易系统60%以上的计算资源。
- 公平性保障——撮合规则必须绝对公平。谁先谁后,谁多谁少,不能有半点含糊。我曾经在审计时发现一个撮合引擎的浮点数比较有bug,导致某些订单被「吃掉」了零点几毫秒的优先级。嗯,那是个大坑。
- 业务核心——所有的交易策略、套利机会、市场深度,最终都体现在撮合结果上。撮合引擎的延迟,直接决定了交易系统的竞争力。
个人经验:我建议你在设计交易系统时,先把撮合引擎的接口定义清楚。其他模块都可以迭代,但撮合核心的接口一旦定了,改起来代价极大。我曾经因为接口没设计好,导致后面重构了三次。
1.3 主流撮合引擎对比
市面上常见的撮合引擎,我大致分三类:
| 类型 | 代表实现 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| 单机内存撮合 | LMAX Disruptor + 内存订单簿 | 延迟极低(微秒级)、实现简单 | 单点故障、容量受限 | 中小型交易所、高频交易 |
| 分布式撮合 | 基于Kafka + 状态机复制 | 高可用、可扩展 | 延迟较高(毫秒级)、一致性难保证 | 大型交易所、数字货币平台 |
| 数据库撮合 | 基于MySQL/PostgreSQL存储过程 | 开发快、数据持久化 | 性能差(秒级)、并发能力弱 | 原型系统、低频交易 |
我个人习惯用单机内存撮合作为主力方案。为什么?因为撮合这个操作,本质上就是「读订单簿 + 写订单簿 + 生成成交」。这些操作在内存里做,比在数据库里做快几个数量级。
但要注意:单机撮合不等于没有高可用。我通常的做法是:
- 主节点做撮合,生成操作日志
- 备节点实时同步日志,保持内存状态一致
- 主节点挂了,备节点秒级切换
这其实就是「主备复制」的思路。我在做第一个撮合引擎时,就是用的这个方案。当时线上跑了两年,只出过一次故障——还是因为网络分区导致的脑裂问题。嗯,那是另一个故事了。
避坑指南:我曾经在选型时犯过一个错误——为了追求「绝对高可用」,选择了分布式撮合方案。结果发现,分布式环境下的一致性协议(比如Raft)在撮合场景下反而成了瓶颈。因为撮合需要「全局有序」,而分布式共识的延迟在毫秒级,对于高频交易来说完全不可接受。后来我学乖了:能用单机解决的问题,别硬上分布式。
1.4 本章小结
好了,咱们把撮合引擎的概貌理清楚了:
- 它是什么——匹配买卖双方的规则引擎
- 它有多重要——交易系统的核心裁判
- 主流方案有哪些——单机、分布式、数据库,各有千秋
接下来,我会带你深入订单簿的数据结构、撮合算法的实现细节、以及如何优化性能。但今天先到这里,消化一下这些基础概念。
记住一句话:撮合引擎没有银弹。每个方案都有取舍,关键是你得知道自己要什么。
公众号:蓝海资料掘金营,微信deep3321