大规模实时欺诈评分
tracio.ai 如何借助流式处理、预计算信号向量与边缘缓存,以每秒 5 万个事件的吞吐量实现低于 50 毫秒的评分延迟。
大规模欺诈评分所需的架构与批处理有着本质区别。当一笔支付正在被授权、或一个账户正在被创建时,你只有几毫秒——而不是几分钟——来给出风险评分。在 tracio.ai,我们每秒处理超过 50,000 个事件,评分延迟中位数为 22 毫秒。本文将阐释使这一切成为可能的架构。
评分流水线
每个进入系统的事件都会经过一条三段式流水线:信号富化、向量计算与风险评分。信号富化会把设备情报数据——访客指纹、机器人检测结果、IP 情报以及历史行为——附加到原始事件上。向量计算把这些经过富化的信号转换为一个为评分模型优化过的定长特征向量。风险评分则让该向量通过我们训练好的模型,返回一个介于 0.0 与 1.0 之间的分值。
关键的设计决策在于:把富化与向量计算和评分分离开来。富化数据是预先计算并缓存的。当访客加载页面时,我们会计算其设备画像并以 60 分钟的 TTL 存入 Redis。当评分请求到达时——通常由支付或登录触发——我们直接取回预计算好的画像,而不是重新计算。这将评分延迟从 200 毫秒以上降至 30 毫秒以内。
使用 Go 进行流式处理
我们的摄取层用 Go 编写,采用扇出(fan-out)架构。传入事件通过 HTTP POST 到达,并被立即放入一个内部 channel。一个工作协程(goroutine)池从该 channel 读取事件,执行富化,并把富化后的事件写入 ClickHouse 供分析使用,同时写入评分队列供实时处理。扇出池会根据队列深度动态伸缩。
我们为摄取层选择 Go,是因为它出色的并发原语与可预测的内存分配。每个工作协程约消耗 4KB 栈空间,使我们能在单个节点上运行数千个并发工作协程。垃圾回收器的亚毫秒级停顿,对于在高吞吐下维持稳定延迟至关重要。
边缘缓存与信号向量
对于流量最大的客户,我们借助预计算的信号向量缓存,在边缘部署评分模型。当某个设备首次被观测到时,我们会计算其完整的信号向量并存入边缘缓存(部署在 Cloudflare Workers KV 上)。针对同一设备的后续评分请求会取回缓存的向量,并在边缘本地运行评分,实现低于 10 毫秒的延迟。
边缘评分模型是我们完整模型的蒸馏版本——更小、更快,但针对同样的准确度目标进行了优化。我们每周重训边缘模型,并通过滚动部署发布更新,以避免缓存失效风暴。对于边缘模型置信度低于可配置阈值的情形,则由服务端运行的完整模型处理。
使用 ClickHouse 进行分析
所有富化后的事件都会存入 ClickHouse——我们的列式分析数据库。ClickHouse 的压缩能力与查询性能,让我们能够在存储数十亿事件的同时支持实时分析查询。我们的客户利用这些分析来理解欺诈模式、调优评分阈值并调查单个事件。
我们在 ClickHouse 中使用物化视图来维护预聚合的指标:按国家/地区划分的欺诈率、按设备类型划分的评分分布,以及按阈值划分的误报率。这些物化视图会随着事件到达而实时更新,无需昂贵的聚合查询即可提供可直接用于仪表盘的指标。
经验总结
构建实时评分系统让我们学到了几点经验。第一,预计算是最重要的优化——任何能在评分请求到达之前完成的工作,都不会计入你的延迟预算。第二,Go 的并发模型非常适合高吞吐的事件处理,但你必须在内存分配上保持克制,以避免 GC 压力。第三,边缘部署对延迟而言是变革性的,但需要对模型进行精心管理,以避免陈旧的预测。