Intermedio8 min di lettura

Elementi singleton in DynamoDB

Un elemento singleton è una singola riga con una chiave fissa e codificata che mantiene state per l'intera applicazione: non un record per utente o per ordine, ma un record, punto. Flag di funzionalità, un blob di configurazione, un kill switch globale: il tipo di cose che un'app relazionale manterrebbe in una tabella delle impostazioni su una riga.

Provenendo da SQL, otterresti una tabella config con id = 1 e SELECT * FROM config. In DynamoDB fai la stessa cosa con una partizione hardcoded key - e poiché conosci sempre quella chiave, la leggi con un GetItem, non un Query o un Scan.

Cos'è un elemento singleton in DynamoDB?

Un elemento singleton è una singola riga DynamoDB memorizzata sotto una chiave fissa e codificata che mantiene lo stato globale per l'intera applicazione (flag di funzionalità, un BLOB di configurazione, una versione a livello di sistema) anziché un record per utente o ordine. Poiché conosci sempre la chiave, la leggi con GetItem e la aggiorni conpiù espressioni di condizione.

  • Un singleton è un elemento con una chiave costante. Puoi codificare PK/SK nel tuo codice (ad esempio CONFIG#GLOBAL) invece di inserire un modello in un ID utente o ordine.
  • Leggilo con GetItem, mai con Scan. Conosci sempre la chiave completa, quindi la lettura del punto ha un costo fisso e prevedibile (al massimo 1 RCU per un oggetto piccolo) - nessun filtro, nessuna passeggiata sul tabella.
  • È unper definizione. Ogni richiesta può toccare la stessa partizione, quindi memorizzalo nella cache e mantieni l'oggetto piccolo; non renderlo un collo di bottiglia in scrittura.
  • Mutalo in modo sicuro con le espressioni di aggiornamento + condizione, non lettura-modifica-scrittura nella tua app: è lì che vive la corsa agli aggiornamenti perduti.

Riconosci lo schema

Hai uno stato globale quando i dati non hanno come ambito alcuna entità. Alcuni raccontano:

  • Un flag uguale per tutti (signup_enabled = false).
  • Un insieme di parametri sintonizzabili letti dall'app all'avvio (limiti di velocità, quote predefinite).
  • Un contatore o un numero di versione per l'intero sistema, non per riga.

Tutto ciò che ha come ambito un utente, un tenant o un ordine non è un singleton: è un elemento ordinario identificato dall'ID di quell'entità. Il singleton è il globale rimanente fetta che non ha nessun altro posto dove vivere.

Dategli una chiave costante

L’intero modello dipende da una decisione. La chiave è letterale, non un modello. Per un elemento flag di funzionalità globale in una singola tabella sovraccarica, scegli un valore fisso prefisso e un valore fisso:

PKSKattributes
SETTINGS#APPFLAGS#V1signup_enabled, maintenance_mode, ai_search_enabled

PK = "SETTINGS#APP" e SK = "FLAGS#V1" sono integrati nel codice. Non c'è ID utente, nessun ID tenant: l'applicazione richiede ogni volta esattamente questo elemento. Il punto è questa prevedibilità: una chiave nota è "GetItem" e "GetItem" è la lettura più economica e coerente offerta da DynamoDB.

Il suffisso "V1" è intenzionale. Se lo schema del flag cambia forma in seguito, scrivi un elemento FLAGS#V2 e capovolgi i lettori, invece di trasformare quello live in posto. Il controllo delle versioni della chiave singleton ti consente di ottenere un passaggio di migrazione pulito.

Leggilo con GetItem

Poiché la chiave è completamente nota, non si usa mai Query e mai Scan per un singleton. Un Scan legge l'intera tabella e filtra lato client: il classico Scan footgun - ed è assurdamente eccessivo per il recupero una riga che puoi indirizzare direttamente.

Un GetItem contro SETTINGS#APP / FLAGS#V1 restituisce i flag in un unico lettura fortemente o eventualmente coerente. Su richiesta in us-east-1, AWS fattura a GetItem di un elemento ≤ 4 KB come 0,5 RCU eventualmente coerente o 1 RCU fortemente coerente (AWS documenti sulla capacità di lettura/scrittura). Mantieni il singleton piccolo e il costo rimarrà invariato per sempre, gonfiando la configurazione blob in un secondo blocco da 4 KB raddoppia la lettura fatturata.

Nel percorso di lettura, quando l'app si avvia o arriva una richiesta, GetItem il valore corretto chiave, si memorizza nella cache il risultato. Il flusso:

noApp/richiestaGetItem PK=IMPOSTAZIONI#APPSK=BANDIERE#V1Item found?Utilizza flag, memorizza nellacache localmenteRitorno alle impostazionipredefinite sicure

La chiave fissa trasforma una ricerca globale in un punto letto con un percorso predefinito integrato.

Nota il ramo no: un singleton mancante non dovrebbe mai mandarti in crash. Predefinito per valore sicuro (funzione disattivata, manutenzione attivata), quindi un gap di prima implementazione o un difetto la chiave non riesce a chiudersi, non ad aprirsi.

Aggiornalo senza gara

La trappola sta aggiornando un singleton con lettura-modifica-scrittura nella tua app: tu GetItem le bandiere, girane una in memoria, poi PutItem tutto indietro. Due scrittori simultanei leggono entrambi il vecchio articolo e il secondo "Put" lo rovina il primo cambiamento. Aggiornamento perso.

Due funzionalità DynamoDB uccidono la gara senza blocco lato app:

- muta un attributo lato server, lasciando il resto intatto. Non è necessario riposizionare l'intero articolo. - fai in modo che la scrittura abbia esito positivo solo se l'elemento appare ancora nel modo previsto, quindi una scrittura obsoleta viene rifiutata "ConditionalCheckFailedException". (AWS documenti sull'espressione della condizione).

Per girare una bandiera, seleziona solo quell'attributo con un "SET" e proteggilo con un aumento della versione in modo che gli scrittori simultanei non possano calpestarsi a vicenda:

# UpdateItem
Key                  PK=SETTINGS#APP  SK=FLAGS#V1
UpdateExpression     SET signup_enabled = :on, schema_version = :next
ConditionExpression  schema_version = :current

Se due scrittori gareggiano, il controllo schema_version = :current del secondo fallisce e riprova con il nuovo valore. Puoi impalcare i nomi, i valori e questa esatta forma di espressione nel DynamoDB Expression Builder prima del cablaggio in codice. Per uno sguardo più approfondito agli operatori, vedere il Guida agli idiomi di aggiornamento-espressione.

Attenzione ai tasti di scelta rapida

Un singleton è, per costruzione, un tasto di scelta rapida: ogni parte della tua app può leggere la stessa partizione. Va bene per le letture se si memorizza nella cache, ma è quello reale rischio del modello.

  • Meche in cache in modo aggressivo. Leggi i flag una volta per processo (o per N secondi), no su ogni richiesta. Il valore del singleton è la cosa più economica da memorizzare.
  • Non renderlo un hot spot di scrittura. Un flag attivato da un amministratore alcune volte al giorno non è niente. Un singleton che incrementi ad ogni richiesta è un throughput della partizione collo di bottiglia: è un controproblema, non un singleton.
  • Mantienilo piccolo. Leggi le scale di costo con le dimensioni degli articoli in blocchi da 4 KB. Un gonfio config blob rende ogni avvio più costoso del necessario.

Se hai veramente bisogno di un contatore globale ad alta scrittura, il singleton è sbagliato forma: suddividelo su N elementi e sommalo in lettura. Questo è uno schema diverso.

Elemento singleton e per entità

La riga è semplicemente l'ambito dei dati.

Elemento singletonVoce per entità
ChiaveCostante hardcoded (SETTINGS#APP)Basato su un modello con un ID (USER#42)
QuantiEsattamente unoUno per utente/ordine/locatario
Lettura tipicaGetItem sulla chiave conosciutaGetItem o Query per entità
AmbitoIntera applicazioneUn'unica entità
Utilizzare perFlag globali, configurazione, versione del sistemaProfili, ordini, qualsiasi cosa per-id

Se ti ritrovi a desiderare due single dello stesso tipo, non ne hai uno singleton: hai un elemento per entità e l'entità è la cosa che ti sei dimenticato di fare chiave per (configurazione per tenant, ad esempio).

Insidie e passaggi successivi

  • Non Scan per questo. Conosci la chiave; affrontarlo direttamente.
  • Non leggerlo-modificarlo-scriverlo. Utilizza espressioni aggiornamento + condizione.
  • Non lasciarlo perdere silenziosamente. Il valore predefinito è sicuro in caso di mancato ritrovamento della cache.
  • Non sovraccaricarlo con scritture ad alta frequenza. È un lavoro di contatore frammentato.

Il singleton vive comodamente all'interno di a design a tabella singola: è solo un altro elemento raccolta con una chiave fissa accanto alle righe dell'entità.

Prova DynoTable per sfogliare la tabella, trova la riga singleton in base alla sua chiave fissa e modifica i flag manualmente mentre crei il percorso di scrittura.

Aggiornato