Avanzado7 min de lectura

Cómo funcionan los internals de almacenamiento de DynamoDB

DynamoDB es una tabla hash cuyos valores son árboles ordenados, repartidos entre máquinas en tres zonas de disponibilidad. Dos estructuras de datos hacen casi todo el trabajo: un hash sobre la clave de partición elige una máquina, un B-tree sobre la clave de ordenación ordena los items dentro de ella.

¿Cómo almacena DynamoDB los datos?

DynamoDB almacena tus datos como una tabla hash distribuida gigante cuyos valores son B-trees ordenados. Un hash sobre la clave de partición elige un nodo de almacenamiento; un B-tree ordena los items por clave de ordenación dentro de él. Cada escritura se replica de forma síncrona en tres nodos en tres zonas de disponibilidad antes de confirmar.

  • La clave de partición se hashea, no se busca. DynamoDB pasa una función hash sobre tu PK para encontrar el único nodo de almacenamiento que contiene esa partición — un salto O(1), sin importar el tamaño de la tabla.
  • La clave de ordenación vive en un B-tree. Dentro de una partición, los items se almacenan en un B-tree ordenado lexicográficamente por SK, por lo que las lecturas de rango (begins_with, between) son baratas y un Scan no.
  • Cada escritura golpea tres nodos antes de confirmar. Una escritura va a un líder, que replica de forma síncrona a dos pares en otras AZ — la durabilidad se paga antes de que tu PutItem retorne.
  • Por esto existen las reglas de patrones de acceso. Hash-luego-árbol es rápido solo cuando lees por clave. Sin clave, no hay camino rápido — recurres a escanear el árbol.

Empieza con la estructura de datos, no la API

Viniendo de SQL, imaginas una tabla como filas en disco con un planificador de queries eligiendo índices. DynamoDB no tiene planificador. La disposición de almacenamiento es el contrato — qué es rápido y qué es un footgun caen ambos directamente de dos estructuras.

Imagina un mapa distribuido gigante. La clave es un hash de tu clave de partición. El valor no es un solo item — es todo un B-tree de items que comparten esa clave de partición, ordenados por clave de ordenación.

Todo lo demás — la semántica de query, los avisos de 10 GB, por qué una clave ausente fuerza un Scan — es una consecuencia de esa única frase.

Hashea la clave de partición para encontrar el nodo

Cuando llega una petición, DynamoDB aplica una función hash interna al valor de la clave de partición. El hash mapea de forma determinista a un nodo de almacenamiento — la partición física que posee esos items. AWS documenta esto como el mecanismo detrás de las búsquedas de clave en tiempo constante sin importar el tamaño de la tabla.

Ese es el paso O(1). Una tabla de 10 TB y una de 10 KB cuestan lo mismo de localizar: hash, salto, hecho. No hay scan de índice para encontrar el nodo, ni estadísticas, ni plan.

La pega es la otra cara. Si no suministras la clave de partición, DynamoDB no tiene nodo al que saltar — tiene que recorrer cada partición. Eso es un Scan, y es la diferencia entre O(1) y leer toda la tabla.

PutItem / GetItemPK=DEVICE#a91Hash(PK)Nodo de almacenamiento(una partición)B-tree sobre SKREADING#... ordenadoItem

La petición hashea a exactamente una partición, luego desciende el B-tree de clave de ordenación de esa partición hasta el item — dos pasos baratos en lugar de un recorrido de tabla.

Ordena los items en un B-tree por partición

Dentro de una sola partición, los items no son un heap. Se mantienen en un B-tree con clave por la clave de ordenación, ordenado lexicográficamente. Una búsqueda en B-tree es O(log n), y crucialmente esa n son los items en una partición, no toda la tabla.

Esta es toda la razón por la que las lecturas de rango de clave de ordenación son baratas. Toma una tabla de telemetría de flota donde las lecturas de cada dispositivo viven bajo una clave de partición:

PKSK
PK = DEVICE#a91SK = READING#2026-06-23T08:00Z
PK = DEVICE#a91SK = READING#2026-06-23T08:05Z
PK = DEVICE#a91SK = READING#2026-06-23T08:10Z

Como el B-tree está ordenado, "todas las lecturas entre 08:00 y 09:00" es un descenso de árbol al valor de inicio más un recorrido secuencial — no un filtro sobre cada lectura que el dispositivo haya enviado jamás. Lees solo el rango que coincide.

Ese orden es también por qué una query begins_with(SK, "READING#2026-06-23") es rápida mientras filtrar sobre un atributo que no es clave no lo es. El árbol puede buscar por SK; no puede buscar por nada más. Para componer esas condiciones de clave de forma segura, constrúyelas en el constructor de expresiones de DynamoDB en lugar de concatenar cadenas a mano:

KeyConditionExpression  PK = :pk AND begins_with(SK, :day)

Replica cada escritura a tres AZ

Una partición no es una máquina. Cada una se replica a través de tres nodos en tres zonas de disponibilidad — un linaje de diseño que se remonta al modelo de replicación del paper de Amazon Dynamo de 2007.

Un nodo es el líder de la partición. Una escritura va al líder, que escribe localmente y replica a sus dos pares. El líder confirma la escritura una vez que un quórum durable de nodos la tiene — así que la durabilidad a través de AZ se paga antes de que tu PutItem retorne.

Las lecturas tienen elección. Una lectura fuertemente consistente va al líder y ve la escritura confirmada más reciente. Una lectura eventualmente consistente puede ser servida por cualquiera de los tres nodos, uno de los cuales puede ir unos milisegundos por detrás — ese es el retraso que cambias por lecturas más baratas y disponibles.

Eventualmente consistenteFuertemente consistente
Servida porCualquiera de los 3 nodosSolo el nodo líder
Ve la escritura más recienteQuizás (pequeño retraso)Siempre
Coste de RCULa mitadCompleto
DisponibilidadMás altaMás baja (un solo nodo)

La misma idea de propagación asíncrona es por qué una lectura de GSI puede estar obsoleta — consulta los GSIs son eventualmente consistentes.

Lee las reglas a partir de la estructura

Casi cada "regla" de DynamoDB es solo física de almacenamiento:

  • Suministra siempre la clave de partición. Sin clave, no hay objetivo de hash — estás escaneando todo el mapa. Este es el núcleo de Query vs Scan.
  • Co-localiza lo que lees junto bajo una clave de partición, de forma que un solo hash + recorrido de árbol devuelva toda la colección de items. Esa es la base del diseño de tabla única.
  • Mantén las particiones acotadas. Una partición es un B-tree sobre un conjunto finito de nodos; una hot key descontrolada o el tope de 10 GB de un LSI son ambos límites de esa partición física.

Una vez que ves la forma hash-luego-B-tree, la disciplina de patrones de acceso deja de parecer arbitraria — simplemente estás manteniendo cada lectura en el camino rápido.

Próximos pasos

Modela tus claves para que coincidan con la estructura con estrategias de clave de ordenación y diseño de tabla única, luego ensambla las expresiones reales en el constructor de expresiones de DynamoDB. Prueba DynoTable para observar estas lecturas ejecutarse contra tus propias tablas y ver exactamente qué items recupera una condición de clave.

Actualizado