对于部署在生产环境中的机器学习模型,特别是那些提供实时预测的模型,特征的检索速度往往是一个主要的性能指标。在线特征存储专门设计来满足这些严苛的低延迟要求。其架构必须优先考虑最小化特征检索时间,通常表示为 $T_{retrieval}$,确保推理服务能在数毫秒内获得所需的特征值,以进行及时预测。构建高性能在线存储所用的架构选择和模式将得到讨论。底层数据库技术的选择是在线存储的基本决定。主要的访问模式是根据一个或多个实体ID(例如用户ID、产品ID)获取特征向量。这种模式非常适合那些为快速点查询优化的数据库系统。键值存储键值存储因其固有的基于主键快速数据检索设计,常是在线特征存储的首选。例子: Redis、Memcached、Amazon DynamoDB、Google Cloud Datastore/Firestore(原生模式)、Azure Cosmos DB(使用键值API或SQL API进行点读取)、Cassandra(主要用于键查找时)。优点:低延迟: 对于基于主键的简单GET操作,通常提供个位数毫秒延迟。Redis或Memcached等内存版本可以达到亚毫秒级延迟。可扩展性: 设计用于通过在多个节点间分布数据来水平扩展。简洁API: 直接的PUT和GET操作非常适合特征存储和获取。考量:数据建模: 特定实体的特征通常存储在单个键下,可能作为序列化对象(例如JSON、Protobuf)或存储支持的结构化格式(如Redis哈希)。需要仔细的模式设计来平衡检索效率和存储开销。查询灵活性: 主键查询能力有限。根据值检索特征或进行复杂过滤通常效率低下或不被支持。一致性: 许多分布式键值存储提供最终一致性,这提高了可用性和性能,但需要理解其对特征新鲜度的影响。强一致性读取通常可行,但可能带来延迟代价。内存数据库与缓存对于要求绝对最低延迟的应用,内存数据库或专用缓存层是不可或缺的。例子: Redis、Memcached、Hazelcast。优点:极速: 数据直接存储在RAM中,消除了磁盘I/O瓶颈,提供最快的访问时间。吞吐量: 可以处理非常高的读取速率。考量:成本: RAM明显比磁盘存储更昂贵。容量: 受服务器节点可用内存的限制。持久性: 需要配置以保证持久性(例如Redis快照或AOF日志)。纯缓存(如Memcached)可能不提供持久性保证。通常用作更持久、可能更慢的键值或其他数据库前的缓存层。digraph G { rankdir=LR; node [shape=box, style=rounded, fontname="Arial", fontsize=10, margin="0.15,0.05"]; edge [fontname="Arial", fontsize=9]; subgraph cluster_service { label = "推理服务"; style=filled; color="#e9ecef"; Inference [label="预测请求\n(实体ID)"]; } subgraph cluster_fs_online { label = "在线特征存储"; style=filled; color="#dee2e6"; Cache [label="内存缓存\n(例如 Redis)", shape=cylinder, style=filled, fillcolor="#a5d8ff"]; PersistentStore [label="持久化键值存储\n(例如 DynamoDB, Cassandra)", shape=cylinder, style=filled, fillcolor="#bac8ff"]; Cache -> PersistentStore [label="缓存未命中 / 直写"]; } Inference -> Cache [label="1. 请求特征 (实体ID)"]; Cache -> Inference [label="2. 返回特征 (缓存命中)"]; PersistentStore -> Cache [label="3. 获取并缓存"]; Cache -> Inference [label="4. 返回特征 (缓存未命中)"]; }一个常见模式涉及推理服务首先查询快速内存缓存。缓存未命中时,请求会回退到持久化键值存储,结果会回填到缓存中供后续请求使用。其他数据库考量虽然键值存储和内存存储很常见,但在特定情况下可能需要考虑其他数据库类型,尽管这通常会伴随延迟权衡:文档数据库(例如MongoDB): 如果特征具有复杂嵌套结构并能自然映射到文档,则可能可行。但是,点查询可能不如专门的键值存储优化。性能很大程度上取决于索引和数据建模。关系型数据库(例如PostgreSQL、MySQL): 通常不是规模化P99低延迟要求的首选,因为锁、事务管理和连接可能带来开销。对于小规模部署、内部工具,或者如果特征已在现有高度优化的关系型系统中管理,并且通常与激进缓存结合使用,则可能可以接受。提升速度的架构模式有几种架构模式有助于实现低延迟服务:激进缓存: 实现缓存层(如图中所示)很重要。这可以是一个独立的系统(Redis/Memcached),也可以是所选数据库的内置缓存功能(如DynamoDB Accelerator - DAX)。缓存命中率是一个重要的监测指标。缓存失效策略(例如,存活时间(TTL)、直写)是影响数据新鲜度和复杂性的重要设计决策。优化数据建模: 经常采用反范式化。特征管道预计算并将特征向量存储在为即时检索优化的结构中,而不是在读取时进行数据连接。这可能涉及存储冗余数据,但避免在推理过程中进行昂贵的计算。模式应针对读取性能进行定制。高效序列化: 用于存储和传输特征数据的格式会影响延迟。二进制格式(如Protocol Buffers(Protobuf)或MessagePack)通常比基于文本的格式(如JSON)提供更低的序列化/反序列化开销,特别是对于大型特征向量。邻近部署: 网络延迟是一个物理限制。将在线存储实例部署在同一区域、可用区,甚至与推理服务共同部署,可以最大程度地减少网络跳数和往返时间。连接池: 推理服务应使用连接池维护到在线存储的持久连接。为每个请求建立新连接会增加显著的延迟开销。异步操作: 在可行的情况下,在推理服务中使用非阻塞I/O允许它在等待特征时处理其他任务,从而提高整体吞吐量,尽管它本身并不能减少单个特征查询的延迟。{"layout": {"title": "在线存储延迟 (P99)", "xaxis": {"title": "数据库类型"}, "yaxis": {"title": "P99延迟 (ms)", "range": [0, 50]}, "font": {"family": "Arial", "size": 10}, "margin": {"l": 50, "r": 20, "t": 40, "b": 40}, "plot_bgcolor": "#f8f9fa", "paper_bgcolor": "#ffffff"}, "data": [{"type": "bar", "x": ["内存键值存储 (Redis)", "持久化键值存储 (DynamoDB)", "文档数据库 (Mongo)", "关系型数据库 (Postgres)"], "y": [1, 8, 15, 35], "marker": {"color": ["#1c7ed6", "#4263eb", "#7950f2", "#ae3ec9"]}}]}用作在线特征存储的不同数据库类别的典型P99读取延迟的示例性比较。实际性能很大程度上取决于工作负载、模式、硬件、网络和配置。最终,设计在线存储需要仔细权衡。虽然键值存储和内存数据库提供了低 $T_{retrieval}$ 所需的原始速度,但数据量、更新频率、一致性要求、操作复杂性和成本等因素都必须纳入最终的架构决策中。使用真实工作负载对不同方法进行基准测试对于根据机器学习应用的特定需求验证性能是必要的。