news 2026/9/18 7:37:06

Feast MySQL Online Store 接入指南:配置、物化与在线特征读取实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Feast MySQL Online Store 接入指南:配置、物化与在线特征读取实战

Feast MySQL Online Store 接入指南:配置、物化与在线特征读取实战

【免费下载链接】feastThe Open Source Feature Store for AI/ML项目地址: https://gitcode.com/GitHub_Trending/fe/feast

MySQL 是当前 Feast 官方路线图中尚未正式规划的存储系统,但社区通过在sdk/python/feast/infra/online_stores/mysql_online_store目录下的实现,为其提供了完整的 Online Store 支持。本文基于仓库内 mysql_online_store/README.md 与 mysql.py 源码,讲解如何在 Feature Repository 中把 MySQL 配置为在线特征存储、执行物化(materialize)并把最新特征实时读取出来。读完本文,你将掌握 MySQL Online Store 的完整配置参数、端到端使用流程,以及其底层表结构与读写实现的原理。

MySQL Online Store 在 Feast 中的定位

Feast 的 Online Store 抽象定义在 online_store.py,它要求实现类提供online_write_batch(批量写入)、online_read(按实体键读取)、update(基础设施调和)和teardown(清理资源)等核心方法。MySQL 实现即遵循这套接口:

  • 配置类MySQLOnlineStoreConfig负责解析feature_store.yaml中的online_store段;
  • 存储类MySQLOnlineStore负责与 MySQL 建连、读写特征数据;
  • 每次materialize(物化)调用时,Feast 会把离线特征写入以<project_name>_<feature_view_name>命名的 MySQL 表,供低延迟在线读取。

从 repo_config.py 可以看到类型映射:"mysql"被注册为feast.infra.online_stores.mysql_online_store.mysql.MySQLOnlineStore,因此在feature_store.yaml中只需把online_store.type设为mysql即可被 Feast 自动加载。

第一步:创建 Feature Repository

沿用 Feast 标准初始化流程,在 shell 中执行:

feast init feature_repo cd feature_repo

初始化后会生成一个包含feature_store.yaml与示例特征定义(如example.py)的最小仓库骨架,本文后续的applymaterialize-incremental命令都基于该目录执行。

第二步:配置feature_store.yaml使用 MySQL

编辑仓库根目录下的feature_store.yaml,将online_store的类型设置为mysql,完整配置如下:

project: feature_repo registry: data/registry.db provider: local online_store: type: mysql host: 127.0.0.1 # mysql endpoint, default to 127.0.0.1 port: 3306 # mysql port, default to 3306 user: test # mysql user, default to test password: test # mysql password, default to test database: feast # mysql database, default to feast batch_write: false # supporting batch write and commit per batch batch_size: 100 # batch size, default to 100

各参数的含义与默认值,与 mysql.py 中MySQLOnlineStoreConfig的字段定义一一对应:

参数类型默认值说明
type字符串mysql固定字面量,用于触发 Online Store 类型映射
host字符串127.0.0.1MySQL 服务端点
port整数3306MySQL 端口
user字符串testMySQL 用户名
password字符串testMySQL 密码
database字符串feast目标数据库名,表会被创建在该库中
batch_write布尔false是否启用批量写入并按批提交
batch_size整数None批量写入时的批大小

这些默认值并非文档承诺,而是源码中_get_conn的连接逻辑直接体现的:host or "127.0.0.1"user or "test"password or "test"database or "feast"port or 3306,且autocommitbatch_write决定(见 mysql.py)。因此即使省略大部分字段,Feast 也能按默认参数连接本地 MySQL。

第三步:应用特征定义

example.py中定义好 Entity 与 FeatureView 后,执行:

feast -c feature_repo apply

apply会注册实体与特征视图,并在 MySQL 中创建对应的基础设施。参考输出:

Registered entity driver_id Registered feature view driver_hourly_stats_view Deploying infrastructure for driver_hourly_stats_view

Deploying infrastructure这一步实际触发了MySQLOnlineStore.update方法:对每个需要保留的 FeatureView,执行CREATE TABLE IF NOT EXISTS <project>_<feature_view_name>建表,并检查information_schema.statistics,若缺少以表名加_ek后缀命名的索引则通过ALTER TABLE ... ADD INDEX补建实体键索引(见 mysql.py)。

MySQL 中的表结构

update方法可以确定,每张在线特征表拥有如下结构:

CREATE TABLE IF NOT EXISTS <project>_<feature_view_name> ( entity_key VARCHAR(512), feature_name VARCHAR(256), value BLOB, event_ts timestamp NULL DEFAULT NULL, created_ts timestamp NULL DEFAULT NULL, PRIMARY KEY(entity_key, feature_name) );

即:同一行数据以“实体键 + 特征名”作为联合主键,value列存放 protobuf 序列化后的特征值,event_ts记录事件时间,created_ts记录写入时间;同时表名形如feature_repo_driver_hourly_stats_view,符合文档所述“每次物化都会更新该表”的命名与更新约定。

第四步:物化最新数据到 MySQL

离线特征通过物化命令写入 MySQL。先在 shell 中取当前时间,再执行增量物化:

$ CURRENT_TIME=$(date -u +"%Y-%m-%dT%H:%M:%S") $ feast -c feature_repo materialize-incremental $CURRENT_TIME

参考输出:

Materializing 1 feature views from 2022-04-16 15:30:39+05:30 to 2022-04-19 15:31:04+05:30 into the mysql online store. driver_hourly_stats_view from 2022-04-16 15:30:39+05:30 to 2022-04-19 15:31:04+05:30: 100%|████████████████████████████████████████████████████████████████| 5/5 [00:00<00:00, 120.59it/s]

底层写入路径:逐条提交与批量提交

物化最终调用的是MySQLOnlineStore.online_write_batch(见 mysql.py),其行为由batch_write配置分支:

  • 非批量模式(默认):逐条执行INSERT ... ON DUPLICATE KEY UPDATE,每处理完一个实体键的所有特征后立即commit(),适合数据量小、需要实时可见的场景;
  • 批量模式(batch_write: true:先把特征值序列化结果累积到insert_values列表,达到batch_size后调用cursor.executemany一次性写入并提交;批量末尾的剩余数据也会在循环结束后补写提交,任一批失败时执行rollback()并抛出异常。

两种模式写入时都使用ON DUPLICATE KEY UPDATE语义(见 mysql.py):若主键(entity_key, feature_name)已存在,则用新值覆盖valueevent_tscreated_ts,实现“最新物化结果覆盖旧数据”的效果,这正对应 README 中“每次 materialize 调用更新表数据”的描述。需要留意的是,从源码实现看,批量模式读取的是config.online_store.bacth_size(注意该拼写为源码中的实际写法),且批大小小于 2 时会抛出ValueError("Batch size must be at least 2"),配置时建议显式给出合理的batch_size

第五步:在线读取最新特征

物化完成后,即可在应用侧使用 Python SDK 按实体键读取在线特征:

from pprint import pprint from feast import FeatureStore store = FeatureStore(repo_path=".") feature_vector = store.get_online_features( features=[ "driver_hourly_stats:conv_rate", "driver_hourly_stats:acc_rate", "driver_hourly_stats:avg_daily_trips", ], entity_rows=[ {"driver_id": 1004}, {"driver_id": 1005}, ], ).to_dict() pprint(feature_vector)

参考输出:

{'acc_rate': [0.01390857808291912, 0.4063614010810852], 'avg_daily_trips': [69, 706], 'conv_rate': [0.6624961495399475, 0.7595928311347961], 'driver_id': [1004, 1005]}

读取路径的源码实现

get_online_features经由OnlineStore.get_online_features编排后,最终落到MySQLOnlineStore.online_read(见 mysql.py):

  1. 对每个实体键,先用serialize_entity_key序列化并转成十六进制字符串作为entity_key
  2. 执行SELECT feature_name, value, event_ts FROM <table> WHERE entity_key = %s取出该实体全部特征;
  3. value列中的二进制通过ValueProto.ParseFromString反序列化为特征值;
  4. 若查询无记录则返回(None, None),否则返回(event_ts, {feature_name: value})

整个流程是逐实体键串行查询,依赖update阶段创建的表名索引(<table>_ek)来加速entity_key等值查找。另外,从 online_store.py 的_is_versioned_read_supported可以看出,MySQL Online Store 被显式列入支持版本化(versioned)在线读取的存储类型名单中,可配合enable_online_feature_view_versioning与版本化表名(形如_v1_v2)使用,teardown时也会按^<base>_v[0-9]+$正则清理全部版本表。

依赖与测试验证

MySQL Online Store 的 Python 连接层基于pymysql(mysql.py),运行前需确保环境已安装该依赖。仓库内的通用测试配置 mysql_repo_configuration.py 注册了两套测试场景:

  • MySQLOnlineStoreCreator:默认逐条提交模式;
  • BatchWriteMySQLOnlineStoreCreatorbatch_write: True、批大小 1000 的批量提交模式。

两者对应的实现位于 tests/universal/feature_repos/universal/online_store/mysql.py,通过testcontainers.mysql.MySqlContainer启动mysql:latest容器并暴露 3306 端口,使用root/test用户与test数据库完成端到端验证。这意味着非批量与批量两条写入路径都被覆盖在 Feast 的通用在线存储测试集中,是验证本配置可行性的直接参考。

使用建议与注意事项

  • 建库先行MySQLOnlineStore只负责建表与索引,不会创建数据库本身,使用前需确保database: feast指定的库已存在,且连接用户具备建表、索引和读写权限。
  • 选择写入模式:小规模数据与实时验证可直接使用默认逐条提交模式;数据量大、追求物化吞吐时开启batch_write: true并合理设置batch_size(源码要求不小于 2,建议按千级设置以减少提交开销)。
  • 键值存储模型:在线表按“实体键 + 特征名”组织,同一 FeatureView 的多个特征对应同一实体键下的多行记录,主键冲突时由ON DUPLICATE KEY UPDATE保证“后物化者覆盖先物化者”。
  • 生命周期管理feast teardown会调用MySQLOnlineStore.teardown删除对应 FeatureView 的表(版本化开启时连同全部版本表一并清理),不再使用的特征可据此安全释放 MySQL 存储空间。

至此,你已经可以基于这份社区实现,把 MySQL 作为 Feast 的低延迟在线特征存储,走通“定义特征 → apply → 物化 → 在线读取”的完整链路,并为已有 MySQL 基础设施的团队省去额外引入 Redis、DynamoDB 等专用在线存储的成本。

【免费下载链接】feastThe Open Source Feature Store for AI/ML项目地址: https://gitcode.com/GitHub_Trending/fe/feast

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/18 7:35:36

智慧园区综合管理平台功能清单表编写指南

简介&#xff1a;一份完整的智慧园区综合管理平台项目功能清单表&#xff08;V3.0&#xff09;&#xff0c;适用于园区智能化项目的管理人员、系统设计人员及招投标技术负责人&#xff0c;用于梳理功能需求、划分模块边界、明确技术指标。文档以数据底座为起点&#xff0c;覆盖…

作者头像 李华
网站建设 2026/9/18 7:29:13

员工考勤管理系统设计:从规则引擎到跨天数据模型

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/18 7:28:26

基于STM32的智能安防与燃气监测系统:从原理到实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/18 7:26:24

CANN社区邮件列表使用指南:订阅、退订、公共存档与邮件投递实操

CANN社区邮件列表使用指南&#xff1a;订阅、退订、公共存档与邮件投递实操 【免费下载链接】infrastructure 本仓库用于托管CANN社区基础设施团队的公开信息&#xff0c;包括不限于&#xff1a;会议日程&#xff0c;成员信息&#xff0c;服务文档和配置等信息 项目地址: htt…

作者头像 李华
网站建设 2026/9/18 7:26:24

AI内容无损转Word:Markdown、Mermaid与LaTeX的完美转换指南

最近做一套技术归档材料&#xff0c;我把几个大模型生成的方案、流程图和公式整理进了Word。一开始图省事&#xff0c;直接在对话窗口里全选复制&#xff0c;粘贴到Word的瞬间我就知道完了——标题层级全丢&#xff0c;列表变成一堆星号和井号&#xff0c;Mermaid代码原封不动躺…

作者头像 李华