Come funzionano i componenti interni di archiviazione DynamoDB
DynamoDB è una tabella hash i cui valori sono alberi ordinati, distribuiti su macchine in tre zone di disponibilità. Due strutture dati svolgono quasi tutto il lavoro: un hash su preleva una macchina, un B-tree su ordina gli articoli al suo interno.
In che modo DynamoDB memorizza i dati?
DynamoDB memorizza i tuoi dati come una gigantesca tabella hash distribuita i cui valori sono ordinati in alberi B. Un hash sull' seleziona un nodo di archiviazione; un albero B ordina gli elementi in base alla chiave di ordinamento al suo interno. Ogni scrittura va a un leader che replica su due peer in tre zone di disponibilità, riconoscendo una volta raggiunto il quorum (due delle tre repliche).
- La chiave di partizione viene sottoposta ad hashing, non viene cercata. DynamoDB esegue una funzione hash
sul tuo
PKper trovare il nodo di archiviazione (o i nodi, una volta che una grande raccolta viene divisa) mantenendo quella partizione: un salto O(1), indipendentemente dalla dimensione della tabella. - La chiave di ordinamento risiede in un albero B. All'interno di una partizione, gli elementi sono archiviati in a
Albero B ordinato per chiave di ordinamento: ordine byte UTF-8 per stringhe, ordine numerico per
Tasti numerici: ecco perché le letture a distanza (
begins_with,between) sono economiche eScanno. - Ogni scrittura raggiunge un quorum prima di eseguire l'ack. Una scrittura va a un leader, che
si replica su due peer in altre AZ e riconosce una volta il quorum (due dei
tre repliche) ce l'ha: la durabilità viene acquistata prima che il tuo
PutItemritorni. - Questo è il motivo per cui esistono le regole del modello di accesso. Hash-then-tree è veloce solo quando leggi per chiave. Nessuna chiave, nessun percorso veloce: torni a scansionare l'albero.
Inizia con la struttura dei dati, non con l'API
Provenendo da SQL, immagini una tabella come righe su disco con una selezione del pianificatore di query indici. DynamoDB non ha pianificatore. Il layout dello spazio di archiviazione è il contratto: cosa c'è veloce e cos'è un fucile cadono entrambi direttamente da due strutture.
Immagina una mappa distribuita gigante. La chiave è un hash della chiave di partizione. Il value è un intero albero B di elementi che lo condividono chiave di partizione, ordinata per chiave di ordinamento.
Tutto il resto: semantica delle query, avvisi di 10 GB, perché una chiave mancante impone
a Scan - è una conseguenza di quella frase.
Hashing la chiave di partizione per trovare il nodo
Quando arriva una richiesta, DynamoDB applica una funzione hash interna al file valore della chiave di partizione. L'hash viene mappato in modo deterministico a un nodo di archiviazione — la partizione fisica che possiede tali elementi. AWS lo documenta come meccanismo alla base delle ricerche di chiavi a tempo costante indipendentemente dalle dimensioni della tabella.
Questo è il passaggio O(1). Una tabella da 10 TB e una tabella da 10 KB costano lo stesso per individuare: hash, salta, fatto. Non esiste alcuna scansione dell'indice per trovare il nodo, nessuna statistica, nessun piano.
Il problema è il rovescio della medaglia. Se non fornisci la chiave di partizione, DynamoDB ha
nessun nodo a cui saltare: deve percorrere ogni partizione. Questo è un Scan, e lo è
la differenza tra O(1) e la lettura dell'intera tabella.
La richiesta viene inviata esattamente a una partizione, quindi scende verso quella partizione albero B con chiave di ordinamento per l'articolo: due passaggi economici invece di una passeggiata sul tavolo.
Ordina gli elementi in un albero B per partizione
All'interno di una singola partizione, gli elementi non sono un mucchio. Sono tenuti in un B-tree con chiave
dalla chiave di ordinamento, ordinata lessicograficamente. Una ricerca nell'albero B è O(log n) e
è fondamentale che n siano gli elementi in una partizione, non l'intera tabella.
Questo è l'intero motivo per cui le letture dell'intervallo di chiavi di ordinamento sono economiche. Effettua una telemetria della flotta tabella in cui le letture di ciascun dispositivo risiedono sotto una chiave di partizione:
| PK | SK |
|---|---|
| PK = DEVICE#a91 | SK = READING#2026-06-23T08:00Z |
| PK = DEVICE#a91 | SK = READING#2026-06-23T08:05Z |
| PK = DEVICE#a91 | SK = READING#2026-06-23T08:10Z |
Poiché l'albero B è ordinato, "tutte le letture tra le 08:00 e le 09:00" sono un albero discesa al valore iniziale più una camminata sequenziale - non un filtro su ogni lettura del dispositivo mai inviato. Leggi solo l'intervallo corrispondente.
Questo ordinamento è anche il motivo per cui una query begins_with(SK, "READING#2026-06-23") è veloce
mentre il filtraggio su un attributo non chiave non lo è. L'albero può cercare tramite SK; esso
non posso cercare altro. Per comporre queste condizioni chiave in modo sicuro, costruiscile
piuttosto nel DynamoDB Expression Builder.
rispetto alle stringhe concatenate manualmente:
KeyConditionExpression PK = :pk AND begins_with(SK, :day)
Replica ogni scrittura su tre AZ
Una partizione non è una macchina. Ognuno viene replicato su tre nodi in tre zone di disponibilità: il progetto del quorum basato sui leader dettagliato nel 2022 Documento USENIX ATC DynamoDB (il documento Amazon Dynamo del 2007 è il nome e antenato della filosofia, non questo modello di replica).
Un nodo è il leader della partizione. Una scrittura va al leader, che
scrive localmente e si replica sui suoi due peer. Il leader controlla la scrittura una volta alla volta
il quorum durevole dei nodi ce l'ha, quindi la durabilità nelle zone di disponibilità viene pagata prima
il tuo PutItem ritorna.
Le letture hanno una scelta. Una lettura va al leader e vede l'ultima scrittura impegnata. Una lettura può essere servita da uno qualsiasi dei tre nodi, uno dei quali potrebbe essere indietro di qualche millisecondo: questo è il ritardo che scambi con letture più economiche e più disponibili.
| Coerenza eventuale | Coerenza forte | |
|---|---|---|
| Servito da | Uno qualsiasi dei 3 nodi | Solo nodo leader |
| Vede l'ultima scrittura | Forse (piccolo ritardo) | Sempre |
| Costo RCU | Metà (0,5 RCU per 4 KB su richiesta in us-east-1) | Completo (1 RCU ogni 4 KB) |
| Disponibilità | Superiore | Inferiore (nodo singolo) |
Con fatturazione su richiesta, la lettura di un articolo da 2 KB costa fortemente 1 RCU; lo stesso leggere costi eventualmente congrui 0,5 RCU. Classifica in linea i tuoi percorsi caldi nel calcolatore dei prezzi.
La stessa idea di propagazione asincrona è il motivo per cui una lettura GSI può essere obsoleta: vedi Gli GSI sono coerenza eventuale.
Leggi le regole della struttura
Quasi ogni "regola" dell'DynamoDB è solo fisica dello storage:
- Fornisci sempre la chiave di partizione. Nessuna chiave, nessun hash target: stai scansionando l'intera mappa. Questo è il nucleo di Query vs Scan.
- Co-individuare ciò che leggete insieme sotto un'unica chiave di partizione, quindi una singola hash + tree-walk restituisce l'intera raccolta di elementi. Questo è il fondamento di design a tabella singola.
- Mantieni le partizioni limitate. Una partizione è un albero B su un insieme finito di nodi; un tasto di scelta rapida o il limite di 10 GB di un LSI sono entrambi limiti di quello fisico partizione.
Una volta vista la forma dell'hash e poi dell'albero B, la disciplina del modello di accesso si interrompe ti senti arbitrario: stai semplicemente mantenendo ogni lettura sul percorso veloce.
Passaggi successivi
Modella le tue chiavi in modo che corrispondano alla struttura con strategie di ordinamento delle chiavi e design a tabella singola, quindi assemblare l'effettivo espressioni nel Builder di espressioni DynamoDB. Prova DynoTable per osservare queste letture eseguite rispetto alle tue tabelle e vedere esattamente quali elementi vengono ritirati da una condizione chiave.