ExtendDB:AWS 开源的 DynamoDB 兼容适配器,本地开发终于不用连线上了

每次本地开发要用 DynamoDB,你有几个选择:

  1. 连线上 DynamoDB(费钱 + 可能误操作生产表)
  2. 用 DynamoDB Local(Java 的,启动慢,行为和线上有差异)
  3. 自己 Mock(维护成本高,覆盖不全)

现在多了第四个选择——ExtendDB,亚马逊云科技官方开源的 DynamoDB 兼容适配器。

它提供完整的 DynamoDB API 兼容层,底层存储可以自定义。本地开发时指向 ExtendDB,线上环境指向真正的 DynamoDB,代码零修改。

ExtendDB 是什么

一句话:让你用 DynamoDB API 操作非 DynamoDB 后端

具体来说:

  • 实现了 DynamoDB 的 API 协议(CreateTable、PutItem、GetItem、Query、Scan、BatchWrite 等)
  • 底层存储可插拔(SQLite、PostgreSQL、文件系统等)
  • 完全兼容 AWS SDK——你的 boto3/aws-sdk-js 代码不需要任何修改

为什么这东西有用

场景一:本地开发

import boto3

# 本地开发 → 连 ExtendDB
# 生产环境 → 连真正的 DynamoDB
# 代码完全一样,只改 endpoint

if os.environ.get('ENV') == 'local':
    dynamodb = boto3.resource(
        'dynamodb',
        endpoint_url='http://localhost:8787',  # ExtendDB
        region_name='us-east-1',
        aws_access_key_id='local',
        aws_secret_access_key='local'
    )
else:
    dynamodb = boto3.resource('dynamodb')

# 之后的代码完全一样
table = dynamodb.Table('users')
table.put_item(Item={
    'user_id': 'u-001',
    'name': '张三',
    'email': 'zhangsan@example.com',
    'created_at': '2026-05-27T12:00:00Z'
})

response = table.get_item(Key={'user_id': 'u-001'})
print(response['Item'])

场景二:CI/CD 测试

# GitHub Actions 里用 ExtendDB 替代 DynamoDB Local
name: Test
on: [push]
jobs:
  test:
    runs-on: ubuntu-latest
    services:
      extenddb:
        image: aws/extenddb:latest
        ports:
          - 8787:8787
    steps:
      - uses: actions/checkout@v4
      - name: Run tests
        env:
          DYNAMODB_ENDPOINT: http://localhost:8787
        run: |
          npm install
          npm test

比 DynamoDB Local 轻量得多——不需要 Java 运行时,启动秒级。

场景三:跨后端迁移评估

想把部分数据从 DynamoDB 迁到其他存储但不确定影响?可以先用 ExtendDB 对接目标后端跑测试,确认兼容性后再做正式迁移。

快速上手

Docker 启动

# 拉取镜像
docker pull aws/extenddb:latest

# 启动(默认 SQLite 后端)
docker run -d \
  --name extenddb \
  -p 8787:8787 \
  -v extenddb-data:/data \
  aws/extenddb:latest

# 验证
aws dynamodb list-tables \
  --endpoint-url http://localhost:8787 \
  --region us-east-1

源码编译

# 克隆仓库
git clone https://github.com/aws/extenddb.git
cd extenddb

# 编译(Go 项目)
go build -o extenddb ./cmd/extenddb

# 启动
./extenddb --port 8787 --backend sqlite --data-dir ./data

配置后端

# extenddb.yaml
server:
  port: 8787
  host: 0.0.0.0

backend:
  type: sqlite  # 可选: sqlite, postgres, memory
  sqlite:
    path: /data/extenddb.db
  # postgres:
  #   host: localhost
  #   port: 5432
  #   database: extenddb
  #   user: admin
  #   password: ${DB_PASSWORD}

logging:
  level: info
  format: json

API 兼容性

ExtendDB 支持的 DynamoDB API 操作:

操作 状态 备注
CreateTable 含 GSI/LSI
DeleteTable
DescribeTable
PutItem 含条件表达式
GetItem 含投影表达式
UpdateItem 含更新表达式
DeleteItem 含条件表达式
Query 含 KeyCondition + Filter
Scan 含过滤和分页
BatchWriteItem
BatchGetItem
TransactWriteItems
TransactGetItems

不支持的(或部分支持):

  • DynamoDB Streams(暂不支持)
  • TTL 自动删除(计划中)
  • 全局表(不适用于本地场景)

和 DynamoDB Local 对比

对比项 DynamoDB Local ExtendDB
运行时 Java(JVM) Go(原生二进制)
启动时间 几秒~十几秒 毫秒级
内存占用 200MB+ 20-50MB
Docker 镜像 ~500MB ~30MB
持久化 SharedDb 模式 多后端可选
API 兼容度 高(官方维护) 高(社区验证中)
开源 是(Apache 2.0)
数据可见性 黑盒 SQLite/PG 可直接查

ExtendDB 最大的优势:轻量 + 开源 + 数据可见。

用 SQLite 后端时,你可以直接用 sqlite3 打开数据文件看里面存了什么,debug 超级方便。DynamoDB Local 做不到这点。

在项目中集成

Node.js + Jest 测试

// test/setup.js
const { DynamoDBClient, CreateTableCommand } = require('@aws-sdk/client-dynamodb');

const client = new DynamoDBClient({
  endpoint: process.env.DYNAMODB_ENDPOINT || 'http://localhost:8787',
  region: 'us-east-1',
  credentials: { accessKeyId: 'local', secretAccessKey: 'local' }
});

beforeAll(async () => {
  await client.send(new CreateTableCommand({
    TableName: 'test-users',
    KeySchema: [{ AttributeName: 'pk', KeyType: 'HASH' }],
    AttributeDefinitions: [{ AttributeName: 'pk', AttributeType: 'S' }],
    BillingMode: 'PAY_PER_REQUEST'
  }));
});

afterAll(async () => {
  // ExtendDB 支持 DeleteTable 清理
});

Python + pytest

# conftest.py
import pytest
import boto3
import os

@pytest.fixture(scope='session')
def dynamodb():
    endpoint = os.environ.get('DYNAMODB_ENDPOINT', 'http://localhost:8787')
    resource = boto3.resource(
        'dynamodb',
        endpoint_url=endpoint,
        region_name='us-east-1',
        aws_access_key_id='local',
        aws_secret_access_key='local'
    )
    # 创建测试表
    table = resource.create_table(
        TableName='test-orders',
        KeySchema=[
            {'AttributeName': 'order_id', 'KeyType': 'HASH'},
            {'AttributeName': 'created_at', 'KeyType': 'RANGE'}
        ],
        AttributeDefinitions=[
            {'AttributeName': 'order_id', 'AttributeType': 'S'},
            {'AttributeName': 'created_at', 'AttributeType': 'S'}
        ],
        BillingMode='PAY_PER_REQUEST'
    )
    table.wait_until_exists()
    yield resource

def test_create_order(dynamodb):
    table = dynamodb.Table('test-orders')
    table.put_item(Item={
        'order_id': 'ord-001',
        'created_at': '2026-05-27T10:00:00Z',
        'amount': 99.9,
        'status': 'pending'
    })
    resp = table.get_item(Key={
        'order_id': 'ord-001',
        'created_at': '2026-05-27T10:00:00Z'
    })
    assert resp['Item']['amount'] == 99.9

我的判断

ExtendDB 填补了 DynamoDB 开发体验中的一个老缺口。

DynamoDB 的线上体验很好(零运维、自动扩缩),但本地开发体验一直是短板。DynamoDB Local 太重(Java)、启动慢、不开源。很多团队因为这个原因在本地开发时用别的数据库(Redis、PostgreSQL),但这就带来了本地和线上行为不一致的问题。

ExtendDB 的思路很务实:Go 原生二进制、启动快、开源、数据可见。对于日常开发和 CI 测试来说,这比 DynamoDB Local 好用。

不过要注意:它还在早期阶段,生产环境不要用它替代真正的 DynamoDB。它是开发/测试工具,不是生产存储。


相关链接:

posted @ 2026-05-28 11:30  亚马逊云开发者  阅读(4)  评论(0)    收藏  举报