应使用 aws-sdk-go-v2/service/dynamodb 初始化客户端,显式设置 region 和凭据,避免硬编码密钥;正确解组需循环内新建结构体实例,字段用值类型并配 dynamodbav tag;优先 Query/GSI 而非 Scan,批量操作用 BatchGetItem;幂等写入用 ConditionExpression,多表一致性用 TransactWriteItems;初期选 On-Demand 模式,稳定后切预置+Auto Scaling。

用 aws-sdk-go-v2/service/dynamodb 初始化客户端,别碰 v1
直接用 aws-sdk-go-v2/service/dynamodb,v1 SDK 已停止维护,且 v2 的 context 支持、错误类型(types.InternalFailureException 等)、重试策略更清晰。v1 的 dynamodbattribute 包在 v2 中已被 attributevalue 替代,混用会导致解组失败或 panic。
初始化时必须传入 region 和凭据——生产环境走 IAM 角色(EC2/ECS),本地开发用 AWS_PROFILE 或 ~/.aws/credentials,别硬编码密钥。
-
config.WithRegion("us-east-1")必须显式设置,哪怕 Lambda 在同 region 运行,SDK 不会自动推断 - 避免全局复用
*dynamodb.Client实例但未设 timeout:HTTP 客户端默认无超时,请求卡住会拖垮整个微服务 - 若用容器部署(ECS/EKS),确保 task role 或 service account 有
dynamodb:PutItem、dynamodb:GetItem等最小权限策略,而非AmazonDynamoDBFullAccess
解组 DynamoDB Item 时,别在循环里复用同一个 struct 指针
这是 Go + DynamoDB 最常踩的坑:attributevalue.UnmarshalMap() 写入的是指针地址,如果循环外定义 var user User,每次调用都往同一内存写,最后切片里全是最后一个 item 的副本。
正确做法是每次迭代新建实例:
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
立即学习“go语言免费学习笔记(深入)”;
users := make([]User, 0, len(items))
for _, item := range items {
var u User
if err := attributevalue.UnmarshalMap(item, &u); err != nil {
// handle error
continue
}
users = append(users, u)
}
- 字段用值类型(
string)而非指针(*string),除非明确需要区分空字符串和 nil;指针字段在解组时容易因未初始化导致 panic - 结构体 tag 必须是
dynamodbav:"field_name",不是json:"field_name",否则UnmarshalMap无视字段 - 如果字段含嵌套 map 或 slice,确保对应 Go 类型也声明为 map[string]interface{} 或 []interface{},否则解组会静默失败
Query 和 Scan 的性能差异,直接影响微服务吞吐量
微服务响应延迟敏感,Scan 全表遍历在数据量 > 1000 条时就明显变慢,且消耗更多 RCU/WCU;Query 基于分区键(Partition Key)索引,毫秒级返回。
- 设计表时必须预估查询路径:比如用户服务按
user_id查询,就设user_id为 Partition Key;若还需按邮箱查,建 GSI(Global Secondary Index),别依赖 Scan -
Query可配KeyConditionExpression和FilterExpression,前者走索引,后者在结果集上过滤——把条件塞进FilterExpression会导致扫描整 partition,白费 RCU - 批量操作优先用
BatchGetItem而非多次GetItem,但注意单次 Batch 最多 100 项,且总 payload ≤ 16MB
事务与幂等写入,在微服务分布式场景下不能省略
微服务间调用网络不可靠,重复请求常见。DynamoDB 的 TransactWriteItems 支持跨表 ACID,但代价是吞吐量下降约 30%,且不支持 Scan/Query。
- 简单幂等写入可用
ConditionExpression:比如attribute_not_exists(created_at)防止重复创建 - 涉及多表更新(如“扣库存 + 生成订单”),必须用事务,否则部分失败导致数据不一致
- 事务内每个操作仍受 400KB 单 item 限制,大对象(如 base64 图片)得先存 S3,DynamoDB 只存 URL
- 事务失败返回
types.TransactionCanceledException,需捕获并重试——但重试前检查是否已部分成功,避免双花
PutItem 都带着明确的业务语义,而不是把 DynamoDB 当作黑盒 key-value 存储来用。

















