特征存储架构及如何构建
个性化存储架构与构建方法

随着机器学习在业务运营中的日益重要,ML平台团队的角色日益突出。这些团队的任务是开发或选择必不可少的工具,使机器学习能够从实验转向实际应用。其中一个不可或缺的工具就是特征存储。如果你在处理ML模型的数据管道复杂性方面感到困惑,特征存储可能是你寻找的解决方案。在本文中,我们旨在逐层提供一个全面的特征存储理解和实施指南。我们的目标是帮助你明智地决定特征存储是否符合你的需求。
特征存储架构?为什么优先于如何
让我们真实一些。你不是为了好玩而建立特征存储;你建立它是因为你存在需要解决的实际挑战。那么你首先考虑特征存储的驱动是什么呢?这里有一些我们听到的最有说服力的原因:
实时特征服务 – 你的机器学习模型需要具有低延迟和可扩展性的特征。这不仅仅是一种美好的愿望;它对于运营效率至关重要。
标准化 – 你厌倦了对特征管道的无规律性处理。你想要一种标准化的方式来构建、存储和管理所有机器学习项目的特征。
统一的数据管道 – 维护训练和服务的分开管道的时代已经过去了。你正在寻找一种统一的方法来减少训练/服务的偏差,并使你的生活更轻松。
特征可重用性和效率 – 集中的特征存储不仅使在项目之间共享特征更容易,还增强了可发现性、准确性和成本效益。通过拥有一个特征的单一真实源,你避免了冗余计算和模型中不一致的使用。
如果你对其中任何一点产生共鸣,那么你来对了地方。特征存储直接解决了这些挑战,提供了一种结构化、可扩展的方法来管理你的特征,从数据摄取到服务。最好的部分是什么呢?它不是一种一刀切的解决方案;它是一个可以根据你的特定需求和限制进行定制的框架。
所以,你首先考虑建立特征存储的驱动是什么?
特征存储 vs. 数据存储 vs. ETL 管道:理解细微差别
在你探索机器学习数据管理领域时,你会遇到几个关键组件,每个组件都有其自身的能力和限制。虽然特征存储是本指南的焦点,但理解它们与传统数据存储和ETL(抽取、转换、加载)管道的区别至关重要。这不仅能帮助你做出明智的决策,还能让你无缝地整合这些组件。
特征存储的角色
特征存储不仅仅是机器学习特征的专用存储库,它是整个特征工程生命周期中不可或缺的一部分。虽然我们将在接下来的几节中深入研究其架构,但重要的是要理解特征存储不仅仅是一种数据存储解决方案。它为特征的创建、版本控制和实时/批处理服务提供了全面的框架。为了更深入地了解特征是什么以及它们在机器学习中为什么至关重要,你可以阅读我们的什么是特征存储文章。
传统数据存储
相比之下,传统的数据存储,如数据库或数据湖,更具通用性。它们非常适合存储原始或处理过的数据,但缺乏特征工程和实时服务的专业能力,这是特征存储所提供的。例如,它们不会固有地支持特征的版本控制或具有低延迟的实时服务。虽然你可以在传统数据存储之上构建这些能力,但这将需要大量的工程工作,而特征存储已经为你处理了。
ETL 管道
另一方面,ETL管道是数据转换的工作马。它们负责从各种来源提取数据,将其转换为可用的格式,并加载到数据存储中。虽然ETL管道对于数据准备非常重要,但它们并不设计用于管理机器学习的特征工程的复杂性。它们更像是一条单向街道,将数据从A点到B点,而不具备特征存储所提供的细致管理和服务能力。
相互作用
了解这些区别并不意味着要在它们之间进行选择;而是要充分利用每个组件的最佳功能。您可以使用ETL流水线来准备原始数据并将其加载到传统数据存储中进行初始存储。然后,特征库可以接管,摄取这些数据,将其转化为有价值的特征,并将其提供给机器学习模型。通过这种方式,ETL流水线、传统数据存储和特征库可以在您的数据生态系统中发挥和谐的作用。
在接下来的部分中,我们将全面探讨构成特征库的架构组件,使其不仅仅成为一个数据存储库。我们将探索它如何作为一个强大的特征工程、管理和实时服务的框架,同时确保可扩展性和可靠性。
特征库架构:构建自己的实用指南
在我们卷起袖子,深入了解特征库的要素之前,让我们退一步。想象一下您正在查看一份蓝图;当您知道每个房间应该放在什么位置时,建造房子就会更容易,对吗?同样的道理适用于这里。特征库设计基本上分为三个核心层,每个层都有自己的组件和职责:
数据基础架构层
将其视为基础。它是原始数据的摄取、处理和存储的地方。这一层是其他所有内容构建的基石。关键组件包括批处理和流处理引擎,以及脱机和在线存储。
服务层
这是您的前门,已处理特征可以通过它访问应用程序和服务。它经过优化以提高速度,并且设计用于扩展。在这里,您将找到为您提供特征的RESTful API或gRPC服务。
应用层
最后,将其视为您的控制室。它是确保其他所有层和组件协同工作的协调器。从作业编排到特征跟踪和系统健康监控,该层确保一切顺利运行。
理解这个特征库架构至关重要,因为它将影响您做出的每一个决策,从您选择的工具到您建立的工作流程。因此,在我们深入研究每个层及其组件之前,请牢记这个蓝图。相信我们,这将使前方的旅程变得更加简单。

数据基础架构层:一切的起点
数据基础架构层是特征库的支柱。它负责数据流水线的初始阶段,包括数据摄取、处理和存储。这一层为接下来的更专门操作奠定了基础,使其对整个系统的可扩展性和可靠性至关重要。

批处理引擎
批处理引擎充当了原始数据转化为特征的计算中心。它的设计目的是处理不需要实时处理的大型数据集,并为它们在离线特征存储中做准备。
注意事项
- 数据一致性 – 保持特征生成在不同运行中的一致性,对于维护机器学习模型的完整性至关重要。
- 版本管理 – 跟踪特征的不同版本。如果特征被更新或废弃,应该做好记录。
- 并发处理 – 规划多个批处理作业同时运行,以确保它们在特征存储中不会发生冲突。
与SDK概念的相关性
- 数据源 – 引擎是从各种SDK定义的数据源(如SQL数据库、平面文件或外部API)摄取原始数据的地方。在设计SDK时,考虑这些数据源的延迟和吞吐量要求。
- 特征转化 – 引擎执行SDK定义的特征转化。根据机器学习模型的类型,不同的转化可能更合适。例如,对于分类模型,可以考虑标签编码,而对于回归模型,多项式特征可能更有用。
最佳实践
- 批次大小 – 选择优化计算速度和系统负载的批次大小。对于时间序列数据,可以选择每天或每小时的批次。
- 特征验证 – 实施检查,确保计算出的特征符合质量和一致性标准,就像食物离开厨房前的质量检查一样。
- 依赖管理 – 管理特征计算的顺序,特别是如果一个特征依赖于另一个特征,就像食谱中的步骤一样。
重点选择
- Apache Spark – Spark提供了一个高度可扩展和容错的分布式计算环境。它支持各种数据源和格式,使其适用于各种特征工程任务。它对机器学习库的本地支持也使其成为特征计算和特征存储的强大选择。
流处理引擎
流处理引擎就像您的数据基础设施的“快餐柜台”,专门处理实时数据处理需求。它在数据到达时进行处理,非常适用于需要实时分析和监控的应用程序。
注意事项
- 延迟 – 与批处理不同,这里延迟是一个关键因素。系统应能够以最小的延迟处理数据。
- 可扩展性 – 因为数据流可能非常变化,系统应能够快速进行扩展或收缩。
- 数据完整性和修复 – 错误是难免的,有时会传输错误的数据。您的引擎不仅应处理无序或迟到的数据,还应能够通过实时或后续批次重新计算来纠正这些错误。
与SDK概念的相关性
- 数据源 – 这个引擎通常处理SDK中定义的实时数据源,如Kafka流、物联网传感器或实时API。
- 特征转化 – 可以在这里执行特定于流的转化,如窗口聚合或实时异常检测。例如,如果您正在开发一个欺诈检测系统,实时转化可以标记异常的交易模式。
最佳实践
- 状态管理 – 跟踪数据流的状态,特别是如果您的特征需要来自多个流的数据或具有时间依赖性。
- 容错性 – 实施从故障中恢复的机制,确保不丢失数据,处理可以平稳地继续。
- 自适应扩展 – 不要强加速率限制,而是着眼于构建一个根据传入数据流的需求进行扩展的系统。
重点选择
- Apache Spark Structured Streaming – 我们推荐使用Apache Spark Structured Streaming,因为它具有容错性、易用性以及与Spark SQL引擎的本地集成。它允许执行复杂的事件时间窗口操作,并支持各种来源和接收器,使其在实时分析和特征计算中变得多才多艺。它与更广泛的Spark生态系统和DataFrame API的兼容性使其成为批处理和实时数据处理的强大选择。成熟的生态系统、广泛的社区和商业支持进一步巩固了它作为结构化流式处理任务首选的地位。
实体店
实体店充当您的“数据仓库”,是一个安全有组织的地方,将经过批处理或流引擎处理后的特征数据存储起来。它被设计用于处理大量的数据,并且针对批量分析进行了优化。
考虑事项
- 数据保留 – 考虑存储成本和数据实用性,决定数据的存储时间。
- 可访问性 – 确保数据易于访问,用于批量分析,并保证安全性。
- 数据模型 – 维护一致的数据模型,以确保数据易于解释和使用。
与SDK概念的关系
- 特征集 – 特征集是共享共同概念或关系的特征组。它们在SDK中定义并存储在这里。这些特征可以是简单的数值特征,也可以是经过预处理的文本或图像等更复杂类型。例如,如果您正在构建一个推荐引擎,您的特征集可能包括用户行为指标,例如点击率、页面停留时间和购买历史。这些特征是相关的,因为它们都有助于了解用户偏好。
- 特征检索 – 这是批量检索特征的主要方法,通常用于训练机器学习模型。它支持时光旅行,允许您查询特定时间点的特征,这对于调试或审计非常有用。
最佳实践
- ACID事务 – 实现ACID(原子性、一致性、隔离性、持久性)事务,以确保数据完整性。
- 索引 – 使用索引加速数据检索,特别是对于大型数据集。
- 数据验证 – 在存储之前,验证数据以确保其符合质量和一致性要求。
突出选择
- 带有Delta或Iceberg文件的S3 – 将其视为高安全性的恒温仓库。这些文件格式提供ACID事务、可扩展的元数据处理,并统一了流处理和批处理数据,使其成为实体店的坚固选择。
在线商店
在线商店类似于您的“零售店”,专为对特征数据进行低延迟访问而设计。它经过优化,以便快速读取,并且是实时应用程序的首选地。
考虑事项
- 延迟 – 低延迟在这里非常重要;数据应在毫秒级别可检索。
- 高可用性 – 商店应具备高可用性,以满足实时应用程序的需求。
- 可扩展性 – 随着特征数量或请求率的增加,系统应无缝扩展。
与SDK概念的关系
- 特征检索 – 这是实时特征检索的主要来源,通常用于生产中的机器学习模型服务。
- 按需特征计算 – 如果SDK支持,一些轻量级的特征计算也可以在这里实时进行。
最佳实践
- 数据分区 – 使用分区策略将数据分布在多个服务器上,以获得更好的性能。
- 缓存 – 实现缓存机制以加速频繁的数据检索。
- 一致性 – 在线商店和实体店之间保持数据一致性非常重要,尤其是如果两个存储同时更新。事务完整性和恢复是关键。例如,如果数据成功写入实体店,但未能写入在线商店,则需要一个强大的机制来处理此类差异,并进行优雅的恢复。
突出选择
- Redis缓存 – Redis是一个开源的内存数据结构存储库,提供超快的读写操作。其低延迟和高吞吐能力使其成为实时机器学习应用程序中提供特征的优秀选择。Redis提供各种数据结构和原子操作,可以灵活设计满足特定需求的高效特征存储。
服务层:基于API的特征访问
服务层是您的“客户服务台”,外部应用程序和服务在此请求和接收特征数据的接口。它经过优化,以确保高可用性和低延迟,以便快速可靠地提供特征。

注意事项
- API设计 – API应该设计成易于使用,包括清晰的文档和版本控制。
- 负载均衡 – 将传入请求分配到多个服务器上,以确保高可用性和低延迟。
- 安全性 – 实现认证和授权机制,控制对功能数据的访问。
与SDK概念的相关性
- 特征检索 – 此层负责向外部应用程序提供特征,通常通过SDK中定义的RESTful API或gRPC服务提供。
- 即时计算 – 除了提供预计算的特征外,此层还可以根据SDK的功能进行实时轻量级计算。例如,如果您为推荐引擎提供特征,则可能需要根据实时用户交互计算项目的“热度评分”。该评分可以在服务层动态计算,然后发送给应用程序。
最佳实践
- 限流 – 实施限流以防止滥用并确保公平使用。
- 监控 – 跟踪API使用情况、错误和延迟,以进行持续优化。
- 缓存 – 使用缓存机制加速频繁数据检索,就像一个井然有序的客户服务台能够快速为客户检索常见表单或信息一样。
突出的选择
- Kubernetes – 对于强大的服务层,我们建议使用您选择的托管服务提供商的Kubernetes集群。结合使用Prometheus实时监控系统指标和Kafka有效限流。当您有大量传入请求时,这些服务可以对其进行排队,并以受控速率馈送到服务层。这有助于防止系统过载,并确保资源的最佳使用。限流尤其重要,以防止滥用并确保资源的公平使用。
应用层:控制塔
应用层作为特征存储的协调器。它管理数据管道、跟踪特征及其元数据,并监控系统的健康状况。该层确保特征存储的所有组件协调工作,对系统的整体性能和可靠性至关重要。

作业调度器
作业调度器是“乐队指挥家”,协调各种组件的协同工作。它协调您的数据管道,确保任务按照正确的顺序执行,并管理它们之间的依赖关系。
注意事项
- 工作流程设计 – 定义清晰的有向无环图(DAGs)或工作流程,概述任务的顺序和依赖关系。
与SDK概念的相关性
- 特性集 – 编排器触发在SDK中定义的特性集的计算和存储。
最佳实践
- 幂等性 – 设计任务具有幂等性,即它们可以安全重试而不会产生副作用,类似于指挥家可以重新开始一首音乐作品而不引起混乱。
- 集成监控和日志 – 将监控仪表板和作业日志部署到特性存储的用户界面中,以便快速调试而不影响访问。这可以提供作业性能和问题的集中视图,便于更快地解决问题。监控可能包括跟踪数据的“新鲜程度”,延迟和错误率。例如,如果您正在摄取实时股票价格,如果数据在过去5分钟内没有更新,您可以设置警报。
- 数据验证和报警 – 虽然很难确保计算数据的绝对正确性,但实施数据验证检查和报警机制可以有所帮助。例如,如果一个ETL作业应该聚合销售数据,销售额突然下降50%,可能会触发人工审核的警报。
重点选项
- Airflow – Airflow是一个开源平台,用于以编程方式编写、调度和监控工作流程。它丰富的功能和可扩展性使其成为编排复杂数据流程(包括MLOps中的流程)的强大选择。Airflow具有原生支持定义任务依赖关系和调度的能力,为工作流管理提供了全面解决方案。它还提供了通过Prometheus和Grafana等工具进行监控和报警的集成点,或者通过PagerDuty等报警服务。
特性注册表(元数据存储)
特性注册表充当特性存储的“图书馆目录”,维护有关每个特性的元数据、血统和其他属性的信息。它是支持元数据的CRUD操作并提供特性血统跟踪的基础。
考虑因素
- 元数据模式 – 定义清晰的元数据模式,包括特性名称、类型和血统信息。
- 可搜索性 – 确保可以根据元数据轻松搜索和检索特性。
- 版本控制 – 实施特性的版本控制,以跟踪随时间的变化。
与SDK概念的相关性
- 特性集 – 存储在SDK中定义的特性集的元数据。这包括特性类型、默认值和数据源等详细信息。
最佳实践
- 数据血统 – 记录每个特性的血统,显示其从源到服务的过程。这类似于一个图书馆目录,不仅列出书籍,还展示了它们的起源以及它们如何到达图书馆。
- 访问控制 – 实施细粒度的访问控制,限制谁可以查看或修改特性元数据。
- 审计日志 – 记录访问或修改特性的日志,类似于图书馆的借阅历史记录。
重点选项
- 带有Feast的PostgreSQL – 这个关系型数据库提供了强大的元数据存储功能。与Feast特性存储框架结合使用时,您还可以获得特性血统跟踪和与数据流水线的轻松集成等附加好处。
控制平面
控制平面是特性存储的“空中交通管制塔”,监督所有操作并确保顺利运行。它作为数据漂移监测、访问控制和其他管理功能的用户界面。
最佳实践
- 数据漂移和偏斜监测 – 实施检测数据漂移和偏斜的算法,这对于维护机器学习模型的完整性至关重要。
- 报警 – 设置用于关键事件或异常的报警机制,集成Slack Webhooks、Opsgenie等。
- 审计日志 – 记录所有操作的日志,提供清晰的更改和访问历史记录,类似于空中交通管制日志。
重点选项
- 服务层的Kubernetes – 鉴于我们推荐为服务层使用Kubernetes,因此将控制平面部署在同一集群上是合理的。这提供了一种具有协同、可扩展和具有成本效益的管理体验,并简化了架构,减少了需要管理的服务数量。
总结
建立一个特征库并非易事;这是一项复杂的工作,需要深入了解数据和可用工具。但好消息是:你并不孤单。无论是托管服务还是开源项目,都有资源可以帮助你建立特征库。关键是从一个坚实的基础开始,而这个基础是对特征库架构的理解。我们已经为你演示了数据基础设施、服务和应用层的构成,揭开了它们的神秘面纱。记住,特征库不仅仅是各个部分的总和;它是一个生态系统。而像任何生态系统一样,平衡至关重要。
因此,当你踏上这个旅程时,将目光放在地平线上,但要稳步前行。毕竟,机器学习的未来不仅仅关乎算法;它关乎特征——如何存储、管理和提供特征。这是一个值得为之努力建设的未来。
文章最初发布在Qwak,经许可后转载。





