高流量DynamoDB表迁移改Schema(加排序键)时如何减少数据损失
DynamoDB高流量表无停机迁移至带Sort Key的新表方案
1. Terraform部署新表
首先用Terraform创建符合要求的新表,指定id为Partition Key,createdAt为Sort Key,配置按需计费模式适配高流量场景,避免容量不足,同时开启点-in-time Recovery保障数据安全。示例代码如下:
resource "aws_dynamodb_table" "new_kv_table" { name = "new-kv-table" billing_mode = "PAY_PER_REQUEST" hash_key = "id" range_key = "createdAt" attribute { name = "id" type = "S" } attribute { name = "createdAt" type = "N" # 用时间戳数字类型,便于排序查询 } point_in_time_recovery { enabled = true } }
2. 开启双写模式
修改现有生产服务的写入逻辑,将所有新数据同时写入旧表和新表:
- 优先使用DynamoDB事务API(
TransactWriteItems),确保两个写入操作原子性,要么全部成功,要么全部回滚,避免数据不一致。 - 若服务暂不支持事务,需添加重试机制,记录写入失败的请求,后续异步补全,确保新表不丢失任何写入数据。
- 注意:新表写入时需确保
createdAt字段有有效值——若旧数据无该字段,可提取业务中的创建时间、数据最后修改时间,或用迁移时的时间戳填充。
3. 批量迁移历史数据
在双写模式稳定运行后,开始迁移旧表的历史数据:
- 使用AWS CLI的
scan命令分批读取旧表数据,控制分页大小(--page-size)和单次返回数量(--max-items),避免占用过多旧表读取容量影响生产流量:aws dynamodb scan --table-name old-kv-table --page-size 100 --max-items 1000 --starting-token <上次的起始令牌> - 对读取到的每条数据补充
createdAt字段(无则按规则生成),用batch-write-item批量写入新表,同时添加条件表达式避免重复写入(双写阶段可能已写入部分数据):aws dynamodb batch-write-item --request-items '{"new-kv-table": [{"PutRequest": {"Item": {"id": {"S": "xxx"}, "createdAt": {"N": "1699999999"}, ...}, "ConditionExpression": "attribute_not_exists(id) AND attribute_not_exists(createdAt)"}}]}' - 循环执行上述操作,直到所有历史数据迁移完成。可通过对比新旧表的项目计数(
aws dynamodb describe-table --table-name <表名> --query 'Table.ItemCount')验证进度。
4. 数据一致性校验
完成批量迁移后,确认新旧表数据完全一致:
- 抽样校验:随机选取部分
id,分别从新旧表读取数据,对比内容和数量。 - 全量校验:若数据量不大,可使用自定义脚本全量对比;高流量大表可通过DynamoDB Streams监听新旧表的写入差异,确保无遗漏。
5. 切换读取流量
逐步将服务的读取逻辑从旧表切换到新表:
- 先将小比例流量(如10%)切换到新表,观察服务运行状态和数据正确性。
- 无异常后,逐步提升比例至100%,确保所有读取请求都指向新表。
6. 停止双写并清理
确认读取完全切换且数据一致后:
- 修改服务代码,停止向旧表写入数据,仅保留新表作为唯一数据源。
- 将旧表设置为只读模式(通过IAM权限限制写入),保留一段时间作为备份,之后可根据业务需求决定是否删除或归档。
关键注意事项
- 流量控制:批量迁移时严格控制读取速率,避免旧表因扫描操作导致读写性能下降,影响生产业务。
- 异常处理:双写和迁移过程中记录所有失败请求,设置重试机制,确保数据无丢失。
- 回滚方案:若切换过程中出现问题,立即将读取流量切回旧表,保持双写模式运行,排查问题后重新切换。
内容的提问来源于stack exchange,提问作者jinyoungch
相关产品推荐
相关产品推荐

