系统架构层面的容错:主备切换、多活架构与异地灾备
聊到系统架构的容错,很多朋友第一反应就是「多搞几台机器」。嗯,这话没错,但怎么搞、搞成什么样子,这里面的门道可深了。我个人习惯把架构容错分成三个层次:主备、多活、异地灾备。它们不是互斥的,而是层层递进的关系。
说白了,你一个做量化交易的系统,如果因为服务器宕机导致订单没发出去,或者数据丢了,那损失可不是开玩笑的。我见过太多团队在初期只图快,架构上能省则省,结果出一次事故,几个月的利润全赔进去。
一、主备切换架构:最朴素的保命手段
主备架构,也叫 Active-Standby。一台主节点干活,一台备用节点等着。主节点挂了,备节点顶上。
听起来很简单对吧?但坑全在细节里。
核心设计原则:
- 心跳检测要可靠:主备之间通过心跳包互相确认状态。心跳超时了,备机才敢接管。
- 数据同步要实时:备机必须能拿到主机的全部状态。否则切换过去,数据是旧的,交易逻辑全乱套。
- 切换要自动且快速:人工切换太慢,等运维登录上去,行情都跑完几轮了。
我在项目中遇到过一种情况:主节点因为网络抖动,心跳包丢了几个,备机以为主挂了,立刻切过来。结果两台机器同时对外提供服务,订单重复发送,交易所那边直接报错。嗯,这就是典型的「脑裂」问题。
避坑指南:
我曾经在期货交易系统里用过主备架构,后来发现一个问题:备机虽然同步了数据,但行情网关的连接是独立的。主备切换后,备机需要重新建立与交易所的 TCP 连接,这个过程花了 3 秒。3 秒在量化交易里,足够错过一个 tick 了。
所以后来我加了一个「预连接」机制:备机平时就维持着与交易所的连接,只是不发送交易指令。切换时直接复用连接,延迟降到 200 毫秒以内。
| 维度 | 主备架构特点 |
|---|---|
| 切换时间 | 秒级到分钟级,取决于数据同步和连接重建 |
| 资源利用率 | 低,备机平时基本闲置 |
| 数据一致性 | 强一致,但切换瞬间可能有少量数据丢失 |
| 适用场景 | 对成本敏感、允许短时间中断的交易系统 |
二、多活架构:让每一台机器都干活
主备架构最大的问题是什么?浪费。备机闲着也是闲着,为什么不让它也处理一部分请求?这就是多活架构的思路。
多活架构,也叫 Active-Active。多台节点同时对外提供服务,流量分摊到各个节点上。一台挂了,其他节点继续扛。
你想想看,对于量化交易系统来说,多活架构的好处很明显:
- 吞吐量翻倍:两台机器同时处理订单,容量直接翻倍。
- 故障影响面小:一台挂了,其他节点还能处理 50% 甚至更多的流量。
- 滚动升级方便:可以一台一台升级,业务不中断。
但多活架构的难点在于「状态共享」。交易系统是有状态的——订单状态、持仓信息、资金余额,这些数据必须所有节点保持一致。否则你在 A 节点下了单,B 节点不知道,结果又下一单,那就出大事了。
注意:
多活架构不是简单的「多部署几台机器」。它要求你的业务逻辑必须是「无状态」的,或者状态必须通过分布式缓存(比如 Redis)或数据库来共享。我见过一个团队,把交易引擎部署了 4 台,结果每台机器各自维护一份内存中的订单簿,最后数据对不上,整个系统乱成一锅粥。
我个人习惯的做法是:把状态层和计算层分离。计算层可以多活,状态层用 Redis Cluster 或者 TiDB 这类分布式存储来承载。这样计算节点随便加,状态不会乱。
三、异地灾备架构:扛住机房级别的灾难
主备和多活,通常都是在同一个机房或者同一个城市。但如果整个机房都挂了怎么办?比如地震、火灾、电力故障。这时候就需要异地灾备了。
异地灾备,说白了就是在另一个城市甚至另一个国家,再建一套完整的系统。平时可能不对外服务,但关键时刻能接管全部业务。
这里要分两种模式:
- 冷备:异地只部署基础设施,数据定期同步。切换时需要人工启动服务,耗时可能几小时。
- 热备:异地系统一直运行着,数据实时同步。切换时秒级完成。
对于量化交易系统,我建议至少做到热备。为什么?因为行情不等人。你因为机房故障停了 10 分钟,可能就错过了一波大行情。我曾经在 2015 年股灾期间遇到过机房网络故障,主备切换花了 15 分钟,那 15 分钟里策略完全停摆,损失惨重。
异地灾备的设计要点:
- 数据同步延迟要可控:跨地域同步,网络延迟是硬伤。通常用专线或者 Kafka 这类消息中间件来做异步同步。
- 切换决策要自动化:不能等人工判断「机房是不是真挂了」。要有自动化的健康检查和切换脚本。
- 回切流程要演练:灾备切过去容易,切回来难。数据可能产生了差异,需要做数据对账和修复。
四、三种架构的对比与选择
说了这么多,到底该选哪种?我个人的经验是:
- 小团队、低预算:主备架构就够了。成本低,实现简单,能解决 80% 的故障场景。
- 中等规模、追求高可用:多活架构。资源利用率高,故障影响小,但需要投入精力解决状态共享问题。
- 大型机构、不能接受任何中断:异地灾备 + 多活。成本最高,但能扛住最极端的灾难。
| 架构类型 | 成本 | 切换时间 | 数据一致性 | 适用规模 |
|---|---|---|---|---|
| 主备切换 | 低 | 秒~分钟 | 强一致 | 小团队 |
| 多活架构 | 中 | 毫秒~秒 | 最终一致 | 中等规模 |
| 异地灾备 | 高 | 秒~分钟 | 最终一致 | 大型机构 |
最后说一句:架构没有银弹。你不可能用一套方案解决所有问题。关键是要想清楚你的业务场景能接受多长的中断时间、能承受多大的数据丢失。想明白了,再选方案。
个人经验总结:
我做了这么多年量化交易系统,最深的体会是:容错不是「加机器」那么简单。你需要在架构设计阶段就想清楚每个环节的故障场景,然后针对性地设计应对方案。主备、多活、异地灾备,这三者不是选择题,而是组合题。很多大型机构的做法是:同城多活 + 异地灾备,既保证了日常的高可用,又能在极端情况下兜底。