工程与管理交易系统架构内存管理

重启不丢上下文:交易系统的状态持久化

交易系统最怕两件事:亏钱,和重启。

亏钱还能靠风控拦着。重启是物理定律——服务器总要维护,进程总要更新。问题不在于能不能重启,在于重启后策略能不能立刻恢复到重启前的状态。


为什么重启是个问题

假设你有一个趋势追踪策略,它维护了以下状态:

  • BOCPD 变点检测的 history buffer(需要数百个数据点)
  • 信号服务的缓存结果(微趋势分数、资金费率、L 信号)
  • 当前持仓的入场价、止损线、止盈线

重启后:

  • BOCPD buffer 清空 → 需要等数百个新数据点 → 数十分钟的真空期
  • 信号服务缓存清空 → 需要重新调用 API → 数分钟的延迟
  • 止损/止盈丢失 → 持仓裸露无保护,直到重新计算

重启一次 = 策略失明数十分钟。 在这期间,任何行情变化都不会被响应。


持久化什么

不是全量持久化。分优先级:

P0(重启后必须恢复)

  1. BOCPD tracker 的 run-length distribution → 没有它,变点检测要重新预热
  2. 信号服务的缓存分数 → 没有它,开仓信号要等新数据
  3. 当前持仓的退出条件(止损/止盈)→ 重启后不能丢,否则持仓裸奔

P1(重启后可以慢慢恢复)

  1. 历史信号日志 → 丢了不影响当前决策
  2. 统计计数器 → 可以重新累加

P2(不持久化)

  1. 实时行情快照 → 重启后 WS 会自动推送最新的
  2. 临时计算结果 → 可以重新算

怎么持久化

用 Redis 做状态存储,RDB 快照 + AOF 双保险。关键设计:

策略启动

  ├─ 检查 Redis 是否有持久化状态?
  │   ├─ 有 → 加载状态,跳过预热
  │   └─ 无 → 进入预热模式

  └─ 运行中每 N 秒 checkpoint 一次状态到 Redis

不是每次状态变化都写,那样 Redis 会被写炸。是定时 checkpoint——即使丢几秒的状态,也比丢全部重新预热强。


元结构映射:广告系统的索引持久化

这和广告索引的持久化逻辑一致:

概念广告索引交易状态
全量持久化索引定期 dump 到磁盘Redis RDB 快照
增量恢复重放 binlogRedis AOF 增量
重启恢复加载 dump + 重放 binlog → 秒级恢复加载快照 + 上次 checkpoint 后数据 → 跳过预热
预热时间索引重建数十分钟BOCPD 预热数十分钟

本质相同:重启后不是从零开始,而是从上次的 checkpoint 开始追增量。


一句话

服务重启不可怕,可怕的是重启后策略失明数十分钟。持久化 BOCPD tracker 和退出条件——这两样丢了是真的会亏钱的。