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

Una guida per comprendere i modelli di ridimensionamento del database

Ci sono molti articoli online che descrivono i modelli di scalabilità del database, ma sono per lo più articoli sparsi, solo tecniche definite a casaccio senza molto contesto. Trovo che non siano definiti in modo graduale e non discutono quando scegliere quale opzione di ridimensionamento, quali opzioni di ridimensionamento sono fattibili nella pratica e perché.

Pertanto, ho intenzione di discutere alcune delle tecniche in dettaglio in articoli futuri. Per iniziare, sento che è meglio se discuto le tecniche passo passo con un contesto a modo mio. Questo articolo è un articolo di alto livello:non discuterò le tecniche di ridimensionamento in dettaglio qui, ma fornirò una panoramica. Allora iniziamo.

Un caso di studio

Supponiamo di aver creato una startup che offre la condivisione di corse a un costo economico. Inizialmente, quando inizi, ti rivolgi a una città e difficilmente avrai decine di clienti dopo la tua pubblicità iniziale.

Salvi tutti i clienti, i viaggi, le posizioni, i dati delle prenotazioni e la cronologia dei viaggi dei clienti nello stesso database o molto probabilmente in un'unica macchina fisica. Non esiste una cache di fantasia o una pipeline di big data per risolvere i problemi poiché la tua app è molto nuova. Questo è perfetto per il tuo caso d'uso in questo momento poiché ci sono pochissimi clienti e il tuo sistema difficilmente prenota 1 viaggio in 5 minuti, ad esempio.

Ma col passare del tempo, sempre più persone iniziano a registrarsi nel tuo sistema poiché sei il servizio più economico sul mercato e grazie alla tua promozione e ai tuoi annunci. Inizi a prenotare, diciamo, 10 prenotazioni al minuto e lentamente il numero aumenta a 20, 30 prenotazioni al minuto.

A questo punto, ti rendi conto che il sistema ha iniziato a funzionare male:la latenza dell'API è aumentata molto e alcune transazioni si bloccano o muoiono di fame e alla fine falliscono. La tua app sta impiegando più tempo per rispondere, causando insoddisfazione dei clienti. Cosa puoi fare per risolvere il problema?

Modello 1 - Ottimizzazione delle query e implementazione del pool di connessioni:

La prima soluzione che viene in mente è che la cache utilizza spesso dati non dinamici come cronologia delle prenotazioni, cronologia dei pagamenti, profili utente e così via. Ma dopo questa memorizzazione nella cache del livello dell'applicazione, non è possibile risolvere il problema di latenza delle API che espongono dati dinamici come la posizione dell'autista corrente o i taxi più vicini per un determinato cliente o il costo del viaggio corrente in un determinato momento dopo l'inizio del viaggio.

Identifichi che il tuo database è probabilmente fortemente normalizzato, quindi introduci alcune colonne ridondanti (queste colonne appaiono spesso in WHERE o JOIN ON clausola nelle query) in tabelle molto utilizzate per motivi di denormalizzazione. Ciò riduce le query di join, suddivide una query di grandi dimensioni in più query più piccole e ne aggiunge i risultati nel livello dell'applicazione.

Un'altra ottimizzazione parallela che puoi fare è modificare le connessioni del database. Le librerie client del database e le librerie esterne sono disponibili in quasi tutti i linguaggi di programmazione. È possibile utilizzare le librerie del pool di connessioni per memorizzare nella cache le connessioni al database o configurare le dimensioni del pool di connessioni nel sistema di gestione del database stesso.

La creazione di qualsiasi connessione di rete è costosa poiché richiede una comunicazione avanti e indietro tra client e server. Il raggruppamento delle connessioni può aiutarti a ottimizzare il numero di connessioni. Le librerie di pool di connessioni possono aiutarti a multiplexare le connessioni:più thread di applicazioni possono utilizzare la stessa connessione al database. Vedrò se riesco a spiegare in dettaglio il pool di connessioni in un articolo separato più avanti.

Misura la latenza delle tue API e trova probabilmente una latenza ridotta del 20–50% o più. Questa è una buona ottimizzazione in questo momento.

Ora hai ridimensionato la tua attività a un'altra città, più clienti si registrano, inizi lentamente a fare 80-100 prenotazioni al minuto. Il tuo sistema non è in grado di gestire questa scala. Ancora una volta, vedi che la latenza dell'API è aumentata, il livello di database si è arreso, ma questa volta nessuna ottimizzazione delle query ti offre un aumento significativo delle prestazioni. Controlli la metrica di sistema, scopri che lo spazio su disco è quasi pieno, la CPU è occupata l'80% delle volte, la RAM si riempie molto rapidamente.

Motivo 2 - Ridimensionamento verticale o aumento:

Dopo aver esaminato tutte le metriche di sistema, sai che non esiste un'altra soluzione semplice piuttosto che aggiornare l'hardware del sistema. Si aggiorna la dimensione della RAM di 2 volte, si aggiorna lo spazio su disco, diciamo, 3 volte o più. Questo è chiamato ridimensionamento verticale o ridimensionamento del sistema. Informa il tuo team dell'infrastruttura o il team di devops o gli agenti di data center di terze parti per aggiornare la tua macchina.

Ma come si imposta la macchina per il ridimensionamento verticale?

Assegni una macchina più grande. Un approccio non consiste nel migrare i dati manualmente dalla vecchia macchina, ma impostare la nuova macchina come replica alla macchina esistente (primary )-crea una primary replica temporanea configurazione. Lascia che la replica avvenga naturalmente. Una volta completata la replica, promuovi la nuova macchina a primaria e metti offline la macchina precedente. Poiché la macchina più grande dovrebbe soddisfare tutte le richieste, tutte le operazioni di lettura/scrittura avverranno su questa macchina.

Freddo. Il tuo sistema è di nuovo attivo e funzionante con prestazioni migliorate.

La tua attività sta andando molto bene e decidi di scalare in altre 3 città:ora sei operativo in 5 città in totale. Il traffico è 3 volte maggiore rispetto a prima, ci si aspetta che effettui circa 300 prenotazioni al minuto. Prima ancora di raggiungere questo obiettivo di prenotazione, si verifica nuovamente la crisi delle prestazioni, la dimensione dell'indice del database sta aumentando notevolmente nella memoria, necessita di una manutenzione costante, la scansione delle tabelle con l'indice sta diventando più lenta che mai. Calcoli il costo per aumentare ulteriormente la macchina ma non sei convinto del costo. Cosa fai adesso?

Pattern 3 - Command Query Responsibility Segregation (CQRS):

Identifichi che la grande macchina non è in grado di gestire tutti i read/write richieste. Inoltre, nella maggior parte dei casi, qualsiasi azienda necessita di capacità transazionali su write ma non su read operazioni. Stai anche bene con un po' di read incoerente o ritardata operazioni e la tua azienda non hanno problemi neanche con questo. Vedi un'opportunità in cui potrebbe essere una buona opzione separare la read &write operazioni fisico macchina saggia. Creerà spazio per le singole macchine per gestire più read/write operazioni.

Ora prendi altre due macchine grandi e le configuri come replica alla macchina attuale. La replica del database si occuperà della distribuzione dei dati da primary macchina su replica macchine. Puoi navigare in tutte le query di lettura (Query (Q ) in CQRS ) alle repliche — qualsiasi replica può servire qualsiasi richiesta di lettura, navighi in tutte le query di scrittura (Comando (C ) in CQRS ) al primary . Potrebbe esserci un piccolo ritardo nella replica, ma secondo il tuo caso d'uso aziendale va bene.

La maggior parte delle startup di media scala che soddisfano poche centinaia di migliaia di richieste ogni giorno possono sopravvivere con la configurazione della replica primaria a condizione che archivino periodicamente i dati meno recenti.

Ora ridimensioni ad altre 2 città, vedi che il tuo primary non è in grado di gestire tutte le write richieste. Molti write le richieste sono in latenza. Inoltre, il ritardo tra primary &replica a volte hanno un impatto su clienti e conducenti ex:al termine del viaggio, il cliente paga l'autista con successo, ma l'autista non è in grado di vedere il pagamento poiché l'attività del cliente è una write richiesta che va al primary , mentre l'attività del conducente è una read richiesta che va a una delle repliche. Il tuo sistema generale è così lento che il conducente non è in grado di vedere il pagamento per almeno mezzo minuto, frustrante sia per il conducente che per il cliente. Come lo risolvi?

Modello 4 - Replica primaria multipla

Hai scalato molto bene con primary-replica configurazione, ma ora sono necessarie maggiori prestazioni di scrittura. Potresti essere pronto a scendere a compromessi su read richiedere prestazioni. Perché non distribuire la richiesta di scrittura a una replica anche?

In un multi-primary configurazione, tutte le macchine possono funzionare sia come primary &replica . Puoi pensare a multi-primary come un cerchio di macchine dice A->B->C->D->A . B può replicare i dati da A , C può replicare i dati da B , D può replicare i dati da C , A può replicare i dati da D . Puoi scrivere dati su qualsiasi nodo, mentre leggi i dati, puoi trasmettere la query a tutti i nodi, chiunque risponda lo restituirà. Tutti i nodi avranno lo stesso schema del database, lo stesso set di tabelle, indice ecc. Quindi devi assicurarti che non ci siano collisioni in id tra nodi nella stessa tabella, altrimenti durante la trasmissione, più nodi restituirebbero dati diversi per lo stesso id .

In genere è meglio usare UUID o GUID per id. Un altro svantaggio di questa tecnica è — read le query potrebbero essere inefficienti poiché implicano la trasmissione di query e l'ottenimento del risultato corretto, in pratica un approccio di raccolta a dispersione.

Ora ridimensioni ad altre 5 città e il tuo sistema è di nuovo in difficoltà. Si prevede di gestire circa 50 richieste al secondo. Hai un disperato bisogno di gestire un numero elevato di richieste simultanee. Come ci riesci?

Modello 5 - Partizionamento:

Sai che la tua location il database è qualcosa che sta diventando alto write &read traffico. Probabilmente write:read il rapporto è 7:3 . Questo sta mettendo molta pressione sui database esistenti. La location le tabelle contengono pochi dati primari come longitude , latitude , timestamp , driver id , trip id ecc. Non ha molto a che fare con i viaggi degli utenti, i dati degli utenti, i dati di pagamento ecc. Che ne dici di separare la location tabelle in uno schema di database separato? Che ne dici di inserire quel database in macchine separate con la corretta primary-replica o multi-primary configurazione?

Questo è chiamato partizionamento dei dati per funzionalità. Database diversi possono ospitare dati classificati in base a funzionalità diverse, se necessario il risultato può essere aggregato nel livello back-end. Usando questa tecnica, puoi concentrarti sul ridimensionamento di quelle funzionalità che richiedono read/write elevate richieste. Sebbene il back-end o il livello dell'applicazione debba assumersi la responsabilità di unire i risultati quando necessario, risultando probabilmente in più modifiche al codice.

Ora immagina di aver ampliato la tua attività a un totale di 20 città nel tuo paese e di pianificare di espanderti presto in Australia. La tua crescente domanda di app richiede una risposta sempre più rapida. Nessuno dei metodi di cui sopra può aiutarti all'estremo ora. È necessario ridimensionare il sistema in modo tale che l'espansione in altri paesi/regioni non richieda sempre modifiche frequenti di progettazione o architettura. Come fai?

Motivo 6 - Ridimensionamento orizzontale:

Cerchi molto su Google, leggi molto su come altre aziende hanno risolto il problema e arrivi alla conclusione che devi ridimensionare orizzontalmente. Assegni diciamo 50 macchine:tutte hanno lo stesso schema di database che a sua volta contiene lo stesso set di tabelle. Tutte le macchine contengono solo una parte dei dati.

Poiché tutti i database contengono lo stesso set di tabelle, è possibile progettare il sistema in modo tale che la località dei dati sia presente, ad es. tutti i dati correlati atterrano nella stessa macchina. Ogni macchina può avere le proprie repliche, le repliche possono essere utilizzate nel ripristino degli errori. Ciascuno dei database è chiamato shards . Una macchina fisica può avere uno o più shards — sta al tuo design come vuoi. Devi decidere su sharding key in modo tale che una singola sharding key si riferisce sempre alla stessa macchina. Quindi puoi immaginare molte macchine che contengono tutti dati correlati nello stesso insieme di tabelle, read/write le richieste per la stessa riga o lo stesso insieme di risorse si trovano nella stessa macchina del database.

Lo sharding è in generale difficile, almeno lo dicono gli ingegneri di diverse aziende. Ma quando servi milioni o miliardi di richieste, devi prendere una decisione così difficile.

Parlerò del sharding in modo più dettagliato nel mio prossimo post, trattenendo così la mia tentazione di discutere di più in questo post.

Ora, dal momento che hai lo sharding attivo, sei sicuro di poter scalare in molti paesi. La tua attività è cresciuta così tanto che gli investitori ti stanno spingendo a scalare il business attraverso i continenti. Vedi di nuovo qualche problema qui. Di nuovo la latenza dell'API. Il tuo servizio è ospitato negli Stati Uniti e le persone dal Vietnam hanno difficoltà a prenotare viaggi. Come mai? Cosa fai al riguardo?

Modello 7 - Partizione Wise data center:

La tua attività sta crescendo in America, Asia meridionale e in alcuni paesi in Europa. Stai effettuando milioni di prenotazioni ogni giorno con miliardi di richieste che colpiscono il tuo server. Congratulazioni:questo è un momento di punta per la tua attività.

Ma poiché le richieste dell'app devono viaggiare attraverso i continenti attraverso centinaia o migliaia di server in Internet, sorge la latenza. Che dire della distribuzione del traffico tra i data center? È possibile configurare un data center a Singapore che gestisca tutte le richieste dall'Asia meridionale, un data center in Germania può gestire tutte le richieste dai paesi europei e un data center in California può gestire tutte le richieste degli Stati Uniti.

Inoltre, abiliti la replica tra data center che aiuta il ripristino di emergenza. Pertanto, se il data center della California esegue la replica al data center di Singapore, nel caso in cui il data center della California si interrompa a causa di problemi di elettricità o calamità naturali, tutte le richieste degli Stati Uniti possono tornare al data center di Singapore e così via.

Questa tecnica di ridimensionamento è utile quando hai milioni di clienti da servire in tutti i paesi e non puoi far fronte a alcuna perdita di dati, devi mantenere sempre la disponibilità del sistema.

Queste sono alcune tecniche generali passo passo per il ridimensionamento del database. Sebbene la maggior parte degli ingegneri non abbia abbastanza possibilità per implementare queste tecniche, nel complesso è meglio avere un'idea più ampia su tale sistema che in futuro potrebbe aiutarti a fare una migliore progettazione di sistemi e architetture.

Nei miei prossimi articoli, cercherò di discutere in dettaglio alcuni concetti. Non esitare a fornire un feedback appropriato per questo post, se presente.

L'articolo è stato originariamente pubblicato sull'account medio dell'autore:https://medium.com/@kousiknath/understanding-database-scaling-patterns-ac24e5223522