Amazon DynamoDB:全托管 NoSQL 数据库
什么是 Amazon DynamoDB?
Amazon DynamoDB 是一种完全托管的 NoSQL 数据库服务,由亚马逊云科技(AWS)提供。它专为需要极高可扩展性、一致低延迟和高吞吐量的应用程序而设计。与传统关系型数据库不同,DynamoDB 采用键值对和文档数据模型,消除了数据库管理的运维负担——无需关注服务器配置、软件修补或集群扩展,一切均由 AWS 自动处理。
作为一款无服务器(serverless)服务,DynamoDB 能够根据流量自动调整读写容量,支持按使用量付费(On-Demand)或提前预设容量(Provisioned)两种模式。它内建了强大的功能,如全局表多区域复制、时间点恢复、流处理触发器和数据加密,非常适合现代云原生应用、移动后端、游戏、物联网和微服务等场景。
核心概念详解
表、项目和属性
- 表(Table):存放数据的集合,类似关系数据库中的“表”,但不需要预先定义严格的结构。一张表可以包含任意数量的项目。
- 项目(Item):表中的一行记录,由一个或多个属性组成。每个项目必须有唯一的主键标识。
- 属性(Attribute):每个项目的数据字段,类似于列。属性可以是标量(字符串、数字、布尔、二进制)、集合(字符串集、数字集、二进制集)或复杂的嵌套文档(Map、List),最大深度为 32 层。
主键设计
主键是每个项目必须包含且不可变的部分,DynamoDB 使用主键快速检索数据。支持两种类型:
-
简单主键(分区键) 仅包含一个分区键(Partition Key,又称哈希键)。DynamoDB 通过对分区键应用哈希函数确定数据存储的物理分区。适合直接通过唯一标识查询的场景,例如用户表中用
user_id作为主键。 -
复合主键(分区键 + 排序键) 由分区键和排序键(Sort Key,又称范围键)共同组成。分区键决定分区,排序键在该分区内对项目进行有序存储。适合需要按范围查询的数据模型,例如订单表用
customer_id做分区键,用order_date做排序键,这样就能高效查询某个客户在特定时间段内的所有订单。
二级索引
除了基于主键的访问,DynamoDB 允许定义二级索引,满足不同的查询需求。
-
全局二级索引(GSI) 拥有独立的分区键和可选的排序键,索引内容可以来自基表中任意属性。GSI 与基表异步更新,容量与基表独立设置,适用于需要多维查询的场景。最多可创建 20 个 GSI。
-
本地二级索引(LSI) 必须与基表共享相同的分区键,但可使用不同的排序键。LSI 强一致性时延更低,且容量与基表共享。只能在创建表时定义,最多 5 个 LSI。适合对同一分区下的数据按不同排序方式进行检索。
读写容量模式
DynamoDB 提供两种容量控制方式:
- 按需模式(On-Demand) 无需容量规划,自动扩展以适应工作负载。按实际读/写请求计费,适合流量不可预测或无需精细优化成本的应用。
- 预置模式(Provisioned) 指定每秒的读取容量单位(RCU)和写入容量单位(WCU)。可配合自动伸缩(Auto Scaling)根据利用率动态调整容量。成本可控,适合流量可预测且追求性价比的场景。
数据操作与 API 简介
基本 CRUD
| 操作 | 说明 |
|---|---|
PutItem |
创建一项新项目或替换旧项目(全量更新) |
GetItem |
根据主键读取单个项目 |
UpdateItem |
修改项目的特定属性,支持原子计数器、条件更新等 |
DeleteItem |
根据主键删除单条记录 |
高效查询
-
Query针对复合主键,返回分区键下所有排序键匹配条件的项目。支持过滤表达式、分页和顺序(升序/降序)。这是 DynamoDB 最核心的高性能操作,单次查询仅涉及一个分区,延迟稳定在个位数毫秒。 -
Scan遍历整张表,读取所有项目,可在扫描后应用过滤表达式。效率较低且消耗大量读取容量,应尽量避免在生产环境中对大数据集使用 Scan。
批量与事务
BatchGetItem/BatchWriteItem一次操作读写最多 25 个不同主键的项目,适合批量处理。TransactWriteItems/TransactGetItems提供 ACID 事务支持,可在单一请求中原子性地完成多项跨表或跨主键操作。
高级特性
DynamoDB Streams
启用流后,每当表中的项目发生创建、更新或删除,变更记录会被推送到一个持续保留 24 小时的有序流中。您可以借助 AWS Lambda 读取流,实现数据同步、跨区域复制、审计日志、搜索索引构建等实时处理需求。
全局表(Global Tables)
允许在多个 AWS 区域间自动复制 DynamoDB 表,实现低延迟的跨区域读写和灾难恢复。底层使用“最后写入者胜出”的冲突解决机制,配置简单,无需手动管理复制管道。
备份与恢复
- 按需备份:创建完整表数据快照,不消耗表性能,长期保留。
- 连续备份(时间点恢复 PITR):自动持续备份,可将表恢复到过去 35 天内的任意一秒。开启此功能会产生额外费用,但提供了关键的数据保护能力。
DynamoDB Accelerator (DAX)
一个全托管的内存缓存集群,与 DynamoDB 紧密集成,可将读取延迟从毫秒降低到微秒级别。DAX 兼容 DynamoDB API,无需修改应用逻辑,只需将端点指向 DAX 集群,适用于对延迟极其敏感的读取密集型工作负载。
数据模型设计最佳实践
面向查询建模
与关系数据库先建实体再设计查询的思路相反,DynamoDB 的设计应从应用的访问模式出发:
- 列出所有需要的查询场景。
- 确定每个查询的条件(分区键需相等,排序键可范围或相等)。
- 针对查询设计主键和二级索引。
- 避免使用 Join 操作,通过数据冗余(单表设计)将相关数据预融合到一个项目或同一分区内。
单表设计模式
将不同类型实体(如用户、订单、产品)全部存储在一张表中,利用分区键和排序键的灵活性区分实体种类,并通过键值前缀实现高效查询。例如,分区键采用 USER#<user_id>,排序键用 PROFILE#<user_id> 存放用户基本资料,用户订单用 ORDER#<order_id> 作为排序键。这种模式显著减少了分布式事务需求,提升了性能。
排序键的利用
- 复合排序键:将多个属性组合进排序键,可通过字符串前缀查询实现多条件筛选。例如
ORDER#2025-01-15#PENDING。 - 使用版本号:在排序键中加入版本或时间戳,方便获取最新记录。
- 稀疏索引:仅当项目包含某个属性时,该项目才会进入索引,利用此特性可构建条件筛选索引,节省容量。
常见使用场景
- Web 和移动应用后端 管理用户会话、用户资料、游戏状态等,高并发、低延迟需求天然匹配 DynamoDB。
- 物联网 (IoT) 存储设备遥测数据,利用时间序列排序键高效查询设备指标。
- 实时购物车与订单系统 通过事务支持保证库存扣减和订单创建的一致性。
- 内容管理与元数据存储 存储文件元数据,通过 GSI 实现多维度检索。
- 排行榜与计数器 使用原子更新和 DAX 实现实时计分和排行展示。
快速上手:创建第一张表
- 登录 AWS 管理控制台,进入 DynamoDB 服务。
- 点击“创建表”,输入表名如
Sessions。 - 定义分区键,例如
session_id(字符串);若需复合主键,添加排序键如created_at(字符串)。 - 在“表设置”中选择默认设置(按需容量模式),点击“创建表”。
- 创建完成后,进入“项目”选项卡,通过“创建项目”添加一条测试数据。
- 返回“概览”页,开启“时间点恢复”以激活连续备份。
- 使用 AWS CLI 或 SDK 测试读写操作,确认功能符合预期。
定价与成本优化
- 读写请求量:按需模式下每百万请求收费,预置模式按 RCU/WCU 每小时计费。
- 存储:按每月存储的 GB 计费,包括表数据和索引占用。
- 可选功能:PITR 备份、全局表跨区域复制、DAX 实例等均额外收费。
- 免费套餐:每月包含 25 GB 存储、25 个预置 WCU 和 RCU 以及 2.5 亿个按需读写请求,足够开发和小型应用免费使用。
优化建议:
- 精确设计索引,避免不必要的数据复制。
- 使用生存时间(TTL)自动删除过期数据,减少存储成本。
- 对于稳定的工作负载,选择预留容量可大幅节省预置模式费用。
- 监控
ConsumedCapacity,及时调整索引或查询模式,降低消耗。
DynamoDB 将强大的分布式数据库能力简化为一款几乎零运维的服务,灵活性和性能使其成为 AWS 生态中最核心的存储基石之一。掌握数据建模方法和核心 API 后,它可以胜任大多数高并发、低延迟的应用场景。