第十七章:风控系统架构设计
系统架构这东西,说起来挺虚的,但真出了问题,你就知道它有多重要了。
我做基差交易这些年,见过太多「系统跑着跑着就崩了」的惨案。有一次,一个同事的监控看板在行情剧烈波动时直接卡死,等恢复过来,已经亏了七位数。嗯,从那以后,我对风控系统的架构设计就特别较真。
一、系统功能模块划分
我个人习惯把风控系统拆成五个核心模块。说白了,每个模块各管一摊,互不干扰,出了问题也好定位。
| 模块名称 | 核心职责 | 我踩过的坑 |
|---|---|---|
| 数据采集层 | 对接交易所、资讯商、内部交易系统 | 曾经因为数据源时间戳不一致,导致基差计算全错 |
| 计算引擎层 | 基差计算、保证金测算、风险指标 | 浮点精度问题,差之毫厘谬以千里 |
| 规则引擎层 | 风控阈值判断、逻辑校验 | 规则写死了,行情一变就失效 |
| 告警通知层 | 多渠道推送、分级告警 | 告警太多,最后没人看了 |
| 可视化层 | 监控看板、报表、历史回溯 | 数据刷新太慢,看板成了摆设 |
你想想看,这五个模块如果耦合在一起,改一个地方就得全停。我建议一开始就做成微服务架构,每个模块独立部署。
二、数据流设计
数据流是系统的血脉。我见过最糟糕的设计,是数据绕了一大圈才到风控引擎,等算出来,行情都变了。
我的做法是这样的:
- 实时数据流:行情数据走消息队列(Kafka/RabbitMQ),延迟控制在10ms以内
- 批量数据流:结算数据、持仓数据走定时任务,每5分钟同步一次
- 异常数据流:一旦发现数据异常,立即走独立通道,绕过正常处理流程
核心原则:数据不落地,处理不等待。所有数据在内存中完成计算,只有最终结果才写入数据库。
我曾经犯过一个错误——把历史数据和实时数据混在一起处理。结果实时计算被历史查询拖慢,差点出事。后来我学乖了,实时库和历史库完全分离。
三、实时监控看板
看板这东西,不是越花哨越好。我见过有人把看板做成「仪表盘展览馆」,花花绿绿一大堆,真正有用的信息反而找不到。
我个人习惯把看板分成三个区域:
- 顶部:核心指标区。基差、保证金占用、风险度、最大回撤。就这四个,多了不看。
- 中部:持仓明细区。按品种、合约、方向排列,支持点击下钻。
- 底部:告警滚动区。最新的告警信息实时滚动,红色是紧急,黄色是警告,蓝色是提示。
数据刷新频率呢?我建议核心指标每秒刷新一次,持仓明细每5秒刷新一次。太快了服务器扛不住,太慢了又没意义。
小技巧:看板上加一个「冻结」按钮。行情剧烈波动时,先冻结当前画面,仔细分析完再解冻。这个功能救过我一次。
四、告警机制设计
告警机制,说白了就是「什么时候该喊救命」。喊早了是狼来了,喊晚了就真出事了。
我设计的告警分三级:
| 级别 | 触发条件 | 推送方式 | 响应要求 |
|---|---|---|---|
| 一级(紧急) | 基差偏离超过3个标准差 | 电话+短信+微信 | 5分钟内必须确认 |
| 二级(警告) | 基差偏离超过2个标准差 | 短信+微信 | 15分钟内确认 |
| 三级(提示) | 基差偏离超过1个标准差 | 微信消息 | 30分钟内查看即可 |
注意:告警阈值不能是固定值。行情波动率变化时,阈值也要跟着变。我曾经因为没做动态阈值,在低波动行情下告警全哑火了。
还有一个细节——告警去重。同一个品种连续触发告警,只发一次,除非状态变了。不然你想想,一分钟收到几十条一样的消息,谁受得了?
五、系统性能要求
性能这东西,没有最好,只有够用。但「够用」的标准是什么?我给出一个参考值:
- 数据采集延迟:不超过50ms
- 基差计算耗时:单品种不超过10ms
- 全品种计算:不超过500ms
- 看板刷新:核心指标1秒内,持仓明细5秒内
- 告警推送:从触发到收到不超过3秒
- 系统可用性:99.99%(一年宕机不超过53分钟)
怎么达到这个水平?我建议:
- 计算引擎用C++或Go写,别用Python
- 数据库用时序数据库(InfluxDB/TimescaleDB),别用关系型
- 缓存层用Redis,热点数据全放内存
- 消息队列用Kafka,吞吐量至少10万条/秒
一句话总结:风控系统不是「能跑就行」,而是「跑得稳、跑得快、跑不崩」。你想想看,真到了关键时刻,系统掉链子,那损失可不是闹着玩的。
六、系统架构图
下面这张图是我自己画的,把整个风控系统的数据流转和模块关系说清楚了。
这张图里,数据从下往上走,告警和可视化并行输出。你注意看,数据库是独立在旁边的,不参与实时计算链路。这个设计我用了好几年,没出过大问题。
公众号:蓝海资料掘金营,微信deep3321