想象你经营着一家名叫“云仓一号”的巨型仓库。每天有海量货物涌进来,每件货物入库前都要在闸口盖一个章——这个章决定它被送往哪个货架区。取货时,你只需报出“区号+楼层格号”,取货员就能飞奔过去。这套“盖章→上架→取货”的体系,正是 DynamoDB 的缩影:数据如同货物,哈希函数如同盖章机,分区键决定货物去向,排序键决定货架上的位置。更有意思的是,这座仓库还能自动扩容、自动清理临期商品、额外设置分拣台(索引)应对偏门查询。本文用这座“云仓一号”贯穿始终,带你从零建立对世界级键值数据库的直觉。

岗位关联

掌握 DynamoDB 核心,是踏入云原生存储与海量数据工程的第一把钥匙。无论你未来做后端、数据平台还是 AI 应用,它都能帮你设计出高吞吐、低延迟、省成本的存储底座。

目录
  1. 可视化演示
  2. 基本概念
  3. 数据分区原理
  4. 一致性模型
  5. 索引机制
  6. 容量与性能
  7. 高级能力
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

展示系统处理流水线、实时性能指标曲线及多方案对比分析,包含数据流转、吞吐延迟监控与方案评估。

本节配有交互动效(进入视口后自动加载,约 3KB)。

系统可视化 处理流程:输入→处理→模型→输出 性能监控:实时指标 P=L×T

基本概念

“云仓一号”里每件货物都拥有唯一的库位号,比如“3区-12层-05格”。取货员听到这个编号便直奔目标货架,全程不用翻账本、不用问同事。这套“报号取货”之所以快,是因为库位号本身就是一张无需查找的地址地图。DynamoDB 的设计哲学与此完全同构:将一切数据组织成可通过主键直达的“货物”。

在 DynamoDB 中,这座仓库叫“表”(Table),每件货箱叫“项目”(Item),货箱上贴的各类标签叫“属性”(Attribute)。主键由两部分拼接而成:分区键(Partition Key)——对应库位区号,决定货物进哪个大区;排序键(Sort Key)——对应楼层格号,决定在大区内的排列顺序。主键合并唯一,换句话说,世界上没有两件货占用同一个“区号+楼层格”。

与传统关系型数据库不同,DynamoDB 没有固定的列结构。这一箱货可以贴三个标签,那一箱可以贴五个,互不干扰。写入用 PutItem(上架),读取用 GetItem(报号取货),按区批量取货则用 Query。它们共同构成了键值访问的核心操作。

当你向取货员完整报出“区号+楼层格号”,他就能在毫秒级把货送到你面前——这就是 DynamoDB 最快查询路径的由来。主键设计得越贴近业务访问模式,这座仓库就越高效。

Item={PK,SK,a1,a2,…,an}\text{Item} = \{ \text{PK}, \text{SK}, a_1, a_2, \ldots, a_n \}
一个项目由主键(分区键 + 排序键)与若干属性共同构成,主键是它的唯一身份凭证。
  1. 分区键 PK项目归属的大区编号,DynamoDB 用它计算哈希决定存储分区,类似仓库的“区号”。
    PK=区域编号\text{PK} = \text{区域编号}
  2. 排序键 SK大区内部的格子位置,让同一分区键下的项目按顺序排列,类似“楼层格号”。
    SK=区内序列号\text{SK} = \text{区内序列号}
  3. 属性集合项目携带的任意键值标签(如颜色、大小、VIP 标记),不同项目可以有不同的标签集合。
    {a1,a2,…,an}=属性映射\{a_1, a_2, \ldots, a_n\} = \text{属性映射}
  4. 主键唯一性整张表内,分区键与排序键的组合不可重复,这是快速定位货物的前提。
    (PK,SK) 全局唯一(\text{PK}, \text{SK}) \text{ 全局唯一}

数据分区原理

仓库大到一定程度,任何单一货架都承受不了全部货物。于是“云仓一号”在入库闸口安装了一台“盖章机”:每件货物经过时,它迅速盖出一个区间编号,货物便被自动送往对应的库区。这台盖章机从不怠工,无论来多少货,它都一视同仁地用同一套规则分派。

在 DynamoDB 中,这台“盖章机”就是哈希函数。它把分区键字符串通过哈希运算映射成一个数字,再对当前分区总数取模,得到分区编号。每个分区实际上是一组物理机器,负责一部分数据的存储与读写。只要分区键选得好,数据就会像撒芝麻一样均匀铺开。

P(n)=Hash(PartitionKey) mod N\text{P}(n) = \text{Hash}(\text{PartitionKey}) \bmod N

1. 哈希函数:将任意长度的字符串压缩成固定长度的数字指纹,同样的输入永远得到同样的输出。

Hash("user_123")→0x9F2C…\text{Hash}(\text{"user\_123"}) \to 0x9F2C \ldots

2. 取模运算:用指纹对分区总数 N 取余,把巨大数字收敛到 0 到 N-1 的区间。

Hash(PK) mod N∈[0,N−1]\text{Hash}(\text{PK}) \bmod N \in [0, N-1]

3. 分区编号:得到的结果就是货物要去的库区;后续所有读写都直接定位到这个分区。

n=分区编号n = \text{分区编号}

4. N 的变化:随着数据增长,DynamoDB 会分裂分区、迁移数据,这就是“分区演化”。

N 随时间动态增大N \text{ 随时间动态增大}

如果所有货物都被盖章机分到同一个库区,其他库区空转,这个唯一的库区就会爆仓——这就是“热点分区”。想象一款爆款商品,它的分区键如果只是固定枚举值(如“爆款”),所有数据都会涌向同一个分区。解决办法是提高分区键基数:用用户 ID、订单号这类高基数键,或给低频键加随机后缀(业界称为“加盐”),把流量打散到不同库区。盖章机选得好,八个库区永远热热闹闹、谁也不闲。

一致性模型

“云仓一号”有三个取货闸口,每个闸口都放着一本总账的副本。强一致性的世界是这样的:三本账实时同步,任何闸口读到的库存数量永远一致;而最终一致性的世界则是:账本同步存在几毫秒延迟,刚入仓的货物可能在 A 闸口看不到,但 B、C 闸口稍后就都能看到了。

DynamoDB 默认采用最终一致性读:你读到的大概率是最新值,但极端情况下可能读到旧值,代价是读吞吐量减半。如果业务绝不允许读到旧账(比如余额查询),可指定强一致性读,系统会等待所有副本同步完毕再返回结果,但消耗 2 倍读容量。这正是分布式系统在一致性与可用性之间的经典取舍。

DynamoDB 之所以敢在一致性上“打折”,是因为多副本带来可用性的大幅提升。只要还有一个副本活着,仓库就还能开门营业。

除了读一致性,DynamoDB 还提供“条件写入”:只有账本还是原来那一页时才允许涂改。这如同仓库规定“只有货架上的登记卡未被他人改动,你才能在上面追加记录”,可有效防止并发覆盖。你愿意等账本同步的几毫秒,换三个闸口永远开门;还是坚持实时一致,接受偶尔排队?理解这个权衡,是分布式存储设计的必修课。

A=1−(1−a)rA = 1 - (1 - a)^r
总可用性等于 1 减去“所有副本同时故障”的概率:副本越多,系统越不容易整体宕机。
  1. 单副本可用性 a某个副本在给定时间窗口内正常服务的概率,例如 99%。
    a=0.99a = 0.99
  2. 单副本故障概率1 减去可用性,即某个副本失效的概率。
    1−a=0.011 - a = 0.01
  3. 全部故障概率r 个副本同时故障的概率,需要乘方运算。
    (1−a)r=0.01r(1 - a)^r = 0.01^r
  4. 总可用性 A用 1 减去“全挂”概率,得到系统整体可用性。
    A=1−(1−a)rA = 1 - (1-a)^r

索引机制

顾客来“云仓一号”取货,九成会报库位号,但偶尔有人问:“把所有 VIP 品牌的货都找出来。”按区号找?VIP 货物散落在八个库区,挨个翻箱太费劲。于是仓库增设了“小分拣台”:每件 VIP 货上架时,前台顺手抄一张索引卡,按品牌归类摆放。这样顾客再问,直接查卡片堆就行,不必跑遍全仓。

DynamoDB 的“小分拣台”就是索引。全局二级索引(GSI)如同一个可以跨库区工作的超级分拣台:它用任意属性作为新分区键,在整张表范围内建立索引。局部二级索引(LSI)则像“区内分拣台”:它只能在同一分区键下,用另一个字段作为排序键,且在建表时必须定义,事后无法修改。

更妙的是“稀疏索引”:只有当项目包含某个属性时,才为它生成索引卡。比如只有 VIP 会员才有“vipLevel“字段,那么基于这个字段建的索引天然只包含 VIP 项目,体积小、写入开销低。索引投影则控制索引卡上附带抄写哪些属性,避免每次查卡后还要回主货架取货。通过索引查询,偏门查询从”全仓翻箱“变成”翻一叠卡片”。

小分拣台无法取代主货架,但它让“按品牌找货”这类偏门查询变得飞快。每次上货时前台多抄一张卡片,换来的是查询不用翻遍全仓——这就是索引以“写入放大”换取“读取加速”的本质。

S=∣{i∈I:索引键非空}∣∣I∣S = \frac{|\{ i \in I : \text{索引键非空} \}|}{|I|}
稀疏索引的选择率:有索引键的项目数占总项目数的比例。比例越低,索引越“稀疏”、越省资源。
  1. 项目全集 I表中所有项目的集合,作为分母。
    I={全部项目}I = \{\text{全部项目}\}
  2. 索引键非空子集分子是那些确实带有索引键字段的项目。
    {i∈I:索引键非空}\{ i \in I : \text{索引键非空} \}
  3. 基数符号竖线表示集合的大小,即数量统计。
    ∣⋅∣=集合中元素个数| \cdot | = \text{集合中元素个数}
  4. 选择率 S该比值反映索引的稀疏程度,值越小说明索引覆盖的项目越少、越高效。
    0≤S≤10 \le S \le 1

容量与性能

“云仓一号”每天有明确的吞吐预算:每小时最多接收多少张上货单、处理多少张取货单。预算是仓库运营的阀门,阀门拧太小,高峰期门口排长队;拧太大,平时又白养一群人。DynamoDB 用读容量单元(RCU)和写容量单元(WCU)精确刻画这座阀门的宽度。

一个 RCU 代表每秒一次 4KB 的强一致性读,或者每秒两次 4KB 的最终一致性读;一个 WCU 代表每秒一次 1KB 的写入。项目体积越大,每次操作消耗的容量单元越多,就像货物越重,占用的搬运工越多。这个换算关系决定了你在云上的成本账单。

容量有两种配置模式:预置容量(固定预算)与按需容量(按实际流量计费)。自动扩容量则像给仓库配备了一个会看水位的调节员:流量上涨,自动加开闸口;流量回落,自动关闸。为了进一步降低读延迟,DAX(DynamoDB Accelerator)在仓库门口增设了“快速提货柜”:热数据直接存在柜中,命中就不用进仓翻箱,延迟从毫秒级降到微秒级。

预算给足,闸口再挤也不排队;预算给少,突发流量一来全仓拥堵。聪明的架构师会利用 DAX 缓存热点、用最终一致读降低成本、让自动扩容量应对突发——容量规划是一门把每一分钱花在刀刃上的艺术。

R=RCU×4KBItemSizeR = \frac{\text{RCU} \times 4\text{KB}}{\text{ItemSize}}
每秒最多可读取的项目数,等于读容量单元数乘 4KB 基准,再除以单个项目大小。
  1. 容量预算RCU 是每秒读容量单元数,是分母上的可用总资源。
    RCU=每秒读单元数\text{RCU} = \text{每秒读单元数}
  2. 基准大小每个 RCU 固定对应 4KB 的数据读取量,这是 AWS 的定价基准。
    4KB=每个 RCU 的基准载荷4\text{KB} = \text{每个 RCU 的基准载荷}
  3. 项目大小每次读取的对象体积,以 KB 为单位。
    ItemSize=单个项目大小\text{ItemSize} = \text{单个项目大小}
  4. 每秒读取数两者相除,得到每秒最多可读取多少个项目。
    R=RCU×4KBItemSizeR = \frac{\text{RCU} \times 4\text{KB}}{\text{ItemSize}}

高级能力

现代仓库除了基本的收发货,还配备了三件自动化神器:多区联动发货、临期自动清仓和门口流水分播。它们让“云仓一号”在无人值守的深夜也能稳定运转。DynamoDB 的高级能力与这三件神器一一对应。

第一件神器是事务。想象一笔订单需要同时扣减库存、创建订单、更新用户积分:任何一步失败,前面步骤都应该回滚,否则会出现“钱扣了货没发”的灾难。DynamoDB 的 TransactWriteItems 保证一批写操作要么全部生效,要么全部不生效,还支持对每笔写附加条件校验,如同几份发货单必须由一位总调度签字才会同时发出。

第二件神器是 TTL 自动清理。给数据设置一个过期时间戳,DynamoDB 会在后台自动删除过期数据,零成本、无需人工干预。这特别适合会话记录、设备日志和物联网时序数据——数据像临期商品一样,到点自动走下架通道,既省钱又省心。第三件神器是 DynamoDB Streams:每次数据变化都会产生一条事件流水,可以实时同步到数据仓库、触发下游计算或驱动审计系统,相当于仓库门口的监控摄像头自动广播每一笔进出。

在时序数据处理中,常见的最佳实践是:分区键设为设备 ID,排序键设为时间戳,TTL 设为 30 天自动清理陈旧数据。查询(Query)沿主键高效取数,而扫描(Scan)则像全仓翻箱倒柜,费容量且慢,生产环境要极力避免。三件自动化神器让这座仓库真正做到“高吞吐、低成本、免运维”,这正是 DynamoDB 成为云原生存储基石的原因。

expired(t)={1t>texpire0t≤texpire\text{expired}(t) = \begin{cases} 1 & t > t_{\text{expire}} \\ 0 & t \le t_{\text{expire}} \end{cases}
TTL 过期判断是一个指示函数:当前时间超过过期时间戳就返回 1,触发删除;否则返回 0,继续保留。
  1. 当前时间戳 t系统当前时刻的时间表示。
    t=当前时刻t = \text{当前时刻}
  2. 过期时间戳创建项目时指定的存活截止时间。
    texpire=过期时间t_{\text{expire}} = \text{过期时间}
  3. 比较判断如果当前时间已晚于过期时间,说明数据寿命终结。
    t>texpiret > t_{\text{expire}}
  4. 指示输出返回 1 表示删除,返回 0 表示保留,由后台任务周期执行。
    expired(t)∈{0,1}\text{expired}(t) \in \{0, 1\}

AI 应用场景

大规模游戏玩家档案存取

阶段:数据存储与特征读取

解决的问题:游戏每秒产生海量玩家档案读写,传统关系库在千万级并发下容易锁表、扩容困难。DynamoDB 的键值访问天然适配玩家 ID 维度的点查,最终一致性读让排行榜、背包等非关键数据的读取成本减半。

具体案例:某手游用玩家 ID 作为分区键,profile 作为排序键存储档案,再用 GSI 按“公会 ID”建索引,实现“查某个公会的所有成员”的偏门查询。高峰期开启自动扩容量,DAX 缓存热门道具配置,读延迟稳定在 1ms 以内。

物联网设备时序数据管理

阶段:时序数据写入、存储与过期清理

解决的问题:千万级物联网设备每 5 秒上报一条状态数据,如果永久存储成本不可控,且历史数据价值随时间衰减。DynamoDB 以设备 ID 为分区键、时间戳为排序键,配合 TTL 自动删除 30 天前的数据,存储成本大幅下降。

具体案例:某智慧工厂为每台机床创建独立分区键,写入温度、震动等时序属性,利用 DynamoDB Streams 将实时数据同步到流处理管道做异常检测,超过阈值立刻告警。TTL 保证数据库只保留近 30 天的原始数据,历史归档交给低成本对象存储。

电商购物车与订单事务处理

阶段:事务性写入与缓存加速

解决的问题:用户在购物车中批量修改商品数量、提交订单、扣减库存,任何一个环节失败都要求整体回滚。DynamoDB 事务保证跨多个项目的原子提交,DAX 缓存热门商品详情让前端秒开。

具体案例:某跨境电商把购物车项目放在一张表,分区键为用户 ID,排序键为商品 ID。提交订单时用 TransactWriteItems 同时更新订单表、清空购物车、扣减库存,并附加“库存大于零”的条件校验,彻底避免超卖。

Python 演示

python62 行
import hashlib  class MiniDynamoDB:    """一个极简 DynamoDB 模拟器:哈希分区 + RCU/WCU 统计 + 稀疏 GSI"""     def __init__(self, partitions=8):        self.partitions = [{} for _ in range(partitions)]        self.n = partitions        self.wcu = 0        self.rcu = 0        self.gsi = {}     def _part(self, key):        # 哈希函数对 key 取指纹,再对分区总数取模        digest = hashlib.md5(key.encode()).hexdigest()        return int(digest, 16) % self.n     def put(self, pk, sk, attrs):        # 写入项目:落到对应分区,同时维护稀疏 GSI        part = self._part(pk)        self.partitions[part][(pk, sk)] = attrs        self.wcu += 1        if 'brand' in attrs:            self.gsi.setdefault(('brand', attrs['brand']), []).append((pk, sk))     def get(self, pk, sk, strong=False):        # 强一致读消耗 2 倍 RCU,最终一致读消耗 1 倍        part = self._part(pk)        self.rcu += 2 if strong else 1        return self.partitions[part].get((pk, sk))     def query_by_pk(self, pk):        # 按分区键查询,分区内按排序键排序返回        part = self._part(pk)        rows = sorted(            ((k, v) for k, v in self.partitions[part].items() if k[0] == pk),            key=lambda x: x[0][1],        )        self.rcu += max(len(rows) // 4, 1)        return [v for _, v in rows]     def query_by_brand(self, brand):        # 通过稀疏 GSI 按品牌查到主键列表        keys = self.gsi.get(('brand', brand), [])        self.rcu += max(len(keys), 1)        return [k for k in keys]  def main():    db = MiniDynamoDB(partitions=8)    db.put('user#1001', 'profile', {'name': 'Alice', 'brand': 'basic'})    db.put('user#1002', 'profile', {'name': 'Bob', 'brand': 'vip'})    db.put('user#1003', 'profile', {'name': 'Cara', 'brand': 'vip'})    print('强一致读:', db.get('user#1001', 'profile', strong=True))    print('同分区排序查询:', db.query_by_pk('user#1001'))    print('GSI 按品牌查询:', db.query_by_brand('vip'))    print('已消耗 WCU:', db.wcu, 'RCU:', db.rcu)  if __name__ == '__main__':    main()
目的:用纯 Python 实现一个迷你 DynamoDB,演示哈希分区、稀疏索引、容量单元统计与两类查询。
  1. db = MiniDynamoDB(partitions=8)初始化 8 个分区,对应“云仓一号”的 8 个库区。
  2. def _part(self, key):哈希函数加取模,决定货物落在哪个分区。
  3. self.partitions[part][(pk, sk)] = attrs以 (PK, SK) 为复合主键写入项目。
  4. if 'brand' in attrs:只有带 brand 属性的项目才进 GSI,体现稀疏索引。
  5. self.wcu += 1每次写入消耗一个写容量单元。
  6. self.rcu += 2 if strong else 1强一致读消耗两倍读容量。
  7. sorted(... key=lambda x: x[0][1])同一分区内按排序键 SK 排序。
  8. db.query_by_brand('vip')通过 GSI 按品牌查出主键列表,不用扫描全表。

常见误区

误区我刚接触 DynamoDB 时以为它只有主键查询,想按其他字段查就只能全表扫描。既然没有索引,是不是不适合复杂查询?

正解DynamoDB 不仅有索引,还有两种:局部二级索引 LSI 和全局二级索引 GSI。LSI 类似“区内分拣台”,只能在原分区键范围内换个排序键;GSI 则是“全局分拣台”,可以跨分区用任意属性建索引。索引相当于在仓库里增设小分拣台,让“按品牌、按状态”这类偏门查询无需翻遍全仓。

为何常见:很多教程只讲主键读写,忽略了索引;加上 Scan 操作的存在让人误以为“查不到就扫全表”,其实为查询模式建好索引才是正道。

误区DynamoDB 默认是最终一致性,那我每次读会不会都读到很久之前的旧数据?是不是丢数据了?

正解最终一致性并非“丢数据”,而是多副本之间存在极短的同步延迟(通常毫秒级)。绝大多数情况下你读到的是最新值,只是在副本刚写入尚未同步的瞬间,可能读到旧值。它不会弄丢任何已确认的写入。用“仓库三本账”类比:账本 A 刚记了新数字,账本 B 还在同步中,此时查 B 会得到上一个数字,但下一秒再看就一致了。

为何常见:把“最终一致性”中的“最终”误解为“很慢”,又把它与 CAP 中的“分区容忍”混为一谈,导致高估了延迟风险。

误区我给表开了自动扩容量,流量再大系统也能自动扛住,容量规划跟我没关系了。

正解自动扩容只能调整表的整体读写预算,解决不了“数据全部挤在同一个分区”的热点问题。如果分区键设计差,某个单一分区会率先触碰到单分区吞吐上限(约 3000 RCU / 1000 WCU),即使整表预算再高也救不了它。好比仓库自动增加了总闸口数量,但所有货都堵在 1 号闸口,总闸口再多也无济于事。

为何常见:混淆“整体容量”与“单分区容量”,低估了数据分布设计的重要性,把自动扩容当成万能药。

误区表里数据几百万条,我又不想设计复合主键,干脆用 Scan 全表扫一遍再过滤,反正能查出来。

正解Scan 会扫描每个分区的每件货物,消耗的容量单元与全表数据量成正比,成本高、延迟大。生产环境正确的做法是围绕业务访问模式设计主键和索引,让请求走 GetItem 或 Query 直达目标分区。Scan 只适合离线分析、导出备份等低频场景,相当于请全仓员工彻夜盘点,而不是日常取货方式。

为何常见:Scan 的写法最简单省事,对小型演示数据也看不出差距,但在真实数据量下代价呈线性爆炸,初学者容易踩坑。

面试题

Q1. DynamoDB 最核心的数据模型是?

单选题 · easy

  • A.行与列的网状表模型
  • B.键值对与文档模型← 正确答案
  • C.图与节点的关联模型
  • D.时间戳序列的编排模型

答案:B。DynamoDB 是键值/文档型 NoSQL 数据库,每个项目由主键(分区键+排序键)与属性集合构成,对应“云仓一号”的库位号与货物标签。网状模型属于图数据库,行列表模型属于关系库,时间序列模型则对应专用时序库。

Q2. 分区键最核心的作用是什么?

单选题 · easy

  • A.对项目数据做加密保护
  • B.决定项目存储的分区位置← 正确答案
  • C.压缩项目体积节省空间
  • D.给属性添加缺失的默认值

答案:B。分区键经过哈希取模后决定数据落在哪个分区,等同于盖章机决定货物去哪个库区。加密、压缩、默认值都不是分区键的职责。它决定了数据的物理分布与查询性能,是表设计的基石。

Q3. 最终一致性读相比强一致读的主要优势是?

单选题 · mid

  • A.保证每次读到最新值
  • B.读容量消耗减少一半← 正确答案
  • C.完全不需要多副本同步
  • D.读取失败次数大幅下降

答案:B。最终一致读消耗 1 个 RCU,强一致读消耗 2 个 RCU,所以读吞吐成本减半。它不保证每次读到最新值,也不意味不需要副本,读取失败率与一致性级别并无直接关系。这把“省钱”与“时效”的选择权交给业务。

Q4. GSI 与 LSI 的核心区别是什么?

单选题 · mid

  • A.GSI 可跨分区建新键索引← 正确答案
  • B.LSI 的读取速度永远更快
  • C.GSI 不占用任何存储空间
  • D.LSI 可以在建表后修改

答案:A。GSI 是全局二级索引,能跨所有分区用任意属性作为新键;LSI 只能在同一分区键下增加排序键,且建表时必须定义、不可修改。LSI 读取并不必然更快,GSI 也要占存储。类比:GSI 是全仓分拣台,LSI 是区内小分拣台。

Q5. 以下哪些手段能避免全表扫描 Scan?

多选题 · easy

  • A.设计高基数的分区键← 正确答案
  • B.合理使用 LSI 或 GSI← 正确答案
  • C.用 GetItem 按主键读取← 正确答案
  • D.把所有属性合并成一个字段

答案:ABC。避免 Scan 的核心是让查询有明确的主键或索引路径:分区键设计良好则 Query 可直达分区,索引可覆盖偏门查询,GetItem 直接按主键取货。合并字段并不能建立新的查询路径,反而可能破坏数据结构。

Q6. 1 个写容量单元 WCU 每秒最多能写多大负载?

单选题 · hard

  • A.1KB 的写入负载← 正确答案
  • B.4KB 的写入负载
  • C.1MB 的写入负载
  • D.16KB 的写入负载

答案:A。DynamoDB 规定 1 个 WCU 代表每秒一次不超过 1KB 的写入。若单个项目大于 1KB,需要消耗多个 WCU。这与读容量单元 RCU 的 4KB 基准不同,是容量规划中常见的计算起点。

Q7. DAX 加速器主要解决什么问题?

单选题 · mid

  • A.防止数据被误删除
  • B.高频读请求的延迟← 正确答案
  • C.多个事务写入冲突
  • D.分区键哈希碰撞

答案:B。DAX 是 DynamoDB 的内存缓存层,把热点项目放在仓库门口的“快速提货柜”里,命中后无需访问底层分区,读延迟从毫秒级降至微秒级。它不参与数据持久化、事务冲突或哈希设计。

Q8. 以下哪些设计能有效缓解热点分区?

多选题 · mid

  • A.使用用户 ID 等高基数键← 正确答案
  • B.给低基数字段加随机盐← 正确答案
  • C.将排序键设计为时间戳← 正确答案
  • D.固定使用枚举字符串键

答案:ABC。高基数键让哈希分散,随机盐把流量打散到不同分区,时间戳排序键则抬高了单分区内数据与吞吐的分布维度。固定枚举键(如“爆款”)恰恰是热点分区的典型诱因,会让所有数据涌向同一个库区。

Q9. 关于 DynamoDB 事务,下列说法正确的有?

多选题 · hard

  • A.支持跨多个项目原子写入← 正确答案
  • B.任一步失败则全部回滚← 正确答案
  • C.与关系库事务功能完全一致
  • D.可附带条件校验防超卖← 正确答案

答案:ABD。DynamoDB 的 TransactWriteItems 支持跨表跨项目原子提交,全部成功或全部回滚,并可对每笔写附加条件表达式。但它是单文档级别的 ACID,不支持多语句自由编排、自定义隔离级别等关系库复杂事务能力。

Q10. TTL 机制的主要用途是什么?

单选题 · easy

  • A.自动删除到达过期时间的数据← 正确答案
  • B.加速主键的哈希计算速度
  • C.将热数据复制到内存缓存
  • D.加密项目中的敏感属性

答案:A。TTL 让数据带着过期时间戳入库,后台自动清理过期项目,特别适合会话记录、日志等时序数据。它不负责哈希加速、缓存复制或加密,是降低存储成本的自动化利器。