Jorge Turbica / blog · Blog ← Todos los artículos EN · Read in English
Cloud

DynamoDB ya carga 100 millones de ítems desde S3 en menos de una hora, en tablas existentes

Bulk put items carga ficheros de S3 en tablas DynamoDB vivas, con condiciones por ítem y sin gastar capacidad. Cancelar no deshace lo escrito.

Cien millones de ítems de 1 KB en menos de una hora, sin tocar la capacidad de la tabla y sin escribir un solo bucle de BatchWriteItem. Es la cifra orientativa que da AWS para bulk put items, la función de DynamoDB disponible desde el 5 de noviembre de 2026 que carga ficheros de S3 en una tabla que ya existe. Hasta ahora, la importación gestionada desde S3 solo servía para crear tablas nuevas.

Qué cambia

DynamoDB ya tenía Import from S3, pero su documentación lo deja claro: crea una tabla nueva al lanzar la importación y no admite tablas existentes. Para recargar un catálogo, hacer un backfill o refrescar datos cada noche había que montar un proceso propio con BatchWriteItem (lotes de 25 ítems, reintentos de UnprocessedItems, control del throttling) o con Glue o EMR.

Bulk put items es un trabajo asíncrono y gestionado:

  • Entrada: DynamoDB JSON o Amazon Ion, un registro por línea, opcionalmente comprimido con gzip o zstd, bajo un prefijo de S3.
  • Condiciones por registro: cada línea puede llevar su propia ConditionExpression con la misma gramática que PutItem. En un mismo fichero conviven escrituras sin condición, solo-inserción (attribute_not_exists) y protegidas por versión. Un registro que no cumple su condición no cuenta como error: se salta y queda anotado en el informe.
  • Capacidad aparte: las escrituras van por capacidad dedicada del sistema y no cuentan en las métricas de lectura y escritura de CloudWatch, así que no disparan tus alarmas ni el autoescalado.
  • Dos niveles: Standard, el más barato, para cargas sin prisa; Accelerated, con más rendimiento y precio más alto, para migraciones o recuperaciones con plazo. Standard está en todas las regiones comerciales y GovCloud; Accelerated, en un subconjunto.

Cuánto tarda y qué cuesta

AWS publica tiempos orientativos del nivel Accelerated con ítems de 1 KB, claves uniformes y sin replicación a GSI:

Ítems de 1 KBTiempo estimado
10 millonesmenos de 10 minutos
100 millonesmenos de 1 hora
1.000 millonesde 2 a 4 horas

En precio, AWS solo afirma que escribe "a un precio inferior" al de las escrituras por petición equivalentes. La referencia para comparar: en us-east-1, el modo bajo demanda cobra 0,625 $ por millón de unidades de escritura. Cargar 100 millones de ítems de 1 KB con PutItem son 100 millones de WRU, unos 62,50 $ solo en la tabla base, y cada GSI que proyecte esos ítems suma sus propias escrituras. Ese es el techo que bulk put items promete rebajar; para la cifra exacta de cada nivel hay que mirar la tabla de precios de tu región.

Cómo lanzarlo

El comando del anuncio, con el nivel Accelerated y un informe de errores y de condiciones fallidas:

bash
aws dynamodb start-bulk-put-items \
  --table-name arn:aws:dynamodb:us-east-1:123456789012:table/MusicCollection \
  --input-s3-configuration '{"S3Bucket":"my-import-bucket","S3KeyPrefix":"daily/","InputFormat":"DYNAMODB_JSON"}' \
  --output-s3-configuration '{"S3Bucket":"my-report-bucket","S3KeyPrefix":"reports/","OutputType":["ERROR","CONDITION_CHECK_FAILURE"]}' \
  --performance-tier ACCELERATED

Y un registro de entrada que solo se escribe si la versión guardada es anterior:

json
{"Item": {"Artist": {"S": "The Ternaries"}, "SongTitle": {"S": "Blue"}, "Version": {"N": "12"}}, "ConditionExpression": "#v < :v", "ExpressionAttributeNames": {"#v": "Version"}, "ExpressionAttributeValues": {":v": {"N": "12"}}}

El seguimiento se hace con describe-bulk-operation y list-bulk-operations (90 días de historial), y cancel-bulk-operation lo detiene. Los permisos son dos acciones nuevas: dynamodb:StartBulkOperation a nivel de cuenta y dynamodb:BulkPutItems sobre la tabla, además de lectura del bucket de entrada, escritura en el de informes y acceso a las claves KMS. Las llamadas quedan en CloudTrail y el arranque es idempotente con un client token.

Cancelar no deshace nada, y otras trampas

La trampa principal está en la cancelación: no hay rollback. Si cancelas a mitad, lo ya escrito se queda en la tabla. Por eso la práctica que recomienda AWS es que toda carga se pueda repetir sin efectos, con attribute_not_exists para inserciones o una comparación de versión para refrescos. Con esa condición, relanzar el mismo fichero tras un fallo no pisa nada.

La segunda está aguas abajo. Los ítems importados aparecen en DynamoDB Streams y en Kinesis Data Streams como si fueran escrituras de la aplicación, y llegan también a las integraciones zero-ETL. Una carga de 100 millones de ítems en una hora es un pico que tus consumidores de streams (Lambdas, réplicas, índices de búsqueda) tienen que absorber; dimensiónalos antes de lanzar el nivel Accelerated en producción. Los GSI y LSI se actualizan solos con capacidad aislada, así que una tabla con muchos índices tarda más en cargar, pero sin afectar a la latencia de la aplicación.

Por último, el estado COMPLETED_WITH_ERRORS no es un éxito: indica registros que no se escribieron, casi siempre por datos de origen mal formados. El informe en S3 da el objeto y la posición de cada fallo; haz que tu pipeline lo lea y falle si no está vacío.

BatchWriteItem y PutItem siguen siendo la herramienta para unos pocos ítems en segundos. Para recargas nocturnas, backfills y migraciones a tablas vivas, esta función sustituye el script de lotes que casi todos los equipos con DynamoDB mantienen.

Fuentes

Jorge Turbica

Software Engineer y SRE. Escribo sobre los retos reales que me encuentro en producción.

Ver portfolio ↗