2. 单机架构的基石:进程模型、内存数据库与文件系统,如何支撑每秒几百笔交易

说实话,很多人一上来就跟我聊分布式、微服务、高并发。但我觉得,如果连单机架构的底子都没打牢,后面那些花里胡哨的东西全是空中楼阁。

我当年刚入行做交易系统时,第一家公司用的就是单机架构。一台物理机,一个进程,一个内存数据库,一个文件系统。就这四样东西,硬是扛住了每秒几百笔交易。你想想看,那时候的硬件资源多金贵?CPU 主频才几百兆赫兹,内存按兆算。但就是这种环境,逼着我们这帮老家伙把每一行代码都榨出油来。

今天我就跟你聊聊,单机架构到底是怎么撑起那几百笔交易的。嗯,咱们从三个核心组件说起:进程模型、内存数据库、文件系统。

2.1 进程模型:为什么单进程比多进程更香?

很多人有个误区,觉得多进程 = 高性能。其实在单机交易系统里,恰恰相反。

我个人习惯,在单机场景下首选单进程 + 多线程模型。为什么?

  • 上下文切换成本低:进程切换要换页表、刷新 TLB,开销大。线程切换只换寄存器组和栈指针,快得多。
  • 共享内存方便:所有线程共享进程地址空间,不需要 IPC(进程间通信)那套复杂的机制。你想想看,交易系统里订单簿、持仓数据都是高频访问的,用共享内存直接读写,比走管道或消息队列快一个数量级。
  • 资源开销小:每个进程都有独立的地址空间、文件描述符表、信号处理表。开 10 个进程,光这些元数据就能吃掉几十兆内存。而 10 个线程,只多占几兆栈空间。

我在项目中遇到过一件事:有个同事非要用多进程模型,每个进程处理一类订单。结果上线后,内存直接爆了。后来我改成单进程 + 线程池,内存占用降了 60%,吞吐量反而提升了 30%。

核心原则:单机交易系统,进程数 = CPU 核心数 + 1 就足够了。剩下的并发需求,全部交给线程。

2.2 内存数据库:为什么不用 MySQL?

你可能会问:为什么不用 MySQL?MySQL 不是挺成熟的吗?

嗯,这里要注意。MySQL 是磁盘数据库,它的数据最终要落盘。而交易系统里,订单的撮合、风控的校验、持仓的更新,这些操作都要求微秒级响应。磁盘 I/O 一次就要几毫秒,差了三个数量级。

所以,单机交易系统的标配是内存数据库。说白了,就是把数据全放在内存里,读写都在内存中完成,磁盘只做持久化备份。

我常用的内存数据库方案有两种:

方案 特点 适用场景
Redis 纯内存,单线程模型,支持丰富数据结构 缓存、计数器、排行榜
自研内存表 用 C++ 或 Java 的 HashMap/ConcurrentHashMap 直接管理 订单簿、持仓、风控规则

我个人更倾向于自研内存表。为什么?因为交易系统的数据结构太特殊了。比如订单簿,需要按价格排序、按时间排序、还要支持快速撤销。Redis 的 ZSet 虽然能排序,但性能不如手写的跳表或红黑树。

我曾经在项目中用 Redis 做订单簿,结果发现撤销订单时,ZSet 的删除操作是 O(log n),而手写的跳表能做到 O(1) 定位 + O(log n) 删除。别小看这点差距,每秒几百笔交易时,每笔交易省几十微秒,整体吞吐量就上去了。

避坑指南:我曾经在内存数据库里直接存了订单的完整对象,结果 GC 频繁触发,导致系统卡顿。后来改成用对象池 + 原始类型数组,GC 压力直接降为零。记住:交易系统里,避免对象频繁创建和销毁

2.3 文件系统:日志才是王道

内存数据库虽然快,但有个致命问题:断电就丢数据。所以,文件系统的作用就是持久化

但你不能直接把内存数据全量写到磁盘。那样太慢了。交易系统里,文件系统的核心是预写日志(WAL,Write-Ahead Logging)

WAL 的原理很简单:

  1. 每次修改数据前,先把修改操作追加到日志文件末尾。
  2. 日志落盘后,再修改内存中的数据。
  3. 系统崩溃后,重启时重放日志,恢复内存数据。

为什么用追加写?因为磁盘的顺序写性能远高于随机写。机械硬盘的顺序写能达到 100MB/s,随机写只有几 MB/s。SSD 虽然好一些,但顺序写依然比随机写快 3-5 倍。

我建议你在实现 WAL 时,注意以下几点:

  • 批量刷盘:不要每笔交易都 fsync,那样太慢。可以攒够 100 笔或 10 毫秒再刷一次盘。
  • 日志压缩:定期把日志中的冗余操作合并。比如同一个订单被修改了 10 次,最终只保留最后一次状态。
  • 双写策略:日志写两份,一份在主磁盘,一份在备用磁盘。防止单点故障。

警告:我曾经见过一个团队,为了追求性能,把 fsync 间隔设成了 1 秒。结果一次断电,丢了 0.8 秒的数据,导致几十笔交易对不上账。记住:性能可以优化,数据不能丢。fsync 间隔建议不超过 100 毫秒。

2.4 三者如何协同工作?

好了,现在我们把进程模型、内存数据库、文件系统串起来。看看它们是怎么配合的:

单机交易系统核心架构 网络层(TCP/HTTP) 进程模型(单进程 + 多线程) 主线程:接收请求 | 工作线程:业务处理 | 日志线程:刷盘 内存数据库 订单簿 | 持仓 | 风控规则 文件系统 预写日志(WAL)| 快照文件 定期快照 / 崩溃恢复 每秒几百笔交易的核心路径: 网络接收 → 线程处理 → 内存读写(微秒级)→ 日志追加(毫秒级)→ 响应返回

你看这张图,整个流程其实很清晰:

  1. 网络层收到交易请求,交给进程模型中的工作线程。
  2. 工作线程直接操作内存数据库,完成订单撮合、持仓更新、风控校验。
  3. 同时,工作线程把操作记录追加到文件系统的 WAL 中。
  4. WAL 定期刷盘,保证数据不丢。
  5. 系统崩溃后,重启时从 WAL 恢复内存数据。

这个架构能支撑每秒几百笔交易,核心原因就三个字:快路径。所有关键操作都在内存中完成,磁盘只做顺序追加写。你想想看,内存访问是纳秒级,磁盘顺序写是微秒级,两者加起来,一笔交易的总延迟也就几百微秒。每秒几百笔,绰绰有余。

总结一下:单机架构的基石,就是进程模型、内存数据库、文件系统这三板斧。进程模型负责并发,内存数据库负责速度,文件系统负责可靠。三者缺一不可。

嗯,今天就聊到这儿。记住,别小看单机架构。很多分布式系统的问题,其实在单机阶段就已经埋下了伏笔。把单机玩透了,后面学分布式才会事半功倍。


专注资料整理