系统架构冗余:主从架构、多活架构、异地多活架构的对比与选择

做量化交易系统这么多年,我踩过最大的坑是什么?

不是策略回测不准,也不是行情延迟高。

而是系统挂了,单子没成交,眼睁睁看着行情走完。

那种感觉,真叫一个难受。

所以今天咱们聊聊架构冗余。说白了,就是怎么让你的交易系统「死不了」。

为什么需要架构冗余?

先讲个真实案例。

2019年,我参与过一个期货高频项目。主服务器放在上海机房,一切正常。结果某天下午,机房空调故障,温度飙升到45度。服务器自动关机了。

整个交易链路断了15分钟。

15分钟,对于高频交易来说,够亏掉一个月的利润了。

从那以后,我养成了一个习惯:任何单点故障,都必须有备用方案

架构冗余的核心目标就三个:

  • 高可用:系统7×24小时不中断
  • 数据不丢:订单、持仓、资金数据完整
  • 快速恢复:故障后秒级切换

核心原则:永远假设你的服务器下一秒就会挂掉。

三种主流架构模式

我按复杂度从低到高,一个个说。

1. 主从架构(Active-Standby)

这是最基础的模式。一台主节点干活,一台从节点待命。

主节点挂了,从节点顶上。

听起来简单,但坑不少。

工作流程

  1. 主节点处理所有交易请求
  2. 数据实时同步到从节点
  3. 心跳检测,每隔1秒发一次「我还活着」信号
  4. 主节点挂了,从节点接管IP和业务

代码示例:一个简单的心跳检测逻辑

import time
import socket

def heartbeat_check(master_ip, port=8888, timeout=3):
    """检测主节点是否存活"""
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(timeout)
        sock.connect((master_ip, port))
        sock.close()
        return True
    except:
        return False

def failover_switch():
    """主从切换逻辑"""
    while True:
        if not heartbeat_check("192.168.1.10"):
            print("主节点挂了,开始切换...")
            # 1. 停止从节点的同步进程
            # 2. 将从节点IP改为主节点IP
            # 3. 启动交易服务
            # 4. 发送告警通知
            print("切换完成,从节点已接管")
            break
        time.sleep(1)

我的经验:心跳间隔别设太短。我曾经设了100ms,结果网络抖动导致频繁误切换,反而把系统搞乱了。建议1-3秒。

优点

  • 实现简单,成本低
  • 数据一致性容易保证
  • 适合中小型交易团队

缺点

  • 从节点资源浪费(平时不干活)
  • 切换有延迟(秒级到分钟级)
  • 无法应对机房级故障

2. 多活架构(Active-Active)

主从架构最大的问题是什么?

从节点闲着。你想想看,花了两台服务器的钱,只有一台在干活。

多活架构就不一样了。所有节点都在处理交易,谁也别闲着。

核心设计

  • 多个节点同时提供服务
  • 负载均衡器分发请求
  • 数据实时同步,保证一致性

数据同步方案

# 伪代码:多节点数据同步
class MultiActiveSync:
    def __init__(self):
        self.nodes = ["node1", "node2", "node3"]
        self.consensus = {}  # 共识状态
    
    def sync_order(self, order_data):
        """同步订单到所有节点"""
        ack_count = 0
        for node in self.nodes:
            if self.send_to_node(node, order_data):
                ack_count += 1
        
        # 超过半数节点确认,才算成功
        if ack_count > len(self.nodes) / 2:
            return True
        else:
            # 回滚已确认的节点
            self.rollback(order_data)
            return False

注意:多活架构最怕「脑裂」。就是两个节点都以为对方挂了,各自接管业务,导致数据冲突。我见过一次,订单重复、持仓对不上,光对账就花了两天。

适用场景

  • 交易量大的中大型团队
  • 对延迟要求高(毫秒级切换)
  • 能接受一定的架构复杂度

3. 异地多活架构

这是终极方案。

多活架构只能防服务器故障,但防不了「整个机房都挂了」。

比如:地震、火灾、光纤被挖断。

异地多活,就是把节点部署在不同城市。

架构示意

北京机房 交易节点 A1 交易节点 A2 数据库主库 上海机房 交易节点 B1 交易节点 B2 数据库从库 深圳机房 交易节点 C1 交易节点 C2 数据库从库 同步 同步 全局负载均衡器(DNS/GSLB) 交易用户

关键挑战

  • 数据一致性:跨城市同步延迟至少几十毫秒
  • 冲突处理:同一笔订单在不同节点同时处理怎么办?
  • 成本:三倍硬件成本 + 专线费用

我的建议:别一上来就搞异地多活。先问自己三个问题:

  1. 你的交易量真的需要吗?
  2. 团队有维护能力吗?
  3. 预算够吗?

大多数团队,主从架构 + 定期备份就够用了。

三种架构对比

维度 主从架构 多活架构 异地多活
实现复杂度
成本 低(2台) 中(N台) 高(3倍+专线)
切换时间 秒级~分钟级 毫秒级 毫秒级
数据一致性 强一致 最终一致 最终一致
容灾能力 单机故障 单机/单机房 城市级灾难
资源利用率 低(从节点闲置) 高(全量利用) 高(全量利用)
适合团队 小团队(1-5人) 中型团队(5-20人) 大型团队(20人+)

如何选择?

我一般按这个思路来:

  1. 起步阶段:主从架构 + 每日备份。省钱省力,够用就行。
  2. 业务增长:升级到多活架构。注意先做好数据分片,别一股脑全同步。
  3. 规模大了:考虑异地多活。但一定要先做压测,我曾经在测试环境跑得好好的,上线第一天就出问题——跨城同步延迟导致订单状态不一致。

避坑指南:我曾经犯过一个错误——把所有鸡蛋放在一个篮子里。主从架构用了同一个机柜的电源,结果一次断电,主从一起挂了。记住:冗余不只是多台机器,还要考虑电力、网络、机房的物理隔离。

总结

架构冗余没有银弹。

主从架构简单可靠,适合起步。

多活架构资源利用率高,适合成长。

异地多活容灾能力强,适合大厂。

选哪个?

看你的交易量、团队能力、预算。

但有一条铁律:无论选哪种,一定要定期做故障演练

我每季度都会搞一次「断网日」,故意把主节点拔掉,看系统能不能自动切换。第一次演练时,从节点居然没起来——因为同步脚本有个bug。还好发现了,不然真出事就晚了。

嗯,今天就聊到这儿。记住:系统可以挂,但你的交易不能停。

专注资料整理