MongoDB Online Store 在线存储指南:Feast 特征仓库的高性能 MongoDB 落地实践
2026/9/17 3:58:41 网站建设 项目流程

MongoDB Online Store 在线存储指南:Feast 特征仓库的高性能 MongoDB 落地实践

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

MongoDB online store 是 Feast 官方提供的一种在线存储实现,用于把特征值物化(materialize)到 MongoDB 中,支撑在线特征检索(online serving)。本文围绕 docs/reference/online-stores/mongodb.md 展开,从配置接入、数据模型、索引策略、异步支持到功能矩阵逐层展开,并结合仓库内 MongoDBOnlineStore 源码 与集成测试,帮助你理解其内部写入/读取原理,并能在自己的特征仓库中直接落地使用。

概述:为什么选择 MongoDB 作为在线存储

Feast 的在线存储负责以低延迟方式提供"最新特征值",支撑线上推理。MongoDB 作为文档型 NoSQL 数据库,天然具备以下适合在线特征服务的能力:

  • 支持 MongoDB Atlas、自建 MongoDB、MongoDB 副本集(replica set)等多种部署形态,连接方式灵活;
  • 文档模型适合按实体(entity key)聚合特征:同一实体的多个特征视图(feature view)可以共存于同一文档中;
  • 自动创建索引、实体键(entity key)同文档聚合(collocation),保证按实体键查询的高效性;
  • 基于 PyMongo 4.13+ 的稳定版AsyncMongoClient提供原生异步读写支持,无需引入 Motor 等额外依赖,可支撑高并发在线特征请求。

在 Feast 中,MongoDB 在线存储的完整实现位于 sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb.py,配置模型为MongoDBOnlineStoreConfig,核心类为MongoDBOnlineStore

快速开始:安装与接入

安装 MongoDB 扩展

使用 MongoDB 在线存储前,需要安装 Feast 的 MongoDB extra,同时按需安装所选离线存储(offline store)的依赖:

pip install 'feast[mongodb]'

该 extra 依赖 PyMongo 客户端。从当前仓库的 CI 依赖锁定文件(如 py3.12-ci-requirements.txt)可以看到,CI 环境中锁定的是pymongo==4.17.0,对应支持异步AsyncMongoClient的 PyMongo 4.13+ 版本线。

从现有模板切换

你可以使用任意 Feast 初始化模板(例如feast init -t gcpfeast init -t snowflakefeast init -t aws)生成特征仓库骨架,然后在feature_store.yaml中把online_store部分替换为 MongoDB 配置即可,离线存储部分保持不变。若未安装 PyMongo,导入MongoDBOnlineStore时会抛出FeastExtrasDependencyImportError提示缺少mongodbextra(见 mongodb.py)。

feature_store.yaml 配置详解

MongoDBOnlineStoreConfig(见 mongodb.py)的完整配置项如下:

配置项类型默认值说明
typeLiteral["mongodb"]"mongodb"在线存储类型选择器,固定为mongodb
connection_stringstr"mongodb://localhost:27017"MongoDB 连接串,支持 Atlas、自建、副本集等多种形态
database_namestr"features"使用的 MongoDB 数据库名
collection_suffixstr"latest"集合名后缀,实际集合名形如<project>_<collection_suffix>
client_kwargsDict[str, Any]{}透传给MongoClient/AsyncMongoClient的任意关键字参数
vector_enabledbool继承自VectorStoreConfig是否启用 Atlas Vector Search 向量检索
similaritystr继承自VectorStoreConfig向量相似度度量(默认cosine
vector_index_wait_timeoutint60等待新建 Atlas Search 索引变为 READY 的超时秒数
vector_index_wait_poll_intervalfloat1.0轮询 Atlas Search 索引状态的间隔秒数

下面给出原文档中的四类典型配置场景。

1. 基础配置:MongoDB Atlas

project: my_feature_repo registry: data/registry.db provider: local online_store: type: mongodb connection_string: "mongodb+srv://username:password@cluster.mongodb.net/" database_name: feast_online_store

Atlas 使用mongodb+srv://协议自动解析副本集节点,适合托管部署。

2. 自建 MongoDB(带认证)

project: my_feature_repo registry: data/registry.db provider: local online_store: type: mongodb connection_string: "mongodb://username:password@localhost:27017/" database_name: feast_online_store collection_suffix: features

注意此处把collection_suffix设为features,最终集合名为my_feature_repo_features(实际取项目名与后缀拼接,见源码_get_collectionf"{repo_config.project}_{online_config.collection_suffix}")。

3. MongoDB 副本集配置

project: my_feature_repo registry: data/registry.db provider: local online_store: type: mongodb connection_string: "mongodb://host1:27017,host2:27017,host3:27017/?replicaSet=myReplicaSet" database_name: feast_online_store client_kwargs: retryWrites: true w: majority

副本集模式下可通过client_kwargs指定写入关注级别(write concern)。retryWrites: true让 MongoDB 驱动在遇到瞬时主从切换错误时自动重试写入,w: majority保证写入被多数节点确认,是生产环境推荐配置。

4. 高级配置:自定义客户端参数

project: my_feature_repo registry: data/registry.db provider: local online_store: type: mongodb connection_string: "mongodb+srv://cluster.mongodb.net/" database_name: feast_online_store collection_suffix: features client_kwargs: maxPoolSize: 50 minPoolSize: 10 serverSelectionTimeoutMS: 5000 connectTimeoutMS: 10000

client_kwargs中的参数会以关键字参数形式原样透传给MongoClient/AsyncMongoClient(源码_get_client_get_client_async均执行MongoClient(connection_string, driver=DRIVER_METADATA, **client_kwargs)),因此 PyMongo 支持的连接池、超时、TLS 等参数均可在这里配置。例如maxPoolSize控制连接池上限、serverSelectionTimeoutMS控制服务器选择超时、connectTimeoutMS控制建连超时,这些参数直接影响高并发下的吞吐与容错表现。

提示:Feast 在创建客户端时还会传入DriverInfo(name="Feast", version=...)作为驱动元数据(见源码 mongodb.py),便于在 MongoDB 服务端监控中识别来自 Feast 的连接。

数据模型:单集合 + 实体键聚合

设计原则

MongoDB 在线存储采用**每个项目一个集合(single collection per project)**的存储布局,并将同一实体的特征按实体键聚合(entity key collocation)。即:来自多个特征视图、面向同一实体的特征,都存放在同一个文档中。这正好与 Mongo 的文档模型契合,一次find即可取回该实体的全部相关特征,避免多表关联查询。

集合名规则为<project>_<collection_suffix>,例如项目my_feature_repo、后缀features时集合为my_feature_repo_features;不使用后缀时默认为<project>_latest

文档 Schema 示例

原文档给出如下示例:单个实体包含来自两个特征视图的特征——driver_stats视图的ratingtrips_last7d,以及pricing视图的surge_multiplier;每个特征视图拥有独立的事件时间戳(event timestamp),created_timestamp标记该实体的物化时间:

{ "_id": "<serialized_entity_key>", // Binary entity key (bytes) "features": { "driver_stats": { "rating": 4.91, "trips_last_7d": 132 }, "pricing": { "surge_multiplier": 1.2 } }, "event_timestamps": { "driver_stats": ISODate("2026-01-20T12:00:00Z"), "pricing": ISODate("2026-01-21T08:30:00Z") }, "created_timestamp": ISODate("2026-01-21T12:00:05Z") }

该 Schema 与源码中MongoDBOnlineStore的类注释完全一致(mongodb.py):_id为序列化后的实体键字节串,features<feature_view>.<feature>嵌套,event_timestamps按特征视图记录更新时间,created_timestamp为整篇文档的全局写入时间。

关键设计决策

  • _id字段:使用序列化实体键(bytes)作为主键,实现 O(1) 级别的按键查询。实体键由 Feast 的serialize_entity_key依据entity_key_serialization_version序列化(见 key_encoding_utils)。
  • 嵌套特征:特征按特征视图名组织,一个实体文档可承载多个特征视图的数据;
  • 事件时间戳:按特征视图分别存储,追踪每个特征集合的最后更新时间,支撑 point-in-time 语义;
  • 创建时间戳:整篇文档的全局写入时间。

索引策略

在线存储只依赖一个自动索引:_id上的主键索引(MongoDB 自动创建),其值即序列化实体键。由于查询全部以_id{"$in": [ids]})或向量检索索引展开,在线读写无需额外创建二级索引。

读写实现原理:从源码看数据流

写入:bulk_write + upsert

写入入口为online_write_batch(同步)与online_write_batch_async(异步),两者共享_build_write_ops构造更新操作(mongodb.py)。其流程为:

  1. serialize_entity_key将实体键序列化为字节串,作为_id
  2. feast_value_type_to_python_type将每个特征的ValueProto转换为 Python 原生类型;
  3. 构造$set更新文档:特征值写入features.<feature_view>.<feature>,该视图事件时间写入event_timestamps.<feature_view>,行级写入时间写入created_timestamp
  4. 包装为UpdateOne(filter={"_id": entity_id}, update=..., upsert=True)——已存在的实体文档原地更新,新实体首次写入时自动创建;
  5. 通过collection.bulk_write(ops, ordered=False)(异步为await collection.bulk_write(...))一次性批量执行,ordered=False允许并行处理,提升吞吐。

集成测试 test_mongodb_online_retrieval.py 展示了完整的写入-读取回路:向driver_locationscustomer_profilecustomer_driver_combined三个特征视图写入不同实体键的特征,随后用get_online_features跨视图读取并断言结果。测试中还验证了复合实体键customer_id+driver_id)与"写入过其他视图但从未写入当前视图"的实体返回None的边界行为。

读取:$in 查询 + 投影裁剪

读取入口为online_read/online_read_async(mongodb.py):

  1. 将所有实体键序列化为ids
  2. 构造{"_id": {"$in": ids}}查询过滤;
  3. 投影(projection)只取需要的字段:_idevent_timestamps.<fv>,以及请求的特征字段features.<fv>.<feature>(未指定请求特征时取整个features.<fv>子树)——这保证了网络传输的最小化;
  4. 命中结果经_convert_raw_docs_to_proto转换:由于 MongoDB 查询是行导向、而 Feast 的类型转换器是列导向(按特征类型批量转换),源码采取"先按列抽取原始值、按特征批量转成ValueProto、再按行重组"的两次转换策略,既保持实体键顺序对齐,又最小化 python/proto 转换调用次数(mongodb.py)。

基础设施管理:update 与 teardown

  • update():MongoDB 是松散的惰性 Schema,无需预建表结构。它只负责两件事:对tables_to_delete中的特征视图执行$unset删除其features.<fv>event_timestamps.<fv>字段;当启用向量检索时为保留的特征视图创建/清理 Atlas Search 索引(详见下文向量检索章节)。
  • teardown():直接clxn.drop()删除整个集合,并关闭同步客户端连接(mongodb.py)。异步客户端通过close()释放资源。

原生异步支持:PyMongo AsyncMongoClient

MongoDB 在线存储基于 PyMongo 4.13+ 的稳定版AsyncMongoClient提供原生异步能力,不依赖 Motor。异步支持的能力包括:

  • 高并发:异步 I/O 不会受线程池限制,可支撑数千级并发特征请求;
  • 真正的异步非阻塞:适合嵌入 FastAPI 等异步在线推理服务;
  • 并发场景性能提升:原文档指出相对同步顺序执行,并发负载下可带来 10–20 倍的性能提升(该数据为项目文档口径,实际收益取决于工作负载与部署环境,建议结合自身压测验证)。

同步与异步方法一一对应、完全对等:

同步异步
online_readonline_read_async
online_write_batchonline_write_batch_async

类属性async_supported返回SupportedAsyncMethods(read=True, write=True),显式声明读写均支持异步(mongodb.py)。异步客户端与同步客户端相互独立缓存:_client/_collection_client_async/_collection_async分别持有连接,异步写入同样复用_build_write_ops生成UpdateOne操作,再经await clxn.bulk_write(ops, ordered=False)执行,保证读写行为与同步路径完全一致。

扩展能力:MongoDB Atlas Vector Search

MongoDB 在线存储还支持向量检索($vectorSearch),可支撑 RAG 等语义检索场景。启用方式是在配置中设置vector_enabled: true,并在特征定义中为向量字段标注vector_index=Truevector_lengthvector_search_metric

update()阶段会自动为每个 (feature_view, vector_field) 组合创建名为<fv>__<field>__vs_index的 Atlas Search 索引,并通过轮询等待其变为 READY(vector_index_wait_timeout/vector_index_wait_poll_interval控制等待行为);索引创建是幂等的,重复调用update()不会重复建索引。特征视图被删除时,对应的向量索引也会被清理。

检索入口retrieve_online_documents_v2使用$vectorSearch聚合阶段按余弦/欧氏等相似度返回top_k个最近文档,并将向量搜索得分以distance特征返回。集成测试 test_mongodb_vector_search.py 使用mongodb/mongodb-atlas-local:8.0.4本地 Atlas 镜像验证了索引创建、写入-检索往返、top_k限制、更新幂等性与 teardown 清理等完整链路。仓库内的 RAG 示例(如 examples/rag)即采用此类向量检索能力构建检索增强生成应用。

功能矩阵:能力边界一览

原文档给出了 MongoDB 在线存储相对 overview.md 功能定义的能力矩阵:

功能MongoDB
向在线存储写入特征值yes
从在线存储读取特征值yes
更新在线存储基础设施(如表)yes
销毁在线存储基础设施(如表)yes
生成基础设施变更计划no
支持 on-demand transformsyes
可被 Python SDK 读取yes
可被 Java 读取no
可被 Go 读取no
支持无实体特征视图(entityless)yes
支持并发写入同一键yes
检索时支持 TTL(time to live)no
支持删除过期数据no
按特征视图聚合(collocated by feature view)no
按特征服务聚合(collocated by feature service)no
按实体键聚合(collocated by entity key)yes

要点解读:

  • 基础设施变更计划(plan)不支持:与 Postgres、Redis 等"表驱动"存储不同,MongoDB 采用集合 + 文档的惰性 Schema,update()中几乎无结构变更可言,因此不生成变更计划;
  • TTL 与过期数据删除不支持:目前 MongoDB 在线存储不基于特征视图 TTL 做检索过滤或物理清理,需要结合应用侧或 MongoDB TTL 索引自行规划;
  • 按实体键聚合:这是其核心布局,与"单集合 + 文档"设计一致;
  • 读写语言覆盖:目前仅 Python SDK 可读,Java / Go 特征服务器尚不消费该存储。

完整的能力对比矩阵见 overview.md。

测试与本地验证

仓库为 MongoDB 在线存储提供了多层测试,便于本地复现验证:

  • 单元/集成检索测试:test_mongodb_online_retrieval.py 通过testcontainersMongoDbContainermongo:latest,内置用户名/密码认证)启动容器,验证多特征视图写入、跨视图读取、复合实体键与缺失特征视图返回None等行为;
  • 通用在线存储测试:test_universal_online.py 覆盖所有通用在线存储的公共行为契约;
  • 向量检索测试:test_mongodb_vector_search.py 覆盖 Atlas Vector Search 全链路;
  • 测试仓库配置:mongodb_repo_configuration.py 注册了 MongoDB 的IntegrationTestRepoConfig,复用MongoDBOnlineStoreCreatormongo:latest容器中建立带认证的连接串。

这些测试均要求本机 Docker 可用(测试内以_requires_docker跳过),可用于理解连接串格式与认证场景的配置范式。

总结

MongoDB online store 以"每项目单集合 + 实体键文档聚合"的设计,为 Feast 在线特征服务提供了一种部署灵活、扩展简单的存储选项:支持 Atlas / 自建 / 副本集多形态连接,client_kwargs可精细调优连接池与超时;_id主键索引 + 投影裁剪保证按键查询高效;同步/异步双通道读写支撑高并发在线推理;并可通过 Atlas Vector Search 扩展语义检索能力。接入时只需在feature_store.yaml中配置type: mongodb与连接参数,即可在既有特征仓库中无缝启用。

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

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询