Mysql
 sql >> Database >  >> RDS >> Mysql

PlanetScale &Vitess:integrità referenziale con database frammentati legacy

Amo la tecnologia serverless. Gioco e creo molte diverse applicazioni serverless per sperimentare altre fantastiche tecnologie. All'interno dell'enorme gruppo di tecnologie con cui utilizzo/sperimento, PlanetScale era il database che ho utilizzato principalmente per i miei progetti collaterali personali, poiché non c'era nessun'altra opzione "buona" supportata da Prisma ORM .

PlanetScale è una piattaforma serverless MySQL che vende semplicemente Vitess, un sistema di clustering di database per il ridimensionamento orizzontale di MySQL. Non hanno scritto il proprio database, forse vi hanno contribuito, ma non lo hanno scritto. Dalla documentazione Vitess:

Vitess è stato creato nel 2010 per risolvere le sfide di scalabilità MySQL che il team di YouTube ha dovuto affrontare.

In questo articolo, ci sposteremo verso la comprensione della struttura di questi database partizionati legacy non ACID, perché non sono in grado di supportare qualcosa di così cruciale come l'integrità referenziale e perché dovremmo evitare di usarli nelle nostre applicazioni. Questo articolo è più sulla tecnologia di Vitess, anche se ho incluso PlanetScale nel titolo perché, come ho detto sopra, sta solo vendendo Vitess (con alcuni strumenti) come servizio e hanno guadagnato popolarità nei mesi successivi come un database serverless "affidabile".

Sfondo

La mia domanda iniziale era perché dice che è impossibile ridimensionare un database PlanetScale con integrità referenziale poiché nella loro documentazione afferma che:

La via FOREIGN KEY i vincoli sono implementati in MySQL (o, meglio, nel motore di archiviazione InnoDB) interferisce con le operazioni DDL online. Scopri di più in questo post del blog Vitess.

Limitato a un singolo ambito del server MySQL, FOREIGN KEY i vincoli sono impossibili da mantenere una volta che i dati crescono e vengono suddivisi su più server di database. Ciò si verifica in genere quando si introduce il partizionamento/sharding funzionale e/o lo sharding orizzontale.

Questo mi ha portato a pensare:fai FOREIGN KEY i vincoli influiscono sulla scalabilità in generale? e se sì, come?

Penso che sia importante rendersi conto che i join di tabelle SQL sono piuttosto costosi, ma per quanto ne so non è stato influenzato molto dall'integrità referenziale? Ora, se stiamo facendo qualcosa come l'analisi dei dati, ovviamente non abbiamo bisogno dell'integrità referenziale perché vorremmo semplicemente scaricare i nostri dati in un'unica tabella, ma PlanetScale e Vitess si vantano di essere utilizzati da grandi applicazioni web come YouTube.

Questo mi ha portato a essere confuso sul motivo per cui avrebbero abbandonato la FOREIGN KEY vincolo in quanto database come CockroachDB e Spanner mantengono ancora l'integrità referenziale oltre ad essere scalabili.

Che cos'è l'integrità referenziale e perché è importante?

Cominciamo con le basi, nel caso tu sia nuovo. Immagino che la maggior parte delle persone che leggono questo post abbiano una buona idea di cosa stanno parlando, ma lo spiegherò come formalità. In parole semplici, una FOREIGN KEY vincolo è una chiave di database che possiamo utilizzare per creare relazioni tra due tabelle diverse facendo riferimento a una colonna o a un insieme di colonne. L'integrità referenziale si riferisce semplicemente allo stato del database in cui sono validi tutti i valori di tutte le chiavi.

Perché è importante?

Ora che abbiamo un'idea di cosa sono, passiamo alla seconda parte:perché sono importanti?

L'integrità referenziale è importante in quanto impedisce di introdurre nuovi errori nel database. È una funzionalità spesso fornita dai database relazionali che impedisce agli utenti o alle applicazioni di inserire dati incoerenti nel database. Ciò porta a una migliore qualità dei dati, uno sviluppo più rapido, un numero molto inferiore di bug e una coerenza nell'applicazione.

Perché Vitess non ce l'ha?

Quindi, per capire perché Vitess non è in grado di supportare l'integrità referenziale, dobbiamo fare un tuffo nell'architettura del database. Vitess è un database SQL non ACID frammentato, non un vero database SQL ACID distribuito.

Ora, ti starai chiedendo quali siano questi termini. Lascia che te li spieghi:ACID è l'acronimo di Atomicity, Consistency, Isolation e Durability.

Qui, l'atomicità si riferisce a un'azione che completa o non riesce completamente, nessun completamento parziale di una transazione. La coerenza si riferisce alla transazione che lascia il database in uno stato valido. L'isolamento significa semplicemente che due transazioni vengono eseguite senza alcuna interferenza l'una con l'altra e la durata significa che le modifiche della transazione vengono salvate.

Uno shard è una partizione orizzontale di dati in un database e ogni shard viene conservato su un'istanza del server di database separata per distribuire il carico. Quindi, quando ci riferiamo a un database che è suddiviso in partizioni, stiamo parlando di qualcosa del genere. Ora, come ho detto prima, Vitess è un database SQL non ACID frammentato, il che sostanzialmente significa che NON garantisce le proprietà ACID delle transazioni.

Perché lasciarlo cadere?

Bene, il problema inizia quando hai un database MySQL con uno schema ben definito e il tuo servizio diventa popolare con il problema di troppe letture che colpiscono il database. Quello che la maggior parte delle persone fa qui è iniziare a memorizzare nella cache le query eseguite di frequente, ma le letture non sono più ACIDic.

Insieme a troppe letture, avere una quantità eccessiva di scritture sul database è un problema serio che molti potrebbero dover affrontare. Diciamo che siamo pronti a dare fuoco alle nostre tasche:possiamo scalare verticalmente, aggiungendo più RAM, un processore a 16 core e un sacco di unità a stato solido davvero veloci.

Ovviamente abbiamo ancora il problema dei join di tabelle SQL che aumentano in complessità, quindi inizi a denormalizzare per evitare i join tra tabelle.

Tempo fa ho tenuto una conferenza al Prisma Meetup, dove ho spiegato i fondamenti della progettazione di un database relazionale. Un argomento che ho trattato qui è stata la denormalizzazione, se sei interessato, assicurati di dare un'occhiata.

Ma la denormalizzazione è fondamentalmente il processo in cui si aggiungono dati ridondanti alle tabelle nel database, il che migliora le prestazioni sul costo dello spazio su disco poiché non si utilizza più la potenza della CPU per i join. Sebbene la denormalizzazione migliori la velocità di lettura, è importante rendersi conto che rende le scritture più lente.

Tuttavia, nonostante tutto ciò, il nostro database è ancora lento, quindi spostiamo i calcoli del database sul client, ad esempio generando un UUID o assegnando una data.

Anche dopo tutto questo, le query saranno ancora lente, quindi manteniamo pronto il risultato dei dati più richiesti in un processo noto come materializzazione del database. Ora le letture potrebbero essere più veloci, ma le scritture stanno diventando più lente di giorno in giorno. L'unica situazione logica ora è eliminare gli indici secondari.

Quindi, a questo punto, il nostro database ha

  • Nessuna proprietà ACID a causa della memorizzazione nella cache
  • Nessuno schema normalizzato
  • Nessun trigger
  • Nessun calcolo del database
  • Nessun indice secondario

Ciò ha aperto la strada ai database Vitess e NoSQL, poiché le aziende avevano problemi con il ridimensionamento del proprio database. Il modo in cui è stato progettato, non sono stati in grado di mantenere la coerenza dei dati, una proprietà ACID, quando le transazioni si estendevano su diversi shard. L'integrità referenziale è tutta una questione di coerenza quando i dati si estendono su più shard, quindi ha senso che non siano in grado di supportarla bene.

Possiamo approfondire la struttura dei database NoSQL senza FOREIGN KEY vincolo e problemi che dovremo affrontare adottando quel modello, ma questo è l'argomento di un altro post.

Non è solo Vitess, è stata una pratica standard per i database partizionati evitare l'integrità referenziale poiché semplicemente non c'è altra scelta. In termini di modello ACID, la loro documentazione afferma che garantiscono l'atomicità ma non l'isolamento, e arrivano addirittura a dire:

Garantire l'isolamento dell'ACID è molto controverso e ha costi elevati. Fornirlo per impostazione predefinita avrebbe reso Vitess impraticabile per i casi d'uso più comuni.

Parliamo brevemente di cos'è l'isolamento ACID. Esistono quattro livelli (secondo gli standard SQL-92), tra cui serializzabilità, lettura con commit, lettura senza commit e letture ripetibili. Detto questo, ci sono più livelli di isolamento, come l'isolamento Snapshot che non è uno standard SQL sebbene utilizzato da diversi database come Firebase o MongoDB. Se sei ulteriormente interessato a questo, ti consiglio di leggere questo post. Per essere breve, non esaminerò cosa significa/significa ogni livello di isolamento, ma se desideri saperne di più, dai un'occhiata a questa pagina della documentazione MySQL.

L'isolamento ACID si riferisce al fatto che le transazioni del database sono ACIDic, il che è importante in quanto garantiscono che le operazioni si comportino nel modo in cui gli sviluppatori si aspettano che facciano. Non sono sicuro di cosa intendono quando dicono "Garantire l'isolamento dell'ACID è molto controverso e ha costi elevati", ma se significano che garantire l'isolamento dell'ACID ha costi elevati per qualsiasi prodotto , hanno torto. Diversi database distribuiti conformi ad ACID hanno il più alto livello di isolamento (transazioni serializzabili) pur mantenendo prestazioni elevate con velocità di lettura/scrittura elevate. Nel contesto di Vitess, tuttavia, non hanno torto poiché le transazioni su più shard non possono soddisfare alcun livello di isolamento.

Conclusione

Con tutto questo, ti starai chiedendo:perché qualcuno dovrebbe voler usare PlanetScale o Vitess? Beh, mi chiedo lo stesso. Con molte aziende e siti Web, il motivo era che hanno scelto Vitess quando non c'erano opzioni migliori. Se vai all'inizio dell'articolo, nota come è stato creato nel 2010. Ora che possiamo godere di un database scalabile conforme ad ACID con integrità referenziale, sarebbe nel nostro migliore interesse passare a questi nuovi database, e io ho già iniziato a farlo! La tecnologia cambia rapidamente e mantenere il database aggiornato è un componente cruciale di qualsiasi applicazione.