
1) 【一句话结论】设计期货交易系统的订单撮合引擎,核心是采用分布式订单簿分片(按价格区间切分,支持水平扩展)+ 内存化订单簿(自研跳表/Redis ZSET,O(logn)操作)+ Raft协议保证分片间数据一致性 + 消息队列(Kafka)解耦,通过分片扩展性、内存优化、一致性协议和异步解耦,支撑万级订单/毫秒级响应。
2) 【原理/概念讲解】订单撮合引擎的核心是“订单簿”与“撮合逻辑”。订单簿是存储买卖订单的有序数据结构,按价格排序(卖方升序,买方降序),维护每个价格点的成交量。分布式分片将订单簿切分为多个分片,每个分片由独立节点处理,通过Raft协议保证分片间数据一致性(如跨分片撮合时,先通过Raft同步价格数据)。内存化订单簿(如跳表)支持O(logn)的插入/删除/查找,减少I/O延迟。撮合逻辑遵循“价格优先、时间优先”原则(价格相同,时间早的订单优先匹配)。消息队列(如Kafka)解耦订单接收与撮合模块,避免阻塞。类比:订单簿像超市货架,分布式分片是多个货架(每个货架存储部分价格商品),内存化货架(电子货架)比传统纸质货架(I/O慢)更快,无锁货架(CAS操作)比锁货架(排队等待)更高效,Raft协议像货架间的库存同步系统,确保每个货架的商品数量一致。
3) 【对比与适用场景】
| 方案 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| 范围分片(按价格区间) | 订单簿按价格区间切分为多个分片,如[0,10000]→分片1 | 符合订单簿逻辑,避免热点分片,跨分片撮合时只需同步相邻分片 | 高并发、大规模交易场景 | 需设计分片边界,避免跨分片数据同步复杂 |
| 一致性哈希分片 | 订单ID或价格哈希后映射到分片 | 负载均衡,分片数量变化时需重新映射 | 对分片数量变化敏感的场景 | 可能导致热点分片 |
| 方案 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| TTL+LRU缓存 | 结合时间失效(TTL)和最近最少使用(LRU) | 自动清理过期数据,避免LRU误删活跃订单 | 过期订单较多,需控制内存 | 需设置合理的TTL,避免频繁清理 |
| 按时间分区清理 | 按时间区间(如按小时)分区,定期清理 | 针对性清理,减少内存压力 | 历史订单按时间分区存储 | 需设计分区策略,避免频繁分区 |
| 方案 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| Kafka | 高吞吐、持久化、分布式 | 消息持久化,支持重试,延迟低(毫秒级) | 订单流解耦,异步处理 | 需考虑消息堆积,设计消费组 |
| Pulsar | 低延迟、高可用 | 延迟更低(微秒级),持久化 | 对延迟要求极高的场景 | 成本较高 |
4) 【示例】
class SkipListNode:
def __init__(self, price, qty, order_id, next_nodes):
self.price = price
self.qty = qty
self.order_id = order_id
self.next_nodes = next_nodes # 指向下一个节点的指针列表
class OrderBook:
def __init__(self):
self.head = SkipListNode(-float('inf'), 0, None, [])
self.tail = SkipListNode(float('inf'), 0, None, [])
self.head.next_nodes[0] = self.tail
def add_order(self, price, qty, side, order_id):
# side=1为卖方(升序),side=-1为买方(降序)
# 插入节点,按price排序
pass
def match(self, qty):
# 卖方:从最高卖价指针(head.next_nodes[0])开始,买方从最低买价指针(head.next_nodes[0])开始
# 比较当前卖价和买价,若相等则匹配,减少数量,直到匹配数量满足
pass
{
"order_id": "order_123",
"price": 10000,
"qty": 1000,
"side": "sell",
"timestamp": "2023-11-01T10:00:00Z"
}
5) 【面试口播版答案】面试官您好,设计期货交易系统的订单撮合引擎,核心是支撑万级订单和毫秒级响应。首先,订单簿是核心数据结构,我们采用分布式分片(按价格区间切分,支持水平扩展)+ 内存化订单簿(自研跳表,O(logn)操作),按价格有序。架构上分为订单接收、分片处理、撮合匹配、结果推送模块。关键技术:1. 分布式分片:订单簿按价格区间切分成多个分片,每个分片部署独立节点,通过Raft协议保证分片间数据一致性(如跨分片撮合时,先通过Raft同步价格数据);2. 内存化订单簿:使用跳表维护每个价格点的订单队列,插入/删除/查找效率高,满足低延迟;3. 并发控制:无锁数据结构(CAS)避免锁竞争;4. 消息队列(Kafka):解耦订单流,订单接收模块写入Kafka,撮合模块消费,支持异步处理。主要挑战包括:内存管理(采用TTL+LRU策略,避免LRU误删活跃订单)、数据一致性(跨分片撮合时通过Raft同步)、消息队列延迟(设计指数退避重试机制,避免堆积)。总结来说,通过分布式分片扩展性、内存化低延迟、Raft保证一致性、消息队列解耦,实现高并发、低延迟的撮合。
6) 【追问清单】
7) 【常见坑/雷区】