快速入门
本页重点介绍 FeatureStore 自定义资源,它是 operator 安装完成后用于部署和配置 Feast 的主要接口。
先决条件
- 已安装 Feast Operator。请参见 安装 Feast。
- 对于基于 PVC 的示例,集群应具有默认的
StorageClass,或者应提前 জানা目标 storageClassName。
- 对于使用外部后端而不是基于 PVC 的文件存储,请提前准备所需服务:
- 建议使用 PostgreSQL 16。PostgreSQL 用于 SQL registry,也可选用于 PostgreSQL online store。
- 建议使用 Redis 6.0 或更高版本。Redis 用于 Redis online store。Feast 支持单个 Redis 实例、Redis Cluster 和 Redis Sentinel。
- 在
FeatureStore CR 引用这些后端之前,请先准备包含后端连接参数的 Kubernetes Secret。
对于本页中的 PostgreSQL 和 Redis 示例,默认假定后端服务、数据库或 schema、凭据以及 Kubernetes Secret 已经存在。仍应在目标集群中验证连通性和驱动兼容性。
FeatureStore CR 概览
FeatureStore CR 中最常用的字段如下:
常见服务配置
离线存储
offlineStore 控制历史特征数据的存储位置,以及是否暴露远程 offline server。
常见选项:
persistence.file:基于文件的存储,通常是在 PVC 上使用 DuckDB,适用于本地开发和评估
persistence.store:外部离线后端,例如 BigQuery 或其他受支持的 Feast offline store
server: {}:创建用于网络访问的远程 offline server Service
基于 PVC 的 DuckDB 示例:
services:
offlineStore:
persistence:
file:
type: duckdb
pvc:
create:
storageClassName: fast
resources:
requests:
storage: 10Gi
mountPath: /data/offline
server: {}
基于 store 的示例:
services:
offlineStore:
persistence:
store:
type: bigquery
secretRef:
name: feast-data-stores
server: {}
在线存储
onlineStore 用于低延迟特征服务。
常见选项:
persistence.file:基于文件的本地存储,通常仅用于开发
persistence.store:Redis、PostgreSQL 或其他受支持的 Feast online store 后端
server:可选的额外 server 设置,例如 env、envFrom、resources、tls 或 volumeMounts
本页示例推荐的后端版本:
- Redis 6.0 或更高版本
- PostgreSQL 16
基于 PVC 的文件示例:
services:
onlineStore:
persistence:
file:
path: online_store.db
pvc:
create:
resources:
requests:
storage: 5Gi
mountPath: /data/online
基于 Redis 的示例:
services:
onlineStore:
persistence:
store:
type: redis
secretRef:
name: feast-data-stores
基于 PostgreSQL 的示例:
services:
onlineStore:
persistence:
store:
type: postgres
secretRef:
name: feast-data-stores
server:
envFrom:
- secretRef:
name: postgres-secret
registry
registry 用于存储 Feast 元数据。它可以是当前 FeatureStore 的本地 registry,也可以复用远程 registry。
常见选项:
registry.local.persistence.file:位于 PVC 或对象存储上的基于文件的 registry
registry.local.persistence.store:基于 SQL 的 registry
registry.local.server: {}:暴露 registry server 以供远程访问
registry.remote:复用另一个 FeatureStore 或外部主机名中的 registry
对于本页中的 SQL-backed registry 示例,建议使用 PostgreSQL 16。
基于 PVC 的 registry 示例:
services:
registry:
local:
persistence:
file:
path: registry.db
pvc:
create:
resources:
requests:
storage: 5Gi
mountPath: /data/registry
server: {}
基于 SQL 的 registry 示例:
services:
registry:
local:
persistence:
store:
type: sql
secretRef:
name: feast-data-stores
server: {}
远程 registry 示例:
services:
registry:
remote:
feastRef:
name: <shared-featurestore-name>
namespace: <shared-namespace>
UI
要启用 Feast UI,请设置:
如果不设置 ui: {},则不会创建 UI Service。
常见持久化模式
基于 PVC 的配置
这是用于评估、本地测试和单副本部署的最简单模式:
apiVersion: feast.dev/v1
kind: FeatureStore
metadata:
name: <featurestore-name>
namespace: <namespace>
spec:
feastProject: <feast-project>
replicas: 1
services:
offlineStore:
persistence:
file:
type: duckdb
pvc:
create:
resources:
requests:
storage: 10Gi
mountPath: /data/offline
server: {}
onlineStore:
persistence:
file:
path: online_store.db
pvc:
create:
resources:
requests:
storage: 5Gi
mountPath: /data/online
registry:
local:
persistence:
file:
path: registry.db
pvc:
create:
resources:
requests:
storage: 5Gi
mountPath: /data/registry
server: {}
ui: {}
Redis Online Store + SQL Registry
这是用于持久化 online store 和基于数据库的 registry 的常见模式。
先创建 Secret:
apiVersion: v1
kind: Secret
metadata:
name: feast-data-stores
namespace: <namespace>
type: Opaque
stringData:
redis: |
connection_string: redis.<namespace>.svc.cluster.local:6379,password=<redis-password>
sql: |
path: postgresql+psycopg://<user>:<password>@postgres.<namespace>.svc.cluster.local:5432/feast
cache_ttl_seconds: 60
sqlalchemy_config_kwargs:
pool_pre_ping: true
echo: false
然后在 FeatureStore 中引用它:
apiVersion: feast.dev/v1
kind: FeatureStore
metadata:
name: <featurestore-name>
namespace: <namespace>
spec:
feastProject: <feast-project>
services:
offlineStore:
persistence:
file:
type: duckdb
pvc:
create: {}
mountPath: /data/offline
server: {}
onlineStore:
persistence:
store:
type: redis
secretRef:
name: feast-data-stores
registry:
local:
persistence:
store:
type: sql
secretRef:
name: feast-data-stores
server: {}
ui: {}
PostgreSQL Online Store + SQL Registry
如果将 PostgreSQL 作为 online store 后端,Secret 可以同时包含 postgres 和 sql 条目:
apiVersion: v1
kind: Secret
metadata:
name: feast-data-stores
namespace: <namespace>
type: Opaque
stringData:
postgres: |
host: postgres.<namespace>.svc.cluster.local
port: 5432
database: feast
db_schema: public
user: <user>
password: <password>
sql: |
path: postgresql+psycopg://<user>:<password>@postgres.<namespace>.svc.cluster.local:5432/feast
cache_ttl_seconds: 60
sqlalchemy_config_kwargs:
pool_pre_ping: true
echo: false
然后使用:
services:
onlineStore:
persistence:
store:
type: postgres
secretRef:
name: feast-data-stores
registry:
local:
persistence:
store:
type: sql
secretRef:
name: feast-data-stores
server: {}
对象存储中的 registry
registry 文件也可以放在 S3 或 GCS 中:
services:
registry:
local:
persistence:
file:
path: s3://bucket/registry.db
cache_ttl_seconds: 60
cache_mode: sync
关于 Secret 的说明
当使用 persistence.store 时,operator 会从 Kubernetes Secret 中读取后端参数。
重要说明:
- 默认情况下,Secret 键名与配置的
type 匹配
- 对于
type: redis,operator 读取 redis 键
- 对于
type: postgres,operator 读取 postgres 键
- 对于
type: sql,operator 读取 sql 键
- 如有需要,可使用
secretKeyName 覆盖键名
Secret 内容应遵循 feature_store.yaml 中使用的后端配置样式,但需要省略后端自身的 type 字段。
特征仓库初始化
operator 可以通过三种常见方式初始化特征仓库。
默认初始化
如果未设置 spec.feastProjectDir,operator 会执行默认的 feast init <project>,并在以下路径下创建仓库:
<offline mount path>/<feastProject>/feature_repo
Init 模板
当 operator 需要引导特定 Feast 模板时,可以使用 init 模板:
spec:
feastProject: <feast-project>
feastProjectDir:
init:
template: spark
Git 仓库
当特征定义已经在源码管理中维护时,可以使用 Git:
spec:
feastProject: <feast-project>
feastProjectDir:
git:
url: https://github.com/feast-dev/feast-credit-score-local-tutorial
ref: 598a270
如果特征仓库不位于默认的 feature_repo 子目录中,请设置 featureRepoPath。
部署 FeatureStore
应用基于 PVC 的示例:
kubectl apply -f featurestore.yaml
主要的就绪字段是 status.phase。当部署就绪时,此字段会变为 Ready。
可通过以下命令直接检查:
kubectl get featurestore <featurestore-name> -n <namespace> -o jsonpath='{.status.phase}'
服务与访问
operator 会将连接信息写入 FeatureStore 的 status:
kubectl get featurestore <featurestore-name> -n <namespace> -o jsonpath='{.status.serviceHostnames}'
kubectl get featurestore <featurestore-name> -n <namespace> -o jsonpath='{.status.clientConfigMap}'
operator 使用以下模式创建 Service 名称:feast-<featurestore-name>-<component>。常见示例如下:
feast-<featurestore-name>-online
feast-<featurestore-name>-offline
feast-<featurestore-name>-registry
feast-<featurestore-name>-ui
生成的 clientConfigMap 包含当前 FeatureStore 部署对应的客户端 feature_store.yaml。配置存储在 feature_store.yaml 键下,Feast 客户端可以直接加载,包括 Python 应用程序和集群内作业。
常见访问模式:
- 在集群内使用生成的 Service 名称
- 使用生成的 client ConfigMap 作为 Feast 客户端配置
- 通过目标环境中使用的访问方式暴露这些 Service
如果需要访问 offline server 或 registry server,则应在 CR 中设置 offlineStore.server: {} 或 registry.local.server: {}。
使用 Feast SDK 和 CLI
特征定义通常维护在 FeatureStore 工作负载之外,例如本地仓库、Git 仓库、CI 作业或其他基于 SDK 的工作流中。生成的客户端 feature_store.yaml 用于将 Feast CLI 或 Python SDK 连接到已部署的服务。
当从客户端环境运行 feast apply 时,registry service 必须可被 Feast 客户端访问。对于本页使用的本地 registry 模式,请设置:
services:
registry:
local:
server: {}
如果还需要远程 materialization 或远程 historical retrieval,也请暴露 offline server:
services:
offlineStore:
server: {}
仓库布局
在 Feast 客户端环境中准备一个特征仓库,并将生成的客户端配置作为 feature_store.yaml 放入该仓库。配置可以从 .status.clientConfigMap 中指定的 ConfigMap 读取。
示例仓库布局:
<feature-repo>/
feature_store.yaml
driver_repo.py
data/
仓库根目录是包含 feature_store.yaml 的目录。
Feast CLI 和 Python SDK 都使用同一个仓库根目录。对于 Python 代码,可通过以下方式加载:
from feast import FeatureStore
store = FeatureStore(repo_path=".")
特征定义示例
下面的示例定义了一个 entity、一个基于文件的 batch source、两个 feature view、一个 push source 和一个 feature service。这些对象足以在单个仓库中演示注册、在线服务、materialization 和基于 push 的更新。
driver_stats_source 从 data/driver_stats.parquet 读取批量数据。driver_hourly_stats 暴露这些字段,用于常规的 batch-to-online materialization。driver_stats_push_source 和 driver_hourly_stats_fresh 展示同一 entity 如何通过 push 接收新鲜值。driver_activity_v1 将该 feature view 组合为可复用的服务定义。
示例特征定义文件:
from datetime import timedelta
from feast import Entity, FeatureService, FeatureView, Field, FileSource, PushSource
from feast.data_format import ParquetFormat
from feast.types import Float32, Int64
from feast.value_type import ValueType
driver = Entity(name="driver", join_keys=["driver_id"], value_type=ValueType.INT64)
driver_stats_source = FileSource(
name="driver_stats_source",
path="data/driver_stats.parquet",
file_format=ParquetFormat(),
timestamp_field="event_timestamp",
created_timestamp_column="created",
)
driver_hourly_stats = FeatureView(
name="driver_hourly_stats",
entities=[driver],
ttl=timedelta(days=365),
schema=[
Field(name="conv_rate", dtype=Float32),
Field(name="acc_rate", dtype=Float32),
Field(name="avg_daily_trips", dtype=Int64),
],
online=True,
source=driver_stats_source,
)
driver_stats_push_source = PushSource(
name="driver_stats_push_source",
batch_source=driver_stats_source,
)
driver_hourly_stats_fresh = FeatureView(
name="driver_hourly_stats_fresh",
entities=[driver],
ttl=timedelta(days=365),
schema=[
Field(name="conv_rate", dtype=Float32),
Field(name="acc_rate", dtype=Float32),
Field(name="avg_daily_trips", dtype=Int64),
],
online=True,
source=driver_stats_push_source,
)
driver_activity_v1 = FeatureService(
name="driver_activity_v1",
features=[driver_hourly_stats],
)
CLI
从特征仓库的根目录运行 feast apply。在上面的示例中,该命令是在 <feature-repo> 中运行的,而不是在 data/ 子目录中运行。
feast apply 会从仓库根目录读取 feature_store.yaml,并递归扫描该仓库中的 Python 文件。如果特征定义存储在子目录中,只要这些文件位于仓库内且未被 .feastignore 排除,命令仍然应从仓库根目录运行。
如果从其他工作目录运行该命令,请显式指定仓库:
feast --chdir /path/to/<feature-repo> apply
默认形式为:
配置授权
Feast 中基于 Kubernetes 的授权由三部分组成:
- 在
FeatureStore CR 中声明角色名称。
- 使用相同的角色名称在特征仓库中定义 Feast
Permission 对象。
- 通过
RoleBinding 将 Kubernetes 用户或 ServiceAccount 绑定到这些角色。
仅在 FeatureStore CR 中声明 feast-reader 和 feast-writer 并将主体绑定到这些角色,还不足以完成授权。Feast 的授权决策还需要特征仓库中匹配的 Permission 定义。
FeatureStore 片段示例:
spec:
authz:
kubernetes:
roles:
- feast-reader
- feast-writer
特征仓库中的 Permission 定义示例:
from feast import Entity, FeatureService, FeatureView
from feast.permissions.action import ALL_ACTIONS, READ
from feast.permissions.permission import Permission
from feast.permissions.policy import RoleBasedPolicy
reader_perm = Permission(
name="reader_perm",
types=[Entity, FeatureView, FeatureService],
policy=RoleBasedPolicy(roles=["feast-reader"]),
actions=READ,
)
writer_perm = Permission(
name="writer_perm",
types=[Entity, FeatureView, FeatureService],
policy=RoleBasedPolicy(roles=["feast-writer"]),
actions=ALL_ACTIONS,
)
添加或更新 Permission 对象后,请运行 feast apply,以便将授权元数据注册到 Feast 中。
RoleBinding 配置示例:
apiVersion: v1
kind: ServiceAccount
metadata:
name: feast-reader-sa
namespace: <namespace>
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: feast-writer-sa
namespace: <namespace>
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: feast-reader-binding
namespace: <namespace>
subjects:
- kind: ServiceAccount
name: feast-reader-sa
namespace: <namespace>
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: feast-reader
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: feast-writer-binding
namespace: <namespace>
subjects:
- kind: ServiceAccount
name: feast-writer-sa
namespace: <namespace>
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: feast-writer
创建示例 ServiceAccount token:
READER_TOKEN=$(kubectl create token feast-reader-sa -n <namespace>)
WRITER_TOKEN=$(kubectl create token feast-writer-sa -n <namespace>)
如果需要自定义 token 生命周期,请在命令中添加 --duration。
SDK token 配置
启用 authz.kubernetes 后,Feast Python 客户端会自动将 token 作为 bearer token 发送。对于运行在同一集群内且挂载了 ServiceAccount token 的客户端,通常不需要额外的 SDK 设置。
对于外部客户端,可通过以下方式之一提供 token:
- 在
feature_store.yaml 中设置 authz_config.user_token
- 设置
LOCAL_K8S_TOKEN 环境变量
feature_store.yaml 片段示例:
authz_config:
type: kubernetes
user_token: <kubernetes-token>
环境变量示例:
export LOCAL_K8S_TOKEN=<kubernetes-token>
延伸阅读
有关端到端 Feast 工作流和更广泛的产品用法,请继续阅读 Feast 官方文档: