3. Model Serving 架构设计:整体架构分层与关键组件选型

在风控评分通道中,Model Serving 架构需要同时满足高并发、低延迟、高可用和可观测四大核心要求。本章从整体架构分层出发,逐层拆解设计要点,并对比主流推理框架的选型策略。

3.1 整体架构分层

我们将 Model Serving 系统划分为三个核心逻辑层:接入层、推理层和存储层。每一层职责清晰,层间通过轻量级协议(HTTP/gRPC)解耦,便于独立扩缩容与灰度发布。

设计原则:接入层负责协议转换与流量治理,推理层专注模型计算与资源调度,存储层提供特征与结果持久化。层间不共享内部状态,仅通过 API 契约通信。
Model Serving 三层架构总览 接入层(API Gateway / Load Balancer) 协议转换(HTTP → gRPC) | 限流熔断 | 鉴权 | 灰度路由 典型组件:Nginx / Kong / Envoy / Spring Cloud Gateway 推理层(Model Serving Runtime) 模型加载与热更新 | 批量推理 | 特征预处理 | 模型版本管理 典型组件:Triton Inference Server / FastAPI + ONNX Runtime / BentoML 资源隔离:GPU MPS / CPU Set / 内存限制 存储层(Feature Store + Result Store) 特征缓存(Redis) | 评分结果持久化(MySQL/ClickHouse) | 模型元数据(etcd) 流量入口 核心计算单元 数据持久化

3.2 接入层设计要点

接入层是流量的第一道关卡,在风控场景中需要处理每秒数千到数万次评分请求。接入层的主要职责包括:

  • 协议转换:客户端通常使用 HTTP/JSON,推理层内部推荐使用 gRPC/Protobuf 以获得更好的序列化性能和强类型约束。
  • 限流与熔断:基于令牌桶或滑动窗口算法,防止突发流量冲垮推理节点。熔断策略采用半开状态自动恢复。
  • 灰度路由:根据请求头、用户 ID 或模型版本标签,将流量按比例分发到不同推理集群,支持 A/B 测试和金丝雀发布。
  • 请求校验与鉴权:校验必填字段、签名、API Key,拒绝无效请求,降低推理层无效计算开销。
接入层组件 协议支持 限流能力 灰度路由 社区活跃度
Nginx + Lua HTTP/1.1, HTTP/2 高(lua-resty-limit-traffic) 需自研 极高
Kong HTTP, gRPC 高(插件生态) 内置 高
Envoy HTTP/1.1, HTTP/2, gRPC 高(本地限流+全局限流) 内置(权重路由) 极高
Spring Cloud Gateway HTTP, WebSocket 中(基于 Redis 的 RequestRateLimiter) 需自研 高
选型建议:如果团队已有 Java 技术栈,优先选择 Spring Cloud Gateway + Nginx 组合;如果追求云原生和统一控制面,Envoy 是更优选择。风控场景建议在接入层开启请求级超时控制(通常设为 200ms),避免慢请求阻塞连接池。

3.3 推理层核心设计

推理层是 Model Serving 的心脏,直接承载模型计算。设计时需要重点考虑模型加载策略、批量推理和资源隔离三个维度。

3.3.1 模型加载与热更新

  • 冷启动加载:服务启动时从对象存储(S3/MinIO)拉取模型文件到本地缓存,加载到 GPU/CPU 内存。
  • 热更新:通过监听模型仓库的版本变更事件(etcd watch / 文件系统 inotify),在不重启服务的情况下切换模型版本。
  • 版本管理:每个模型保留最近 N 个版本,支持按版本号或标签(stable/canary)路由请求。

3.3.2 批量推理策略

风控评分模型通常为轻量级树模型或浅层神经网络,单次推理延迟在 1-10ms 量级。批量推理可以显著提升吞吐量:

  • 动态批处理:推理框架自动收集请求,在最大延迟容忍度内组成 batch,减少内核启动开销。
  • 队列管理:为每个模型维护独立请求队列,设置最大 batch size 和最大等待时间(如 32 条 / 5ms)。
  • 优先级调度:高优先级请求(如实时交易评分)可跳过队列直接推理,或插入队列头部。
推理层内部工作流(动态批处理) 请求队列 FIFO / 优先级 最大等待 5ms 批处理调度器 动态组 Batch 最大 32 条 模型实例 XGBoost / ONNX GPU / CPU 结果分发 解 Batch → 返回 请求排队 组批优化 并行计算

3.4 关键组件选型:Flask vs FastAPI vs Triton

在推理框架选型上,需要根据模型类型、部署规模和性能要求做出权衡。下表从多个维度对比三个主流选项:

维度 Flask FastAPI Triton Inference Server
定位 轻量级 Web 框架 高性能异步 Web 框架 专用推理服务器
协议 HTTP/1.1 HTTP/1.1, HTTP/2, WebSocket HTTP, gRPC, 原生 C API
异步支持 需额外配置(Gunicorn + gevent) 原生 async/await 内置异步调度器
批量推理 需自研 需自研 内置动态批处理
GPU 管理 无 无 内置 GPU 调度、MPS、并发模型
模型格式 任意(需手动加载) 任意(需手动加载) TensorRT, ONNX, PyTorch, XGBoost 等
生产就绪度 中(需大量自建组件) 高(自动文档、校验、监控) 极高(企业级部署、健康检查、Prometheus 指标)
适用场景 原型验证、低并发内部工具 中等并发、需要快速迭代的评分服务 高并发、多模型、GPU 密集的风控核心链路
避坑提示:不要在生产风控链路中直接使用 Flask 的默认开发服务器(Werkzeug 单进程)。即使使用 Gunicorn + gevent worker,Flask 在处理长连接和流式请求时仍存在性能瓶颈。如果团队人力有限,优先选择 FastAPI + Uvicorn 作为推理层入口,再通过 Triton 作为后端推理引擎,形成“FastAPI 编排 + Triton 计算”的混合架构。

3.5 混合架构推荐:FastAPI + Triton

在风控评分通道的实际落地中,我们推荐采用FastAPI 作为推理编排层,Triton 作为模型计算引擎的混合架构。FastAPI 负责请求解析、特征预处理、结果后处理、调用链追踪;Triton 负责模型加载、GPU 资源调度和批量推理。两者通过 gRPC 通信,兼顾灵活性与性能。

# FastAPI 编排层示例:调用 Triton 进行推理
import tritonclient.grpc as grpcclient
from fastapi import FastAPI, Request
from pydantic import BaseModel

app = FastAPI()
triton_client = grpcclient.InferenceServerClient(url="triton:8001", verbose=False)

class ScoreRequest(BaseModel):
    user_id: str
    features: list[float]

@app.post("/v1/score")
async def score(request: ScoreRequest):
    # 1. 特征预处理(归一化、缺失值填充)
    processed_features = preprocess(request.features)

    # 2. 构造 Triton 请求
    inputs = [grpcclient.InferInput("input", [1, len(processed_features)], "FP32")]
    inputs[0].set_data_from_numpy(np.array([processed_features], dtype=np.float32))
    outputs = [grpcclient.InferRequestedOutput("output")]

    # 3. 调用 Triton 推理
    result = triton_client.infer(model_name="xgb_score", inputs=inputs, outputs=outputs)
    score = result.as_numpy("output")[0][0]

    # 4. 结果后处理(分数映射、阈值判断)
    final_decision = postprocess(score)

    return {"user_id": request.user_id, "score": float(score), "decision": final_decision}
架构收益:FastAPI 层可以灵活集成自定义预处理逻辑、第三方特征服务调用、缓存策略;Triton 层专注模型计算,支持多模型并发、GPU 共享和自动扩缩容。两者解耦后,模型更新只需重启 Triton 实例,编排层无需变更。

3.6 存储层设计要点

存储层在 Model Serving 中承担特征缓存、评分结果持久化和模型元数据管理三类职责:

  • 特征缓存(Redis):缓存实时特征(如设备指纹、IP 画像),减少重复计算。设置 TTL 过期策略,避免冷数据堆积。
  • 评分结果持久化(MySQL / ClickHouse):记录每次评分的请求 ID、用户 ID、模型版本、输入特征摘要、输出分数、决策结果、耗时。用于离线分析、模型监控和审计。
  • 模型元数据(etcd / ZooKeeper):存储模型版本、路由规则、健康状态。推理层通过 watch 机制感知元数据变更,实现热更新。
存储类型 推荐组件 关键配置 注意事项
特征缓存 Redis Cluster maxmemory-policy allkeys-lru;超时 300s 避免大 Value(>10KB),防止阻塞
评分结果 ClickHouse MergeTree 引擎;按天分区;TTL 30 天 写入 QPS 高时启用批量插入(每 1000 条 flush)
模型元数据 etcd 租约 10s;watch 超时 30s 避免频繁写入,元数据变更频率通常低于 1 次/分钟
关键指标:存储层写入延迟应控制在 5ms 以内(P99),否则会影响推理链路的整体耗时。建议将存储写入操作异步化:推理请求返回后,通过消息队列(Kafka)将评分结果异步写入 ClickHouse,避免阻塞主链路。