You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Android Kotlin中用BatchWriteItem或批量自定义解析器上传数据到AWS DynamoDB

Android Kotlin + AWS Amplify 批量同步数据到DynamoDB解决方案

问题背景

我有一个基于Android Kotlin的项目,用到了AWS Amplify的Cognito、Datastore、Appsync等服务。作为AWS新手,我被批量同步数据到DynamoDB的问题困扰了一个月,目标是用最小延迟同步约2000条记录。

已尝试两种逐条同步的方法,均存在高延迟问题:

  • 用Amplify DataStore逐条保存:2000条耗时约20分钟
  • 用Amplify API.mutate逐条突变:2000条耗时约200秒

核心问题是逐条请求导致的网络 overhead 过高,需要实现批量上传方案。


可行解决方案

方案一:自定义GraphQL批量突变(推荐,贴合Amplify生态)

通过在AppSync后端定义批量操作接口,生成客户端代码后调用,性能远高于逐条请求。

步骤1:修改GraphQL Schema

在项目的schema.graphql中添加批量创建字段:

type Mutation {
  createRandomNumber(input: CreateRandomNumberInput!): RandomNumber
  # 添加批量创建接口
  batchCreateRandomNumbers(inputs: [CreateRandomNumberInput!]!): [RandomNumber]
}

步骤2:配置AppSync批量解析器

在AWS控制台进入你的AppSync API,为batchCreateRandomNumbers配置DynamoDB批量写入解析器:

  • 数据源选择你的DynamoDB表
  • 请求映射模板(将输入转为BatchWriteItem格式):
{
  "version": "2017-02-28",
  "operation": "BatchWriteItem",
  "tables": {
    "RandomNumbersTable": [
      #foreach($item in $ctx.args.inputs)
        {
          "PutRequest": {
            "Item": {
              "id": { "S": "$util.autoId()" },
              "number": { "N": "$item.number" }
              # 其他字段按需添加
            }
          }
        }#if($foreach.hasNext),#end
      #end
    ]
  }
}
  • 响应映射模板:
$util.toJson($ctx.result.data.RandomNumbersTable)

步骤3:生成Android客户端代码

在项目根目录执行命令,生成批量操作对应的Kotlin代码:

amplify codegen models

步骤4:Android端调用批量接口

按DynamoDB限制(单次最多25条)拆分数据,批量调用:

// 生成2000条数据
val items = (1..2000).map {
    CreateRandomNumberInput.builder()
        .number(it)
        .build()
}

// 按25条为一批拆分并发送请求
items.chunked(25).forEach { batch ->
    Amplify.API.mutate(
        BatchCreateRandomNumbersRequest.builder()
            .inputs(batch)
            .build(),
        { response ->
            Log.i("BatchSync", "成功同步批次:${response.data?.size}条")
        },
        { error ->
            Log.e("BatchSync", "批次同步失败", error)
        }
    )
}

该方案2000条数据仅需80次请求,通常几十秒内即可完成。


方案二:直接使用DynamoDB SDK for Android

如果不想修改GraphQL Schema,可直接调用DynamoDB原生BatchWriteItem接口,复用Amplify的身份凭证。

步骤1:添加依赖

在app/build.gradle中添加DynamoDB SDK依赖:

dependencies {
    implementation 'com.amazonaws:aws-android-sdk-dynamodb:2.62.0'
}

步骤2:初始化DynamoDB客户端

复用Amplify的身份凭证,初始化客户端:

val credentialsProvider = Amplify.Auth.getCredentialsProvider()
val dynamoDbClient = AmazonDynamoDBClientBuilder.standard()
    .withCredentials(credentialsProvider)
    .withRegion(Regions.US_EAST_1) // 替换为你的AWS区域
    .build()

步骤3:执行批量写入

按25条为一批拆分数据,发送批量请求:

val items = (1..2000).map { number ->
    val item = mutableMapOf<String, AttributeValue>()
    item["id"] = AttributeValue().withS(UUID.randomUUID().toString())
    item["number"] = AttributeValue().withN(number.toString())
    PutRequest().withItem(item)
}

items.chunked(25).forEach { batch ->
    val requestItems = mutableMapOf<String, List<WriteRequest>>()
    requestItems["RandomNumbersTable"] = batch.map { WriteRequest().withPutRequest(it) }
    
    val batchRequest = BatchWriteItemRequest().withRequestItems(requestItems)
    dynamoDbClient.batchWriteItem(batchRequest)
    
    Log.i("BatchSync", "批次处理完成")
}

注意:需确保Cognito身份池权限包含dynamodb:BatchWriteItem。


方案三:优化现有API并发请求(临时应急)

如果无法修改后端,可通过控制并发数提升逐条请求的速度,避免被限流:

val items = (1..2000).map {
    RandomNumbers.builder()
        .number(it)
        .build()
}

// 用协程控制并发数(比如同时执行10条请求)
val semaphore = Semaphore(10)
CoroutineScope(Dispatchers.IO).launch {
    items.forEach { item ->
        semaphore.acquire()
        launch {
            try {
                Amplify.API.mutate(
                    ModelMutation.create(item),
                    { Log.i("BatchSync", "已保存:${it.data?.number}") },
                    { Log.e("BatchSync", "保存失败", it) }
                )
            } finally {
                semaphore.release()
            }
        }
    }
}

该方案性能不如前两种,但比纯逐条同步快很多。


内容的提问来源于stack exchange,提问作者Mahesh Gouda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 18:17:34