Avanzado7 min de lectura

Parallel scans en DynamoDB

Un parallel scan parte un Scan en N peticiones Scan independientes; cada una reclama un Segment de la tabla, de modo que varios workers la leen a la vez. Es la única forma que ofrece la API Scan de leer una tabla entera más rápido de lo que permite el throughput de una sola partición.

¿Qué es un parallel scan en DynamoDB?

Un parallel scan en DynamoDB parte un Scan en N peticiones independientes; cada una reclama un Segment de la tabla con Segment y TotalSegments, para que varios workers la lean en paralelo. Es la única forma que ofrece la API Scan de leer una tabla entera más rápido de lo que permite el throughput de una sola partición — pero sigue siendo una lectura completa, así que pagas por cada item escaneado.

  • Un Scan secuencial lee una partición a la vez — su velocidad está limitada al throughput de una sola partición, da igual lo grande que sea la tabla.
  • Segment + TotalSegments parten la lectura entre TotalSegments workers; cada worker escanea su propio trozo en paralelo.
  • DynamoDB hashea la para asignar segmentos, así que los trozos pueden quedar desequilibrados — más workers no siempre significa más velocidad.
  • Sigue siendo un Scan: pagas por leer cada item, y un parallel scan gordo puede vaciar el throughput de la tabla por debajo de tu tráfico en vivo.

Por qué un Scan secuencial es lento

Si vienes de SQL, una lectura de tabla completa parece una sola operación en streaming. En DynamoDB no lo es. Los datos de la tabla viven repartidos en muchas particiones físicas, pero un solo Scan las recorre de una en una, 1 MB por página.

Eso significa que un Scan plano solo puede tirar del presupuesto de throughput de una partición en un momento dado — aunque la tabla esté repartida en docenas de particiones con capacidad ociosa. Cuanto más grande es la tabla, más tarda el rastreo. (AWS: Scan paralelo)

Parte la lectura con Segment y TotalSegments

Un parallel scan arregla el cuello de botella. Eliges un número de workers, pones TotalSegments a ese número y das a cada worker un Segment distinto basado en cero. Cada worker lanza su propio Scan; DynamoDB los atiende en paralelo.

Worker 0Scan  Segment=0  TotalSegments=4
Worker 1Scan  Segment=1  TotalSegments=4
Worker 2Scan  Segment=2  TotalSegments=4
Worker 3Scan  Segment=3  TotalSegments=4

Cada worker sigue paginando con LastEvaluatedKey de forma independiente — posee su segmento de la primera página a la última. La aplicación vuelve a coser los cuatro streams. Ahora lees el throughput de cuatro particiones a la vez en lugar de una.

Ejemplo trabajado: el export nocturno

Digamos que tienes una tabla de telemetría, sensor-readings. Cada item es una lectura de un dispositivo de campo:

PK = "DEVICE#a83f"          (partition key — the device id)
SK = "TS#2026-06-22T03:14"  (sort key — ISO timestamp)
batteryMv  = 3120
tempC      = 41.8
firmwareTag = "fw-7.2.1"

Cada noche un cron vuelca la tabla entera a S3 para el warehouse de analytics. Un Scan secuencial de 80 GB tarda horas y apenas muerde tu capacidad de lectura provisionada. Así que lo repartes entre ocho workers:

Scan  sensor-readings  Segment=0  TotalSegments=8  ConsistentRead=falseScan  sensor-readings  Segment=7  TotalSegments=8  ConsistentRead=false

Ocho workers, ocho segmentos, una lectura de tabla aproximadamente ocho veces más rápida. Si solo necesitas lecturas recientes, añade un FilterExpression para tirar timestamps antiguos antes de que las filas salgan por el cable — construye e inspecciona esa expresión en el Expression Builder:

FilterExpression:  begins_with(SK, :today)

Cómo DynamoDB asigna items a segmentos

DynamoDB asigna cada item a un segmento hasheando su clave de partición — no por número de filas ni por bytes.

Así que todos los items que comparten un PK caen en el mismo segmento. En sensor-readings, todas las lecturas de DEVICE#a83f van a un solo worker, da igual cuántos timestamps tenga ese dispositivo o lo grande que sea su . (AWS: Scan paralelo)

tabla sensor-readingshash de la clave de particiónSegment 0DEVICE#a83fDEVICE#1c20Segment 1DEVICE#9be4Segment 2 (vacío)

Los segmentos acaban desiguales. Un worker puede quedarse con tres dispositivos habladores con millones de lecturas; otro puede sacar un trozo vacío. Subir TotalSegments no ayuda si tus claves de partición se agrupan — solo añades workers ociosos esperando al caliente. Una distribución uniforme de claves es lo que hace que el fan-out merezca la pena.

Mira el coste de lectura antes de lanzarlo

Un parallel scan es un evento de throughput, no un almuerzo gratis. La pregunta honesta es «¿cuánto de esta tabla entera estoy a punto de leer?» — y antes de que DynoTable lance una lectura de tabla completa te pone un diálogo de confirmación con el tamaño aproximado de la tabla y el número de items más un aviso de capacidad de lectura, y luego hace stream del progreso de items-escaneados en vivo mientras corre la lectura, para que el job nocturno no te sorprenda.

Piezas y cuándo no molestarse

  • El precipicio de throughput. Un scan con TotalSegments alto puede consumir toda la capacidad de lectura de la tabla en segundos y dejar sin aire al tráfico en vivo. En una tabla que sirve usuarios, limita cada worker con el parámetro Limit o escanea fuera de pico. (AWS: Scan paralelo)
  • Sigue siendo la herramienta equivocada para un access pattern. Los parallel scans son para jobs deliberados de tabla completa — exports, backfills, migraciones. Si llegas a uno para responder una query recurrente, eso es una señal de modelado: añade un GSI y conviértelo en un Query.
  • SELECT * en PartiQL es el mismo scan disfrazado. Compila a un Scan secuencial. Cuando de verdad necesitas analytics entre items — un GROUP BY, un JOIN, un agregado — el SQL Workbench de DynoTable los ejecuta en el cliente sobre un result set acotado, en lugar de martillar la tabla.
  • La consistencia fuerte duplica la factura. Un Scan por defecto usa lecturas de . Para un export, deja ConsistentRead=false salvo que cada página deba reflejar las escrituras más recientes — y ten en cuenta que incluso un scan strongly consistent dura minutos, así que no es un snapshot point-in-time (usa PITR/Export para eso).

Próximos pasos

Modela tus claves para que las lecturas del día a día nunca necesiten un scan — empieza por el single-table design y Query vs Scan. Cuando un job de tabla completa es de verdad la llamada correcta, prueba DynoTable para lanzar lecturas de tabla completa con un aviso de tamaño y coste por delante y progreso de scan en vivo.

Actualizado