3. 特征平台架构设计:整体架构分层与组件交互流程

一个生产级的特征平台,其核心价值在于为模型 Serving 提供稳定、低延迟、一致性的特征数据。为了实现这一目标,平台架构通常采用清晰的分层设计,将数据接入、计算、存储与在线服务解耦。本章将详细阐述特征平台的四层架构模型及各层之间的核心交互流程。

3.1 整体架构分层

特征平台架构自上而下分为四个核心层次:数据源层、特征计算层、特征存储层和Serving 层。每一层各司其职,共同构成从原始数据到模型在线推理的完整链路。

架构设计原则: 分层架构的核心优势在于解耦。每一层都可以独立扩展、优化和故障隔离。例如,当数据源从 Kafka 切换为 Pulsar 时,只需修改数据源层的适配器,上层的计算与存储逻辑无需变更。
架构层 核心职责 典型组件/技术 关键指标
数据源层 对接异构数据源,提供统一的接入抽象 Kafka, Pulsar, HDFS, MySQL CDC, S3 数据接入吞吐量 (MB/s)、数据延迟 (ms)
特征计算层 执行特征变换、聚合、Join 等逻辑 Flink, Spark, ByteHouse, 自定义 UDF 计算延迟 (ms/s)、吞吐量 (QPS)、数据新鲜度
特征存储层 存储特征元数据、离线/实时特征值 Redis, HBase, Cassandra, MySQL, Hive 读写延迟 (μs/ms)、存储容量 (TB)、一致性
Serving 层 提供高并发、低延迟的在线特征获取 API gRPC Server, RESTful API, 本地缓存 SDK P99 延迟 (ms)、QPS、可用性 (SLA 99.99%)

3.2 组件交互流程与数据流转

特征数据的生命周期始于数据源,终于模型 Serving。下图展示了特征从生产到消费的完整交互流程,重点突出了离线-实时特征一致性与在线存储预热两个关键环节。

特征平台四层架构与数据流交互图 特征平台四层架构与数据流交互图 数据源层 (Data Source Layer) Kafka 实时流 MySQL CDC Hive 离线表 S3 日志文件 数据接入 特征计算层 (Feature Compute Layer) Flink 实时计算 窗口聚合 / 时间戳对齐 Spark 离线批处理 T+1 全量特征 / 回溯 特征注册中心 元数据管理 / 版本控制 写入实时特征 写入离线特征 特征存储层 (Feature Store Layer) 在线 KV 存储 (Redis) 毫秒级读取 / TTL 管理 离线数仓 (Hive) 历史回溯 / 训练样本 特征元数据 (MySQL) 特征定义 / 血缘 / 版本 特征读取 Serving 层 (Online Serving Layer) gRPC 特征服务 本地缓存 SDK 模型推理引擎

3.3 核心交互流程详解

基于上述分层架构,特征平台在模型 Serving 场景下存在三条核心数据流,它们共同决定了特征服务的质量与效率。

3.3.1 实时特征流 (Hot Path)

  • 触发条件: 用户行为事件(如点击、曝光)实时产生。
  • 流程: 数据源层 (Kafka) → 特征计算层 (Flink 实时聚合) → 特征存储层 (Redis 在线 KV) → Serving 层 (gRPC 读取)。
  • 关键要求: 端到端延迟 < 100ms,保证特征新鲜度。

3.3.2 离线特征流 (Cold Path)

  • 触发条件: 每日定时任务,用于生成历史特征和训练样本。
  • 流程: 数据源层 (Hive) → 特征计算层 (Spark 批处理) → 特征存储层 (Hive 离线表 & Redis 预热)。
  • 关键要求: 高吞吐量,保证离线与在线特征的一致性(通过特征版本对齐)。

3.3.3 在线存储预热 (Warm-up)

  • 触发条件: 模型版本更新或每日离线特征产出后。
  • 流程: 离线特征 (Hive) → 数据导出 Job → 批量写入 Redis 在线存储。
  • 关键要求: 预热期间不能影响在线 Serving 的读写性能,通常采用 双缓冲 或 灰度切换 策略。
实践要点: 在实时特征流中,Flink 作业需要处理迟到数据和乱序事件。建议使用 Event Time 语义,并设置合理的 Watermark 延迟(如 5 秒),以平衡特征准确性与延迟。

3.4 组件交互时序图

为了更清晰地展示一次模型推理请求中,各组件之间的调用关系,我们以在线特征获取为例,绘制如下时序图。

在线特征获取时序图 在线特征获取时序图 (Serving 请求) 模型推理 Serving API 本地缓存 Redis 集群 1. 请求特征 (entity_id) 2. 查询本地缓存 3. 缓存 Miss 4. 回源 Redis 查询 5. 返回特征值 6. 回写本地缓存 7. 返回特征结果 时序说明: • 步骤 2-3:本地缓存 (如 Guava Cache) 用于降低 Redis 压力,通常设置 5-60 秒 TTL。 • 步骤 4-5:Redis 回源是核心路径,必须保证 P99 延迟 < 5ms。 • 步骤 6:回写缓存时需注意缓存击穿,建议使用互斥锁或异步加载。 • 整体目标:从模型推理发起请求到获取特征,端到端延迟 < 20ms。

3.5 架构设计关键考量

在落地上述分层架构时,需要重点关注以下三个方面的权衡与设计。

考量维度 描述 推荐策略
特征一致性 离线训练使用的特征与在线 Serving 使用的特征必须完全一致,否则会导致训练-推理偏差 (Training-Serving Skew)。 1. 使用统一的特征定义语言 (如 YAML)。
2. 离线与在线复用同一套特征计算逻辑。
3. 定期进行离线-在线特征比对校验。
延迟与吞吐 Serving 层需要同时满足低延迟 (P99 < 10ms) 和高吞吐 (数万 QPS) 的要求。 1. 使用多级缓存 (本地 + 分布式)。
2. 特征预加载与批量获取。
3. 连接池与异步非阻塞 I/O。
可扩展性 特征数量、数据源类型、模型版本会持续增长,架构需要支持水平扩展。 1. 计算层与存储层无状态化。
2. 特征存储按实体 ID 分片。
3. 元数据与数据存储分离。
常见陷阱: 很多团队在初期只关注实时特征流,忽略了离线-在线一致性校验。当模型上线后,由于特征计算逻辑不一致(例如,离线用 7 天聚合,在线用 3 天聚合),导致模型效果远低于预期。务必在架构设计阶段就将特征血缘追踪和一致性校验作为核心组件纳入。