Feast核心架构深度剖析:离线与在线存储机制

Feast核心架构深度剖析:离线与在线存储机制

【免费下载链接】feast Feature Store for Machine Learning 【免费下载链接】feast 项目地址: https://gitcode.com/GitHub_Trending/fe/feast

Feast作为现代机器学习特征存储平台,其核心创新在于独特的双存储架构设计,巧妙解决了机器学习工作流中训练与服务的不同需求矛盾。本文深度剖析了Feast的离线与在线存储机制,包括双存储架构设计原理、离线存储支持的数据仓库集成、在线低延迟存储技术实现,以及特征服务器与客户端SDK架构。通过这种精心设计的架构,Feast为机器学习团队提供了既能够处理大规模历史数据,又能够支持低延迟实时服务的完整特征管理解决方案。

Feast双存储架构设计原理

Feast作为现代机器学习特征存储平台,其核心创新之一便是独特的双存储架构设计。这种架构巧妙地解决了机器学习工作流中训练与服务的不同需求矛盾,为特征工程提供了统一而高效的管理方案。

架构设计哲学

Feast的双存储架构基于一个核心洞察:机器学习工作流中的训练和服务阶段对特征数据有着截然不同的访问模式和性能要求:

  • 训练阶段:需要大规模的历史数据进行批量处理,关注数据完整性和时间点正确性
  • 服务阶段:需要低延迟的实时特征访问,关注响应时间和并发性能

mermaid

离线存储机制深度解析

离线存储作为Feast的数据基石,负责处理海量历史特征数据。其设计遵循以下核心原则:

数据分区与时序管理
# Feast离线存储的时间分区策略示例
class TimePartitionedOfflineStore:
    def __init__(self, storage_backend, partition_granularity="DAY"):
        self.backend = storage_backend
        self.granularity = partition_granularity
        
    def get_historical_features(self, entity_df, feature_refs, event_timestamp):
        # 基于时间范围进行分区剪枝优化查询
        partitions = self._prune_partitions(entity_df[event_timestamp])
        return self.backend.execute_query(partitions, feature_refs)

离线存储通过智能的时间分区策略,实现了高效的历史数据检索。每个分区包含特定时间范围内的特征数据,支持基于时间点的精确查询。

点-in-time正确性保障

Feast确保训练数据的时间点正确性,避免数据泄露问题:

mermaid

在线存储架构设计

在线存储针对低延迟访问优化,采用完全不同的数据组织和访问模式:

内存优化数据结构
class OptimizedOnlineStore:
    def __init__(self, storage_engine):
        self.engine = storage_engine
        self.cache = LRUCache(max_size=100000)
        
    def get_online_features(self, entity_keys, feature_names):
        # 批量获取优化,减少网络往返
        results = []
        for key in entity_keys:
            if key in self.cache:
                results.append(self.cache[key])
            else:
                feature_data = self.engine.get(key, feature_names)
                self.cache[key] = feature_data
                results.append(feature_data)
        return results
实时数据同步机制

离线存储和在线存储之间的数据同步是架构的关键环节:

mermaid

双存储协同工作流程

Feast通过精心设计的协同机制确保两个存储系统的一致性:

数据物化过程
def materialize_features(feature_store, start_date, end_date):
    """将离线特征物化到在线存储"""
    # 1. 从离线存储获取增量数据
    incremental_data = feature_store.offline_store.get_incremental_data(
        start_date, end_date
    )
    
    # 2. 数据转换和优化
    optimized_data = _optimize_for_online(incremental_data)
    
    # 3. 批量写入在线存储
    feature_store.online_store.batch_write(optimized_data)
    
    # 4. 更新元数据版本
    feature_store.registry.update_materialization_interval(
        start_date, end_date
    )
一致性保障策略
策略类型实现机制优势
最终一致性异步物化作业高性能,低延迟
版本控制特征版本标记避免读写冲突
回退机制检查点和日志数据安全可靠

性能优化技术

Feast在双存储架构中采用了多项性能优化技术:

查询优化
-- Feast生成的优化查询示例
SELECT 
    entity_id,
    feature_value,
    event_timestamp
FROM offline_features
WHERE entity_id IN (:entity_ids)
AND event_timestamp <= :request_timestamp
AND event_timestamp >= :ttl_start
QUALIFY ROW_NUMBER() OVER (
    PARTITION BY entity_id 
    ORDER BY event_timestamp DESC
) = 1
缓存策略

Feast实现了多级缓存体系来提升性能:

  • 内存缓存:高频访问数据的快速响应
  • 查询结果缓存:重复查询的结果复用
  • 元数据缓存:减少注册表访问开销

扩展性与插件架构

Feast的双存储设计支持灵活的扩展机制:

# 自定义存储插件示例
class CustomOnlineStore(OnlineStore):
    def online_write_batch(self, config, table, data):
        # 实现自定义写入逻辑
        pass
        
    def online_read(self, config, table, entity_keys):
        # 实现自定义读取逻辑
        pass

# 注册自定义存储
feast.register_online_store("custom", CustomOnlineStore)

这种插件化架构使得Feast能够支持多种存储后端,包括Redis、DynamoDB、BigTable等,同时保持统一的API接口。

容错与监控

双存储架构内置了完善的容错机制:

  • 写入重试:网络故障时的自动重试
  • 数据校验:写入前后的数据一致性检查
  • 监控指标:实时监控两个存储系统的健康状态
  • 告警系统:异常情况的及时通知

通过这种精心设计的双存储架构,Feast为机器学习团队提供了既能够处理大规模历史数据,又能够支持低延迟实时服务的完整特征管理解决方案。

离线存储支持的数据仓库集成

Feast作为一个企业级的特征存储平台,其离线存储层提供了与多种主流数据仓库的无缝集成能力。这种集成不仅简化了特征工程流程,还确保了数据的一致性和可扩展性。下面我们将深入探讨Feast支持的各类数据仓库集成方案及其技术实现细节。

多数据仓库支持矩阵

Feast通过统一的抽象接口支持多种数据仓库作为离线存储后端,下表展示了当前支持的主要数据仓库类型及其关键特性:

数据仓库类型官方支持状态SQL方言兼容性分布式计算云原生集成典型使用场景
Snowflake✅ 官方支持ANSI SQL✅ 自动扩展✅ 多云支持大规模企业级分析
BigQuery✅ 官方支持BigQuery SQL✅ 服务器less✅ GCP原生Google云生态集成
Redshift✅ 官方支持PostgreSQL✅ 集群扩展✅ AWS原生AWS数据湖屋集成
PostgreSQL✅ 贡献插件PostgreSQL❌ 单实例✅ 混合云中小规模部署
Spark✅ 贡献插件Spark SQL✅ 分布式✅ 多环境大数据处理生态
Trino✅ 贡献插件ANSI SQL✅ 分布式✅ 多环境联邦查询场景

统一抽象架构设计

Feast通过精心设计的抽象层实现了多数据仓库的无缝集成,其核心架构如下图所示:

mermaid

配置示例与最佳实践

Snowflake集成配置
# feature_store.yaml
project: production_ml
registry: s3://my-bucket/registry.db
provider: aws
offline_store:
  type: snowflake.offline
  account: my_company.us-east-1.snowflakecomputing.com
  user: ${SNOWFLAKE_USER}
  password: ${SNOWFLAKE_PASSWORD}
  role: DATA_ENGINEER
  warehouse: ML_WH
  database: FEATURE_STORE
  schema: PROD
  authenticator: externalbrowser
BigQuery集成配置
offline_store:
  type: bigquery.offline
  project: my-gcp-project
  dataset: feature_store
  location: US
  credentials_path: /path/to/service-account-key.json
  temp_location: gs://my-bucket/temp/

高级特性与性能优化

点时间正确性查询

Feast在所有支持的离线存储中实现了高效的点时间正确性查询,确保特征检索的时间一致性:

# 点时间正确性查询示例
entity_df = pd.DataFrame({
    "driver_id": [1001, 1002, 1003],
    "event_timestamp": [
        datetime(2023, 10, 15, 14, 30),
        datetime(2023, 10, 15, 15, 45), 
        datetime(2023, 10, 15, 16, 20)
    ]
})

training_df = store.get_historical_features(
    entity_df=entity_df,
    features=[
        'driver_stats:avg_trip_duration',
        'driver_stats:acceptance_rate',
        'driver_stats:total_earnings'
    ]
).to_df()
分布式计算优化

对于大规模数据集,Feast利用数据仓库的分布式计算能力进行优化:

-- Feast生成的Snowflake优化查询示例
WITH entity_data AS (
  SELECT 
    driver_id,
    event_timestamp,
    ROW_NUMBER() OVER (PARTITION BY driver_id ORDER BY event_timestamp) as row_num
  FROM temporary_entity_table
),
feature_data AS (
  SELECT
    driver_id,
    event_timestamp as feature_timestamp,
    avg_trip_duration,
    acceptance_rate,
    total_earnings,
    ROW_NUMBER() OVER (
      PARTITION BY driver_id 
      ORDER BY ABS(DATEDIFF(second, feature_timestamp, e.event_timestamp))
    ) as time_rank
  FROM driver_stats_features d
  JOIN entity_data e ON d.driver_id = e.driver_id
  WHERE d.feature_timestamp <= e.event_timestamp
)
SELECT 
  e.driver_id,
  e.event_timestamp,
  f.avg_trip_duration,
  f.acceptance_rate,
  f.total_earnings
FROM entity_data e
LEFT JOIN feature_data f ON e.driver_id = f.driver_id AND f.time_rank = 1
WHERE e.row_num = 1

数据分区与性能考量

不同的数据仓库在分区策略上有所差异,Feast针对每种存储进行了专门优化:

数据仓库分区策略支持自动分区管理查询性能优化成本优化特性
Snowflake自动微分区✅ 全自动✅ 聚类键✅ 按需扩展
BigQuery分区表✅ 时间分区✅ 聚类✅ 槽租赁
Redshift分布键✅ 排序键✅ 压缩编码✅ 并发扩展
PostgreSQL表分区❌ 手动✅ 索引❌ 有限扩展

监控与运维集成

Feast提供了完善的监控指标和运维集成能力:

在线低延迟存储技术实现

Feast的在线存储层是实现低延迟特征服务的关键组件,它专门为高并发、低延迟的在线推理场景设计。在线存储负责存储最新的特征值,支持毫秒级的特征检索,为实时机器学习推理提供数据支撑。

核心架构设计

Feast在线存储采用统一的抽象接口设计,定义了标准化的数据访问模式:

mermaid

所有在线存储实现都必须遵循OnlineStore抽象基类定义的接口规范,确保不同存储后端的行为一致性。

Redis存储实现深度解析

Redis作为Feast最常用的在线存储后端,采用了高度优化的数据模型和访问模式:

数据模型设计

Redis存储采用两级哈希映射结构:

  • 第一级Key: 由项目名和实体键组成,使用Protobuf序列化
  • 第二级Field: 特征视图名和特征名的MurmurHash3哈希值
# Redis键生成算法
def _redis_key(project: str, entity_key: EntityKeyProto) -> bytes:
    """生成Redis存储键"""
    redis_key_proto = RedisKeyV2(
        project=project,
        entity_names=sorted(entity_key.entity_names),
        entity_values=entity_key.entity_values
    )
    return redis_key_proto.SerializeToString()
高性能写入机制

Redis在线存储采用批量写入和管道优化技术:

def online_write_batch(self, config, table, data, progress):
    client = self._get_client(config.online_store)
    with client.pipeline(transaction=False) as pipe:
        # 预检查现有时间戳
        for entity_key, _, _, _ in data:
            redis_key = _redis_key(config.project, entity_key)
            pipe.hmget(redis_key, ts_key)
        prev_timestamps = pipe.execute()
        
        # 批量写入新数据
        for i, (entity_key, values, timestamp, created_ts) in enumerate(data):
            if should_update(prev_timestamps[i], timestamp):
                redis_key = _redis_key(config.project, entity_key)
                feature_data = {
                    _mmh3(f"{table.name}:{feature_name}"): value.SerializeToString()
                    for feature_name, value in values.items()
                }
                feature_data[f"_ts:{table.name}"] = timestamp_to_proto(timestamp)
                pipe.hmset(redis_key, feature_data)
        pipe.execute()
低延迟读取优化

读取操作采用并行管道和批量查询:

def online_read(self, config, table, entity_keys, requested_features):
    client = self._get_client(config.online_store)
    requested_features, hset_keys = self._generate_hset_keys_for_features(
        table, requested_features
    )
    keys = self._generate_redis_keys_for_entities(config, entity_keys)
    
    # 使用管道批量查询
    with client.pipeline(transaction=False) as pipe:
        for redis_key in keys:
            pipe.hmget(redis_key, hset_keys)
        redis_values = pipe.execute()
    
    return self._convert_redis_values_to_protobuf(
        redis_values, table.name, requested_features
    )

SQLite存储实现

虽然SQLite不适合生产环境,但其实现展示了关系型数据库的存储模式:

def online_read(self, config, table, entity_keys, requested_features):
    conn = self._get_conn(config)
    result = []
    
    serialized_keys = [
        serialize_entity_key(ek, config.entity_key_serialization_version)
        for ek in entity_keys
    ]
    
    # 单次查询获取所有实体数据
    cur = conn.execute(f"""
        SELECT entity_key, feature_name, value, event_ts 
        FROM {_table_id(config.project, table)} 
        WHERE entity_key IN ({','.join('?' * len(serialized_keys))})
        ORDER BY entity_key
    """, serialized_keys)
    
    # 内存中分组处理
    rows = cur.fetchall()
    grouped_rows = {k: list(g) for k, g in itertools.groupby(rows, key=lambda r: r[0])}
    
    for entity_key in entity_keys:
        key_bin = serialize_entity_key(entity_key, config.entity_key_serialization_version)
        features = {}
        timestamp = None
        for _, feature

【免费下载链接】feast Feature Store for Machine Learning 【免费下载链接】feast 项目地址: https://gitcode.com/GitHub_Trending/fe/feast

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

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值