入门阅读约 2 分钟

如何用 Docker 运行 DynamoDB Local:完整指南

DynamoDB Local 是 AWS 提供的、可下载的 DynamoDB 单进程模拟版——相同的 API,不需要 AWS 账户,不需要网络,没有按请求计费。用它来做本地开发和集成测试,然后在生产环境把同一份代码指向云端。它会忽略预置吞吐量,也永远不会限流,所以它无法替代负载测试或限额测试。

我该怎么用 Docker 运行 DynamoDB Local?

运行 docker run -p 8000:8000 amazon/dynamodb-local 来启动官方镜像,它会把 DynamoDB 引擎暴露在 http://localhost:8000。用任意占位凭证把你的 AWS SDK 或 CLI 指向那个端点,然后就像对着云端一样创建表、发请求。加上 -sharedDb 和一个挂载的 -dbPath 卷,可以让数据在重启之间保留。

启动容器

docker run -p 8000:8000 amazon/dynamodb-local

这会把引擎暴露在 http://localhost:8000

docker-compose

大多数项目会在 docker-compose.yml 里固定它,好让整个团队拿到相同的端点:

services:
  dynamodb:
    image: amazon/dynamodb-local
    user: root
    command: '-jar DynamoDBLocal.jar -sharedDb -dbPath /data'
    ports:
      - '8000:8000'
    volumes:
      - dynamodb-data:/data
volumes:
  dynamodb-data:

该镜像以非 root 的 dynamodblocal 用户身份运行,它无法在 root 拥有的命名卷内打开数据库文件——没有 user: root 你就会撞上 SQLiteException [14] unable to open database file,而且每一次调用都会挂起。

持久化

DynamoDB Local 默认是内存中运行的——容器一停,每张表就消失了。两个标志能让它变得持久:

  • -sharedDb 让所有客户端使用同一个共享数据库文件(没有它,每一组凭证/区域都会得到自己独立的数据库——一个常见的"我的表去哪了?"惊喜)。
  • -dbPath /data 加上一个挂载的卷,会把那个文件写到磁盘上,于是数据能在 docker compose down 之后存活。

把 SDK 指向它

只有端点会变——凭证可以是任意占位值:

import {DynamoDBClient} from '@aws-sdk/client-dynamodb';

const client = new DynamoDBClient({
  endpoint: 'http://localhost:8000',
  region: 'local',
  credentials: {accessKeyId: 'x', secretAccessKey: 'x'}
});

创建一张表

aws dynamodb create-table \
  --endpoint-url http://localhost:8000 \
  --table-name AppData \
  --attribute-definitions AttributeName=PK,AttributeType=S AttributeName=SK,AttributeType=S \
  --key-schema AttributeName=PK,KeyType=HASH AttributeName=SK,KeyType=RANGE \
  --billing-mode PAY_PER_REQUEST

像这样的单表 PK/SK 结构是一个不错的默认选择。当你加载测试数据时,用 DynamoDB-JSON 转换器把普通 JSON 转换成线路格式。

验证容器已经启动、表也创建成功了:

aws dynamodb list-tables --endpoint-url http://localhost:8000

用图形界面浏览它

CLI 调用很快就会变得繁琐。常见的选项是开源的 dynamodb-admin 网页界面,或者一个桌面客户端。DynoTable 直接连接到 localhost:8000(或任意 LocalStack 端点——参见连接 DynamoDB Local 与 LocalStack),让你用浏览、通过 查询、编辑本地表——用的就是你操作云端表时的同一套界面,无需 aws CLI 往返。

Local 不模仿什么

将 Local 视为 API 兼容层,而不是容量模拟器。它忽略了预配置吞吐量,永不返回 ⟦0⟧, 并且不模拟按需突发行为。针对 Local 的负载测试告诉您 AWS 中没有关于分区限制或自适应容量的内容。如果您没有计划,集成测试中还会出现其他差距:

行为DynamoDB 本地AWS DynamoDB
计费/RCU/WCU按请求计量
节流从来没有是的,在表/索引限制下
TTL 删除时机尽最大努力,不受 SLA 约束AWS日程背景清扫
DynamoDB 直播简化全流语义+Lambda接线
跨表交易在最近的版本中受支持具有记录限制的完整 ACID
全局表/PITR不可用生产特点

如果您的测试断言节流、TTL 在几秒钟内到期或流扇出,针对一次性云表或 LocalStack 运行至少一套套件您需要启用的功能。

实用的本地工作流程

大多数团队将 Local 分为三层:

  1. 单元测试 — 在 CI 中旋转容器,在 beforeAll 中创建表,撕裂下afterAll。保持固定装置较小;元帅平原JSON穿过 DynamoDB JSON converter 测试粘贴时手动绘制属性图。
  2. 集成测试 — 运行您的应用程序使用的相同 SDK 客户端工厂,仅交换 endpoint 和凭证。断言项目形状和有条件写入,而不是消耗的容量(本地不返回对预算有意义ConsumedCapacity)。
  3. 手动探索 — 将 DynoTable 与本地配置文件连接,进行阶段编辑,并在部署架构更改之前运行 PartiQL 或关键条件查询。当您的业务规模超出单一流程时——多个服务、S3 触发器或 IAM 风格路由 — 升级到 LocalStack 或开发帐户。对于“我的访问模式是否可以编译?”,本地保持最快的循环。

无需手动编组的种子数据

当您不标记每个项目时,从 JSON 文件加载十个夹具项目会更快珍视自己。将数组粘贴到 DynamoDB JSON converter,复制整理好的输出,并使用 BatchWriteItem 针对 --endpoint-url 进行批量写入 http://localhost:8000。对于更新频繁的固定装置,组装 UpdateExpressionDynamoDB expression builder 并粘贴生成的属性映射到您的测试工具中。

DynoTable 的项目编辑器在提交时执行相同的编组 — 当测试失败让您只能盯着 CLI 中的原始 {"S":...} blob。

何时离开当地

当您需要在 AWS 本身上测量以下任何一项时,请运送到真实的桌子:

  • 容量规划 — 每秒查询 1,000 次的 1 KB 项会消耗按需计费每秒大约 250 个最终一致的 RCU;本地报告为零。模型与 pricing calculator 使用以下尺寸 item-size calculator
  • 索引传播滞后 — GSI 读取最终在生产中保持一致;本地返回索引行的速度足够快,陈旧读取的错误会隐藏起来,直到部署为止。
  • 跨账户 IAM — 资源范围的角色和条件键仅存在于云。保持本地化以快速反馈模式和表达式语法;验证成本和在生产流量之前针对临时表的一致性假设。

值得编写脚本绕过的陷阱

  • 忘记 -sharedDb — 每个唯一的凭证对都有一个隔离的数据库; CI 和你的笔记本电脑看起来像是不同的宇宙。
  • 根拥有的卷没有 user: root — SQLite 后端静默失败直到您添加上面部分中的撰写覆盖。
  • 假设 Streams 奇偶校验 — 支持流的 Lambda 需要云或 LocalStack 目标;仅本地不会执行扇出。
  • 空字符串键 — 自 2020 年起允许在非键属性上使用,但仍被拒绝在按键上;以与AWS中相同的方式验证灯具。

Download DynoTable,添加指向http://localhost:8000的配置文件,并浏览您刚刚创建的表格 - 相同的网格、过滤器生成器和 SQL 您在生产中使用 Workbench,循环上的 AWS 支出为零。

更新于