这是使用 Apache Cassandra 作为实时特征存储的实用指南。我们探索了实时 AI 以及 Cassandra 独特的性能和成本属性,这些属性使其成为功能存储的优秀数据库,然后深入了解功能存储的基础知识及其在实时应用程序中的作用。 Cassandra 被大公司用作特征存储,包括
该指南分为几个关键部分。我们首先介绍 Cassandra 及其功能,这些功能使其成为功能存储的理想选择。然后,我们解释了特征存储的基础知识,包括它们是什么以及如何在实时应用程序中使用它们。之后,我们将探讨使用 Cassandra 创建特征存储的实现细节。这包括数据建模、特征的摄取和检索,以及处理数据更新。最后,我们提供了使用 Cassandra 作为特征存储的最佳实践和技巧,以确保最佳性能和可扩展性——从延迟要求到估计的性能指标要求,再到参考架构和生态系统兼容性。
本指南不讨论
实时人工智能根据最近发生的事件进行推理或训练模型。传统上,训练模型和基于模型的推论(预测)是分批进行的——通常是在夜间或一天中定期进行。如今,现代机器学习系统对最新数据进行推理,以提供最准确的预测。 TikTok 和谷歌等一小部分公司通过在新数据进入时对模型进行即时训练,进一步推动了实时范式。
由于推理的这些变化和模型训练可能发生的变化,特征数据的持久性——用于训练和执行 ML 模型推理的数据——也需要适应。阅读本指南后,您将更清楚地了解 Cassandra 和基于 Cassandra 构建的托管服务 DataStax Astra DB 如何满足实时 AI 需求,以及它们如何与其他数据库技术结合使用用于模型推理和训练。
特征存储是特定于机器学习 (ML) 的数据系统,它:
实时 AI 对 Cassandra 具有独特资格满足的特征存储提出了特定要求,特别是在模型服务和模型训练的特征存储和服务方面。
**为功能服务实施低延迟查询
对于实时推理,需要将特征返回到具有低延迟的大规模应用程序。典型模型涉及分布在约 10 个实体中的约 200 个特征。实时推理需要为收集特征、轻量级数据转换和执行推理编制时间预算。根据以下调查(我们与从业者的对话也证实了这一点),特征存储需要在 50 毫秒内将特征返回到执行推理的应用程序。
通常,模型需要跨多个逻辑实体的“内部连接”——组合来自多个表的行值,这些表共享一个公共值;这对低延迟功能服务提出了重大挑战。以预测送餐时间的 Uber Eats 为例。数据需要加入订单信息,加入餐厅信息,再加入餐厅所在区域的交通信息。在这种情况下,需要两个内部联接(参见下图)。
要在 Cassandra 中实现内部连接,可以在插入时对数据进行非规范化,或者对 Cassandra 进行两次顺序查询 + 在客户端执行连接。尽管通过非规范化将数据插入数据库时可以执行所有内部联接,但模型和表之间的比例为 1:1 是不切实际的,因为这意味着要维护过多数量的非规范化表。最佳实践表明,特征存储需要允许 1-2 个内部连接顺序查询,并结合非规范化。
以下是可用于估计实时 ML 管道要求的性能指标的摘要:
测试条件:
特征 = 200
表数(实体)= 3
内部联接数 = 2
查询 TPS:5000 次查询/秒
写TPS:500条记录/秒
集群大小:AstraDB 上的 3 个节点*
延迟性能总结(这里的不确定性是标准偏差):
tp95 = 13.2(+/-0.6) 毫秒
tp99 = 23.0(+/-3.5) 毫秒
tp99.9 = 63(+/- 5) 毫秒
压实效果:
变更数据捕获 (CDC) 的影响:
tp50, tp95 ~ 3-5 毫秒
tp99 ~ 3 毫秒
tp999 ~ 可以忽略不计
*以下测试是在 DataStax 的Astra DB 的免费层上完成的,这是 Cassandra 的无服务器环境。当使用以下推荐设置在三个音符上部署时,用户应该期望类似的延迟性能。
对延迟最显着的影响是内部连接的数量。如果只查询一张表而不是三张表,tp99下降58%;对于两张桌子,它减少了 29%。 tp95 分别下降了 56% 和 21%。因为 Cassandra 是水平可扩展的,所以查询更多功能也不会显着增加平均延迟。
最后,如果开箱即用无法满足延迟要求,Cassandra 还有两个附加功能:由于高写入吞吐量能力而支持非规范化数据的能力(从而减少内部连接)以及选择性地将数据复制到内部的能力。通过更改数据捕获的内存缓存(例如 Redis)。您可以在此处找到更多减少延迟的技巧。
为特征转换实现容错和低延迟写入
实时 AI 的一个关键组成部分是能够使用最新数据进行模型推理,因此尽快提供新数据以进行推理非常重要。同时,对于企业用例,写入的持久性很重要,因为数据丢失会导致重大的生产挑战。
*对象存储(例如 S3 或 HIVE)可以替换为其他类型的面向批处理的系统,例如数据仓库。
低延迟持久写入和低延迟功能服务之间存在权衡。例如,可以仅将数据存储在非持久位置(例如 Redis),但生产故障可能会导致难以恢复最新功能,因为这需要从原始事件中进行大量重新计算.
一种常见的架构建议将特性写入离线存储(例如,Hive/S3)并将特性复制到在线存储(例如,内存缓存)。尽管这为特征服务提供了持久性和低延迟,但它是以引入特征写入延迟为代价的,这总是会导致较差的预测性能。
Cassandra 在低延迟功能服务和低延迟“持久”功能写入之间提供了一个很好的权衡。写入 Cassandra 的数据通常至少复制了 3 次,并且它支持多区域复制。从写入到读取可用性的延迟通常为亚毫秒。因此,通过将特征直接保存到在线商店 (Cassandra) 并绕过离线商店,应用程序可以更快地访问最近的数据以做出更准确的预测。同时,CDC从线上商城到线下商城,可以利用现有工具进行批量训练或数据探索。
为预测缓存和性能监控实施低延迟和写入
除了存储特征变换外,还需要存储预测和其他跟踪数据以用于性能监控。
有几个用于存储预测的用例:
Cassandra 是两种用例的合适存储,因为它具有高写入吞吐量功能。
规划弹性读写工作负载
每秒查询和写入事务的级别通常取决于同时使用系统的用户数量。因此,工作负载可能会根据一天中的时间或一年中的时间发生变化。能够快速扩大和缩小集群以支持增加的工作负载非常重要。 Cassandra 和 Astra DB 具有支持动态集群扩展的功能。
可能影响写入工作负载的第二个方面是特征转换逻辑是否发生变化。随着写入工作负载的大幅增加,Cassandra 会自动优先维护低延迟查询和写入 TPS,而不是数据一致性,这对于执行实时推理来说通常是可以接受的。
实施低延迟、多区域支持
随着实时 AI 在所有应用程序中变得无处不在,确保特征数据在尽可能靠近推理发生的地方可用非常重要。这意味着将特征存储在与进行推理的应用程序相同的区域中。跨区域复制特征存储中的数据有助于确保该特征。此外,仅复制特征而不是用于生成特征的原始数据可以显着降低云出口费用。
Astra DB 支持开箱即用的多区域复制,复制延迟以毫秒为单位。我们的建议是将所有原始事件数据流式传输到单个区域,执行特征生成,并将特征存储和复制到所有其他区域。
尽管从理论上讲,可以通过在每个区域生成特征来获得一些延迟优势,但事件数据通常需要与来自其他区域的原始事件数据相结合;从正确性和效率的角度来看,将所有事件发送到一个区域以处理大多数用例会更容易。另一方面,如果模型使用在区域上下文中最有意义,并且大多数事件都与区域特定实体相关联,那么将特征视为区域特定是有意义的。任何确实需要跨区域复制的事件都可以放置在具有全局复制策略的键空间中,但理想情况下,这应该是事件的一小部分。在某个时候,全局复制事件表的效率将低于简单地将所有事件发送到单个区域以进行特征计算。
规划具有成本效益和低延迟的多云支持
多云支持提高了应用程序的弹性,并允许客户协商更低的价格。诸如 DynamoDB 之类的单一云在线商店不仅会增加检索功能的延迟和显着的数据出口成本,还会导致对单一云供应商的锁定。
支持跨云复制的开源数据库提供了性能成本的最佳平衡。为了最小化出口成本,事件和特征生成应该整合到一个云中,特征数据应该复制到跨其他云的开源数据库中。这最大限度地减少了出口成本。
规划生产模型的批量和实时培训
用于构建模型的批处理基础设施用于两个用例:构建和测试新模型,以及构建生产模型。因此,为了训练的目的,将特征数据存储在较慢的对象存储中通常就足够了。然而,较新的模型训练范例包括实时或近实时更新模型(实时训练);这被称为“在线学习”(例如TikTok 的 Monolith )。实时训练的访问模式介于推理和传统批量训练之间。吞吐量数据要求高于推理(因为它通常不会访问单行查找),但不如涉及全表扫描的批处理高。
Cassandra 可以支持每秒数十万的 TPS 等级(使用适当的数据模型),这可以为大多数实时训练用例提供足够的吞吐量。但是,如果用户希望从对象存储中保留实时训练,Cassandra 可以通过 CDC 到对象存储来实现这一点。对于批量训练,CDC 应该将数据复制到对象存储。值得注意的是,像Tensorflow和 PyTorch 这样的机器学习框架特别针对对象存储中 ML 模型的并行训练进行了优化。
有关“在线学习”的更详细解释,请参阅 Chip Huyuen 对持续学习的解释,或Gomes 等人的这篇技术论文。铝。
支持 Kappa 架构
由于在线/离线倾斜导致的成本和数据质量问题, Kappa 架构正在逐渐取代 Lambda 架构。尽管许多文章讨论了从单独的批处理和实时计算层迁移到单个实时层的优势,但文章并不经常描述如何构建服务层。
使用 Kappa 架构生成特征带来了一些新的考虑:
Cassandra 通过以下方式支持 Kappa 架构:
支持 Lambda 架构
大多数公司都有一个 Lambda 架构,带有一个与实时管道分开的批处理层管道。此场景中有几类功能:
然而,在这种情况下,DataStax 推荐如下图所示的架构:
原因如下:
如果无法更新现有管道,或者有特定原因需要先将特征存储在对象存储中,我们的建议是在 Cassandra 特征存储和对象存储之间使用双向 CDC 路径,因为如下图所示。
确保与现有机器学习软件生态系统的兼容性
要将 Cassandra 用作特征存储,它应该与生态系统的两个部分集成:执行推理和训练的机器学习库,以及执行特征转换的数据处理库。
两个最流行的机器学习框架是 TensorFlow 和 PyTorch。 Cassandra 具有 Python 驱动程序,可以轻松地从 Cassandra 数据库中检索功能;换句话说,可以并行获取多个功能(请参阅此示例代码)。执行特征转换的两个最流行的框架是 Flink 和Spark Structured Streaming 。 Flink和Spark的连接器可用于 Cassandra。从业者可以使用Flink和Spark Structured Streaming以及 Cassandra 的教程。
FEAST 等开源功能商店也有用于 Cassandra 的连接器和教程。
了解查询模式和吞吐量以确定成本
作为特征存储的 Cassandra 的读取查询数量取决于传入推理请求的数量。假设特征数据分布在多个表中,或者如果数据可以并行加载,这应该给出可以进行的实时推理之间的扇出估计。例如,10 个单独表中 10 个实体的 200 个特征在实时推理和 Cassandra 查询之间的比例约为 1:10。
计算正在执行的推理数量将取决于推理流量模式。例如,在“流式推理”的情况下,每当相关特征发生变化时就会进行推理,因此推理的总数取决于特征数据变化的频率。当在“请求-回复”设置中执行推理时,它仅在用户请求时执行。
了解批处理和实时写入模式以确定成本
写入吞吐量主要取决于功能更改的频率。如果发生反规范化,这也可能会影响写入的功能数量。其他写入吞吐量注意事项包括针对批处理或流式推理场景的缓存推理。
在设计实时 ML 管道时,需要特别注意特征存储的性能和可扩展性。 NoSQL 数据库(如 Cassandra)特别好地满足了这些要求。使用 Cassandra 或AstraDB建立您自己的特征存储,并使用Cassandra 连接器试用Feast.dev 。