系统设计 Lab
feature store 本质是两个 store 共用一套 schema:难点在于让 training 和 serving 用完全一致的方式算出同一个 feature。
调节 serving lookup、feature 数和 entity 数、online latency 目标、training 行数、streaming 新鲜度,再开关 streaming features 和 point-in-time correctness。架构会从 feature 在请求路径里现算,演进到 offline batch store,再到带 parity 的 online/offline split,再到 point-in-time training join,最终到大规模的 streaming materialization。
分步讲解
一步一步把它想清楚
要点
常规演进场景
从左到右点击,就是预设的演示路径。每张卡片都会改变 workload 输入。
推荐形态
当前架构路径
Models
Serving model 每次预测都按 entity key 要一个 feature vector
Training job 请求 join 到 label 的历史 feature 来训练模型
Serving + registry
Serving API 为 online inference 低延迟地取出 feature vector
Feature registry feature 定义和 transform 逻辑的 single source of truth
Online store
Online store 按 entity 做 key,在个位数 ms 内返回最新的 feature 值
Materialization
Batch job 按计划重算 feature,并写进两个 store
Stream job 从 event stream 更新 feature,做到秒级新鲜度
Offline
Offline store 持久保存历史 feature 值,供 training 和 backfill 用
Point-in-time join 把每个 label join 到它时间点上的 feature 值,杜绝泄漏
瓶颈
Online lookup 负载
Online latency 压力
Online store 体量
新鲜度 vs 延迟预算
Training join 开销
为什么会变
决策权衡
有出处支撑的规则
这些是模型背后那些经得起时间考验的 system design 论断。而 slider 的具体阈值,则被刻意标注为教学用的假设。
feature store 把低延迟的 online store 和可扩展的 offline store 拆开
Feast 把 feature materialize 进 online store 供 serving,又保留一个 offline store 做历史检索,于是同一套 feature 定义同时支撑两条路径。
Feast DocsOnline/offline parity 才是 feature store 真正要解决的核心问题
Michelangelo 把 feature 只算一次,并在 training 和 serving 间共享,让模型在两边看到相同的值,避免 training/serving skew。
Uber MichelangeloTraining join 必须 point-in-time correct,才能避免 label 泄漏
feature 必须按预测时间点 join 到 label;用 label 之后的值会泄漏未来信息,把 offline 指标虚高。
Feast Point-in-Time Joinsin-memory key-value store 能在亚毫秒延迟下服务 online feature
从 in-memory store 按 entity key 做 point lookup,能满足 warehouse 扫描达不到的紧 serving 预算。
Redis Docs教学用假设
- online lookup 被建模为按 entity key 读一行 feature 的 point read;每次取回完整的 feature vector。
- 单节点的读取、延迟、存储、join 预算都是保守的教学数字,不是厂商上限。
- online store 体量约等于 entity 数 x feature 数 x ~32 字节;真实系统还要加上 TTL、索引和 replication 开销。