Avanzato7 min di lettura

Partizioni fisiche di DynamoDB

Una partizione fisica è l'unità su cui DynamoDB memorizza davvero i tuoi dati: una fetta di SSD, replicata tra le Availability Zone, che contiene una fetta del tuo key space. La tua tabella è una cosa logica. Le partizioni sono dove i byte — e i limiti di throughput — vivono davvero.

Come funzionano le partizioni di DynamoDB?

DynamoDB distribuisce la tua tabella su partizioni fisiche — fette di SSD replicate tra le Availability Zone. Ognuna si ferma a ~10 GB, 3.000 unità di lettura/sec e 1.000 unità di scrittura/sec. L'hash della tua partition key decide su quale partizione atterri un item, e DynamoDB divide le partizioni automaticamente man mano che crescono o si surriscaldano.

  • Ogni partizione si ferma a ~10 GB di storage, 3.000 unità di lettura/sec e 1.000 unità di scrittura/sec. Quei tetti sono per partizione, non per tabella.
  • L'hash della tua partition key sceglie la partizione. Gli item con la stessa chiave finiscono insieme; una hot key significa una hot partition.
  • DynamoDB divide le partizioni per te — sulla dimensione, e sul calore sostenuto — ma non può sistemare una chiave che convoglia tutto il traffico in un unico posto.
  • Il throttling con capacità da vendere è il segnale. Un errore ProvisionedThroughputExceeded mentre la tua tabella sta al 5% di utilizzo significa che una singola partizione è al massimo.

Come un item trova la sua partizione

DynamoDB passa il valore della tua partition key attraverso una funzione di hash interna. L'output dell'hash sceglie la partizione fisica. Stessa chiave in entrata, stessa partizione in uscita — ogni volta.

Venendo da SQL, non c'è analogo. Non c'è un B-tree di index da regolare, nessuna shard key da assegnare a mano. Il posizionamento è un hash che non controlli e non vedi mai.

Gli item che condividono una partition key formano un'item collection, memorizzati insieme e ordinati per sort key. È ciò che rende economica una Query su una chiave — legge una sequenza contigua su una partizione. (Vedi Query vs Scan.)

Prendi un archivio di eventi-partita per un gioco. Le chiavi della tabella sono arenaId (partizione) ed eventKey (sort):

# Item
arenaId    = "ARENA#7f3a"
eventKey   = "EVT#1719100800#a91c"
playerTag  = "Nightjar"
dmgDealt   = 412

Ogni evento per l'arena 7f3a fa l'hash sulla stessa partizione e si impila in ordine di sort key. Ottimo per "leggi la timeline di questa partita." Una passività se quell'unica arena prende tutto il traffico.

I tre tetti che ogni partizione impone

Una singola partizione è progettata per erogare al massimo:

LimitePer partizioneContato come
Storage~10 GBbyte grezzi degli item
Capacità di lettura3.000 unità lettura/sec1 RU = una lettura fortemente coerente da 4 KB
Capacità di scrittura1.000 unità scrittura/sec1 WU = una scrittura da 1 KB

Fonte: la guida AWS Best practices for designing partition keys.

La dimensione dell'item scala il calcolo. Un item da 20 KB costa 5 unità di lettura per lettura fortemente coerente, quindi una partizione serve ~600 di tali letture/sec prima di andare in throttling — non 3.000. Arrotonda per eccesso il costo di scrittura ogni 1 KB, quello di lettura ogni 4 KB.

La trappola: questi sono limiti di partizione, non di tabella. La tua tabella può essere provisioned per 40.000 WCU e andare comunque in throttling, perché tutte le scritture stanno martellando una sola partizione che si ferma a 1.000.

Come si dividono le partizioni

DynamoDB aggiunge partizioni automaticamente in due casi. Non esegui mai un comando.

Divisione sulla dimensione. Quando una partizione si riempie verso ~10 GB, DynamoDB divide in due il suo range di chiavi e sposta metà degli item su una nuova partizione. Lo storage cresce in modo trasparente; le tue letture e scritture continuano a funzionare per tutto il tempo.

Divisione per calore. Quando una partizione riceve traffico sostenuto vicino al suo tetto di throughput, DynamoDB divide il range di chiavi caldo così che ogni metà atterri sulla propria partizione. AWS chiama questo il meccanismo split-for-heat. Brevi raffiche di throttling che si fermano da sole di solito significano che una divisione è appena avvenuta.

DimensioneCalorePartizione A~10 GB / caldaTrigger didivisione?Range diviso a metàper byte memorizzatiRange diviso a metàper trafficoDue partizionicapacità ciascunaUna KEY caldaresta su una partizione

La divisione compra spazio tra molte chiavi, ma il nodo in basso è il trucco: una divisione divide un range di chiavi, mai una singola chiave.

Perché una hot key batte lo splitter

Ecco il footgun. La divisione redistribuisce range di partition key. Se il tuo traffico si concentra su un valore di chiave, ogni richiesta fa l'hash sulla stessa partizione, e non resta range da dividere.

Se l'arena 7f3a è una finale di torneo che tira 4.000 scritture/sec mentre ogni altra arena è inattiva, andrai in throttling a 1.000 — e una divisione non può aiutare, perché tutte e 4.000 condividono una chiave. Il più recente motivo di throttling KeyRangeThroughputExceeded nomina esattamente questo: il range di chiavi di una partizione, non la tabella, è oltre il suo limite.

La soluzione è nel modello dei dati, non nello slider di capacità. Fai il write-shard della hot key: appendi un piccolo suffisso così che un'arena logica si distribuisca su N partizioni fisiche.

arenaId = "ARENA#7f3a#3"   # shard 0..9, scelto per scrittura

Le letture poi si distribuiscono tra gli shard e si fondono lato client. Puoi prototipare le forme di chiave e la Query per ogni shard con l'Expression Builder per DynamoDB prima di toccare una riga di codice applicativo.

Una sfumatura: l'eccezione LSI

C'è un caso in cui lo storage è limitato per partition key. Senza un Local Secondary Index, un'item collection si auto-divide su tutte le partizioni di cui ha bisogno — miliardi di valori di sort key vanno bene.

Aggiungi un LSI, e l'intera collection per una partition key deve stare in una singola partizione da 10 GB, perché l'LSI la condivide. È la rupe per-PK trattata in GSI vs LSI — un'altra ragione per cui la maggior parte dei team ricorre ai GSI.

Progettare così che le partizioni restino fredde

La leva che controlli davvero è la partition key. Scegline una con molti valori distinti rispetto al numero di righe, così che il traffico si distribuisca uniformemente. (Più pattern in single-table design.)

  • Chiave ad alta cardinalità. Una chiave per-utente o per-tenant batte una chiave per-giorno o per-stato che tutti martellano nello stesso momento.
  • Attento alle hot key note. Un valore "torneo corrente" o "oggi" è un rischio di concentrazione prima di spedire, non dopo.
  • Fai lo shard della hot key inevitabile. Quando una chiave deve prendere traffico sproporzionato, un suffisso è la via di fuga standard.

Il throttling con capacità da vendere è il tuo segnale che una partizione è calda. Ispeziona gli item incriminati e prova un layout di chiave a shard in DynoTable — puntalo alla tua tabella, trova la chiave sovraccarica e modella la soluzione prima che ti svegli di notte.

Aggiornato