AWS 大数据深度剖析(第 8 部分):在线特征存储 —— DynamoDB、ElastiCache 与 OpenSearch k-NN

推荐系统如何在推理时提供特征服务:用 DynamoDB 存用户特征、用 ElastiCache 做热点缓存、用 OpenSearch k-NN 做向量召回、用 Neptune 做图检索。

zhuermu··13 分钟
big-dataawsdynamodbelasticacheopensearchvector-searchfeature-storeonline-serving

为什么需要在线服务层?

一个推荐请求必须在 200ms 内返回。你不可能在这样的延迟下去查询数据仓库或数据湖 —— 你需要一个专门的在线服务层

本章将介绍四种在线存储系统 —— DynamoDB、ElastiCache(Redis)、OpenSearch k-NN 和 Neptune,说明各自最擅长什么,以及如何在它们之间做选择。


整体职责划分

在线存储

一个推荐请求(GET /feed?user_id=123)可能会查询四种不同的在线存储:

Recommendation Service (200ms budget)

  ├─[10ms]── DynamoDB    : Fetch user features + recall pool cache
  ├─[2ms]─── Redis       : Fetch real-time behavior sequence + last recommendation cache
  ├─[20ms]── OpenSearch k-NN: User vector → ANN find items
  └─[50ms]── Neptune     : Second-degree friends / graph recall (on demand)


SageMaker Endpoint (ranking model scoring, 30ms)


Return Top 10

关键洞察:每种存储都有自己的“主场” —— 避免混淆职责。


Amazon DynamoDB

它是什么

AWS 托管的 KV / 文档数据库。最重要的几个特性:

  • 毫秒级读写(P99 低于 10ms)
  • 自动扩缩容至数十万 QPS
  • 完全 Serverless(按读/写单元和存储计费)
  • 无固定 Schema(每一行可以有不同的字段)

数据模型

Table: user_features
  Partition Key: user_id (String)
  Sort Key: <optional>

Item:
{
  "user_id": "12345",
  "age": 25,
  "city": "Shanghai",
  "tags": ["food", "travel"],
  "last_5_clicks": ["v_001", "v_002", ...],
  "ctr_7d": 0.054,
  ...
}

每一行称为一个 Item,单个 Item 的最大尺寸为 400 KB。

计费模型

两种容量模式:

模式计费方式适用场景
On-Demand(按需)$0.25 每百万 RRU(读请求单元);$1.25 每百万 WRU(写请求单元)不可预测或突发流量
Provisioned(预置)按预留的 RCU / WCU 计费,支持 Auto Scaling稳定流量,最高可便宜 70%

RRU / WRU 计费细节(常见坑)

  • 1 RRU = 一次强一致性读,最多 4 KB;最终一致性读 = 0.5 RRU(每 4 KB)
  • 1 WRU = 一次写入,最多 1 KB
  • 大对象会向上取整(读 4 KB,写 1 KB):读取一个 5 KB 的对象 = 2 RRU
  • 事务性读/写费用翻倍

在估算时,首先要确定你需要强一致性还是最终一致性 —— 仅这一点就能让成本相差 2 倍。对于推荐特征查询,最终一致性通常就足够了,因此按每次读取 0.5 RRU 来估算。

在客户场景中的三种角色

#用途Schema数据来源
1用户特征(user_features)user_id 映射到 100+ 个特征维度数据仓库 ads_user_features 每日同步 + Flink 实时更新
2召回池(recall_u2u_cf)user_id 映射到 top-K 候选列表数据仓库 ads_recall_*_pool 每日或每小时同步
3实时行为序列(user_realtime)user_id 映射到最近 N 次点击Flink 实时维护(消费自 MSK)

建模最佳实践

DynamoDB 不是 MySQL —— 它无法做 JOIN 或 GROUP BY。建模时:

  1. 围绕访问模式设计:先想清楚“我每次会怎么查这份数据?”,再据此设置 PK / SK
  2. 热点分区是一大陷阱:避免任何单个 key 承接远超平均水平的 QPS(例如某个“news”分区承接了所有查询)
  3. 单表设计(Single-Table Design)(进阶):将多个相关实体放在一张表中,通过不同的排序键加以区分

局限性

  • 单个 Item 限制为 400 KB(大对象必须拆分或存到 S3)
  • 不适合复杂查询(聚合、范围扫描代价高昂)
  • 不支持全文搜索或向量搜索 —— 那是 OpenSearch 的活儿

官方文档


ElastiCache (Redis)

它是什么

AWS 托管的 Redis 服务(也支持 Memcached,但生产环境几乎都用 Redis)。

关键特性:

  • 亚毫秒级延迟(通常低于 1ms)
  • 丰富的数据结构:String / List / Hash / Set / Sorted Set / Stream
  • 弱持久化(数据默认存放在内存中;AOF / RDB 持久化会带来开销)

在客户场景中的角色

用途说明
推荐结果缓存同一用户 5 分钟内再次访问 —— 直接返回缓存结果
行为序列(短期)List 数据结构天然适合维护“最近 N 次点击”
限流 / 频控计数器、滑动窗口
会话存储用户当前会话的临时上下文

ElastiCache 与 DynamoDB 对比

DynamoDBElastiCache (Redis)
延迟5-10ms低于 1ms
持久化
容量几乎无限受内存限制(节点级 GB 到 TB)
复杂数据结构
成本按使用量付费按节点付费(7x24 在线)

实践中:用 DynamoDB 作为主存储,用 Redis 作为热点缓存 + 复杂数据结构(List / Sorted Set)。

部署模式

  • Cluster Mode Disabled(关闭集群模式):单主 + 多副本,简单
  • Cluster Mode Enabled(开启集群模式):分片以支撑大容量
  • Serverless(2023 年起):按使用量付费,零运维

官方文档https://docs.aws.amazon.com/elasticache/


OpenSearch k-NN(向量召回)

什么是 OpenSearch

AWS 从 Elasticsearch 分叉出来的产品(2021 年基于 ES 7.10 分叉)。它提供 ES 的全部能力:

  • 全文搜索
  • 日志聚合
  • 地理位置查询
  • 向量索引(k-NN 插件)

k-NN 用法

向量召回的核心:存储双塔模型产出的物品 embedding,然后用用户向量查询最近邻。

PUT items
{
  "settings": {
    "index": {"knn": true}
  },
  "mappings": {
    "properties": {
      "item_id": {"type": "keyword"},
      "category": {"type": "keyword"},
      "embedding": {
        "type": "knn_vector",
        "dimension": 64,
        "method": {
          "name": "hnsw",
          "engine": "lucene",
          "parameters": {"ef_construction": 256, "m": 16}
        }
      }
    }
  }
}

POST /items/_search
{
  "size": 100,
  "query": {
    "knn": {
      "embedding": {
        "vector": [0.12, -0.85, ...],
        "k": 100
      }
    }
  }
}

ANN 算法与引擎选型

OpenSearch k-NN 支持 3 种引擎(截至 2026 年):

引擎状态适用场景
Faiss生产首选大规模、需要量化(PQ/SQ)、可选 GPU 加速
Lucene稳定中小规模、纯 JVM 部署、无原生库依赖
nmslib已弃用不再推荐用于新索引

算法层:

  • HNSW:基于图的索引,兼顾延迟与召回率(首选)
  • IVF:基于聚类的倒排索引,需要训练码本,量化可节省内存
  • PQ(Product Quantization,乘积量化):将向量压缩 4 到 16 倍

对于亿级规模的向量:Faiss + HNSW,并配置合适的 ef_construction / m 参数。若为超大规模做成本优化,可再叠加 PQ 量化。

OpenSearch k-NN 与 S3 Vectors 对比

S3 Vectors(2025 年预览,2025 年下半年 GA)—— 向量索引直接存储在 S3 上,按存储 + 查询计费,Serverless。

OpenSearch k-NNS3 Vectors
延迟10-30ms频繁查询约 100ms;冷查询亚秒级(数百 ms)
成本高(节点 7x24 运行)低(按用量付费、按存储付费)
规模千万级到亿级亿级到百亿级(为超大规模设计)
多租户 / 隔离索引级Bucket / 索引原生隔离
适用场景推荐热路径(要求毫秒级延迟)RAG / 冷向量 / 长尾召回 / Bedrock Knowledge Bases 后端

官方文档写道:“对于不频繁的查询提供亚秒级延迟,对于更频繁的查询可低至 100 毫秒。”

推荐:实时召回热路径用 OpenSearch k-NNRAG / Knowledge Base / 大规模冷向量场景用 S3 Vectors。两者可以共存:热向量放在 OpenSearch,长尾向量下沉到 S3 Vectors。

部署

OpenSearch Service(托管),按节点小时计费。从 3 个 m6g.large 节点起步,大约每月 $400。

官方文档


Amazon Neptune(图数据库)

它是什么

AWS 托管的图数据库。支持三种查询语言:

  • Gremlin(属性图)
  • SPARQL(RDF 图)
  • openCypher(Neo4j 家族,2022 年起支持)

推荐场景中的图

社交类应用天然是图状结构:

(User A) -[follow]-> (User B)
(User A) -[like]-> (Post 1)
(User B) -[create]-> (Post 1)
(Post 1) -[has_tag]-> (Tag "food")

常见的图召回模式:

  • 二度好友:查询 A 的好友的好友,作为候选用户
  • 共同兴趣:A 和 B 都互动过同一批帖子 —— 强连接信号
  • 关系传播:在图上运行 PageRank / Random Walk(随机游走)

Neptune ML(GNN)

Neptune ML 是 Neptune 内置的图神经网络(GNN)训练能力:

  • 基于 DGL(Deep Graph Library)
  • 自动从图数据构建训练样本
  • 输出节点 / 边的 embedding
  • embedding 可以喂给 OpenSearch k-NN 用于召回

Neptune 成本与决策框架

Neptune 的入门成本较高:

  • db.r6g.large 实例:约每月 $330
  • 增加只读副本:约 $330 x N
  • 数据量和 I/O 也要计费

决策:图召回是一项进阶能力(可在 POC 第 3 阶段考虑)。先落地协同过滤 + 双塔模型,验证业务价值,再引入图召回。

官方文档


离线到在线的同步策略

从数据仓库 ADS 表同步到在线存储,是离线-在线协同的关键。

同步方式

方式工具适用场景
Glue Job 批量写入Spark用户特征 / 召回池的每日全量同步
EMR 批量写入Spark大数据量、复杂转换
Athena UNLOADAthena to S3 to DynamoDB Import一次性批量加载
DynamoDB S3 Import直接从 S3 文件导入初始化 / 全量数据加载
SageMaker Feature StoreSDK自动管理离线/在线一致性(见第 9 章)

同步频率

数据频率
长期用户画像每日
物品特征(热度)每小时
召回池每日或每小时
实时行为序列Flink 实时(毫秒到秒级)

一致性考量

数据仓库与在线存储无法保证强一致性 —— 这是设计上不可避免的。在做架构设计时:

  • 在线特征可容忍最多 1 天的陈旧度
  • 实时特征由 Flink 独立维护
  • 在 A/B 测试期间,通过 feature flag 控制特征版本

在线层选型决策表

需求选择
用户特征点查(KV)DynamoDB
召回池缓存(user 到 list)DynamoDB
短期推荐结果缓存Redis
行为序列(短期)Redis (List) + DynamoDB(持久化)
向量召回(亿级规模)OpenSearch k-NN
图召回 / 多跳Neptune
全文搜索OpenSearch(标准索引)
限流 / 频控Redis

客户场景:最终的在线层架构

Recommendation Service (deployed on ECS / EKS)

  ├──▶ DynamoDB (primary)
  │     ├─ user_features (synced daily from data warehouse)
  │     ├─ recall_u2u_cf (synced daily from data warehouse)
  │     └─ user_realtime (Flink writes in real time)

  ├──▶ ElastiCache Redis
  │     ├─ recommend_cache (TTL 5 min)
  │     └─ rate_limit_counter

  ├──▶ OpenSearch k-NN
  │     └─ item_embeddings (two-tower model output, rebuilt daily in batch)

  └──▶ SageMaker Endpoint
        └─ rank_model (ranking scores)

Optional Phase 3 addition:
  └──▶ Neptune
        └─ social_graph + Neptune ML embeddings

本章小结

服务角色延迟
DynamoDB用户特征 / 召回池 / 实时序列(持久化)5-10ms
ElastiCache Redis热点缓存 / 复杂数据结构 / 限流低于 1ms
OpenSearch k-NN向量召回(双塔物品 embedding)10-30ms
Neptune(+ Neptune ML)社交图 / 图召回 / GNN30-100ms

下一章:ML 平台本身 —— 如何使用 SageMaker。

参考资料

  1. Feast documentation — Feast
  2. Amazon SageMaker Feature Store — AWS Documentation