Gestione degli schemi con Skeema

Pubblicato: 2019-04-26

Nota: questo post proviene dal team di ingegneri di SendGrid. Per altri post di ingegneria tecnica come questo, dai un'occhiata al nostro blogroll tecnico.

La gestione dello schema del database spazia da un selvaggio west che chiunque può "farlo dal vivo" nel processo di produzione a un processo di revisione multi-team a cascata in cui solo un individuo unto può toccare il database di produzione.

Man mano che i dati contenuti nei database relazionali diventano più preziosi per un'azienda e la disponibilità del database diventa più importante per l'azienda, emergono ostacoli a potenziali modifiche dello schema di rottura.

All'inizio, gli amministratori di database (DBA) sono diventati i guardiani del database al fine di proteggere il database da eventi negativi. Ma avere un DBA vecchio stile tra gli sviluppatori e il database delle loro applicazioni può causare un rallentamento significativo nel ciclo di vita di sviluppo di un'applicazione, creare silos di sviluppo e operazioni e generare attrito tra i team.

Nel mondo odierno orientato allo sviluppo di microservizi, gli sviluppatori devono essere in grado di gestire autonomamente le modifiche allo schema del database perché si tratta dei loro dati e sono in definitiva responsabili delle prestazioni e del tempo di attività dell'applicazione. I DBA e i team operativi devono fornire strumenti e consigli appropriati per aiutare i team di sviluppo a diventare i proprietari del loro database.

Come gestiamo lo schema

Il nostro attuale processo di gestione dello schema utilizza un unico repository Git per archiviare lo schema iniziale per tutti i nostri cluster di database e contiene tutte le modifiche successive a quello schema quando vengono applicate modifiche/creazioni e rilasci di singole tabelle:

  • Uno sviluppatore apporta una modifica allo schema in locale e genera un'istruzione alter/create/drop e la aggiunge come richiesta pull a un ramo di integrazione.
  • Viene creato un set di ticket Jira per il team Data Operations per esaminare e applicare le modifiche dello schema ai nostri ambienti di test/staging e produzione.
  • Un membro del team Data Operations esamina la modifica richiesta e applica la modifica all'ambiente di test/staging e unisce la PR al ramo di integrazione.
  • Lo sviluppatore richiedente verifica la modifica nei nostri ambienti di test/staging e approva che la modifica venga trasferita in produzione.
  • Infine, Data Operations unisce il ramo di integrazione al master e applica la modifica dello schema all'ambiente di produzione.

Dato il valore dei dati archiviati nei nostri database e il desiderio di avere quei database sempre attivi e funzionanti, abbiamo optato per questa sequenza bizantina di eventi per proteggerci da noi stessi.

La protezione del database è una cosa, ma questo processo introduce diversi ostacoli per apportare modifiche allo schema in modo affidabile ed efficiente:

  • La revisione e le modifiche allo schema avvengono con cadenza bisettimanale e possono essere facilmente deragliate poiché più team lavorano su database diversi nello stesso repository Git e tutti fanno affidamento su qualcuno del team Data Operations per rivedere e apportare modifiche a vari ambienti.
  • Avere un repository per tutti gli schemi di database relazionali può portare a processi di rilascio complessi. Una modifica a uno schema pronto per la produzione non può passare alla produzione se sono presenti altre modifiche allo schema che non sono pronte per essere inviate alla produzione ma sono in fase di staging in attesa di ulteriori test.
  • Il team Data Operations, che è un piccolo team, diventa un collo di bottiglia nel tentativo di gestire quale cambiamento può e non può andare in produzione e quando. La pianificazione dei conflitti e la disponibilità del personale possono davvero rallentare il rilascio di nuove funzionalità o correzioni alle applicazioni correnti.
  • Stiamo applicando manualmente queste modifiche ai sistemi di produzione utilizzando i commenti nelle richieste pull e nei ticket Jira; a volte il copia incolla può andare terribilmente storto.

Entra Skeema (e alcuni aiutanti)

Al fine di rimuovere questi ostacoli al processo, rendere le modifiche allo schema meno soggette a errori umani, consentire agli sviluppatori di gestire lo schema della propria applicazione e potenzialmente aumentare la velocità di sviluppo, il team di Data Operations ha compiuto grandi sforzi per automatizzare e semplificare la gestione di schema del database.

Abbiamo automatizzato l'applicazione delle modifiche allo schema dallo sviluppo locale alla produzione utilizzando i nostri strumenti esistenti, Git, Buildkite CI e pt-online-schema-change, con l'aggiunta di un altro, Skeema.

L'idea è di suddividere il nostro repository di schema DB monolitico in repository di schemi individuali, uno per cluster di database, e consentire agli sviluppatori di apportare le proprie modifiche allo schema in un ambiente a loro familiare. Vogliamo anche disporre di barriere sane per aiutare gli sviluppatori a cercare ulteriore assistenza per apportare modifiche agli schemi di grandi dimensioni, complesse o potenzialmente distruttive.

Skeema è uno strumento CLI che gestisce lo schema MySQL in modo dichiarativo utilizzando SQL.

Può generare il linguaggio di definizione dei dati (DDL) per ogni tabella in un database ed esportare il DDL in un file system locale per l'integrazione con un repository di tracciamento tramite Git. Skeema può confrontare i file SQL in un repository Git con un database MySQL attivo e generare tali differenze come istruzioni DDL.

Può anche essere configurato per utilizzare lo strumento pt-online-schema-change di Percona e formattare il comando pt-online-schema-change necessario per far corrispondere lo schema del database MySQL in esecuzione allo schema definito nel repository Git.

Skeema è anche in grado di gestire lo schema in diversi ambienti, come locale, test e produzione con diverse configurazioni in ciascuno. Infine, può essere facilmente adattato a un flusso di lavoro basato su richiesta pull.

La creazione di singoli repository di schemi di database MySQL interromperà il nostro attuale repository Git monolitico db-schema e consentirà agli sviluppatori di team separati di gestire lo schema MySQL della propria applicazione nel proprio repository anziché in un repository condiviso (db-schema).

Avere un repository separato per ogni schema di database consentirà una maggiore autonomia al team di sviluppo dell'applicazione. Ciò elimina la necessità di coordinare tutte le modifiche allo schema in base a una pianificazione rigida e consente di spostare le modifiche in produzione come desidera il team dell'applicazione.

Un componente fondamentale dell'automazione di questo processo è la pipeline CI di Buildkite. Abbiamo creato una pipeline che:

  • Verifica la presenza di errori di sintassi SQL
  • Crea un server MySQL di prova utilizzando il ramo principale corrente dello schema del database e verifica l'applicazione delle modifiche nella richiesta pull (PR)
  • Verifica le differenze e applica le modifiche alle PR al nostro ambiente di test MySQL
  • Verifica le differenze e applica le modifiche PR al nostro ambiente di staging e genera alcune statistiche della tabella dall'ambiente di produzione

Le statistiche sull'output di produzione sono le dimensioni della tabella su disco e il conteggio delle righe stimato. Queste statistiche possono aiutare a determinare se la modifica dello schema potrebbe causare un certo livello di interruzione del servizio e potrebbe richiedere una gestione speciale. Una volta che il PR è stato unito al master, la pipeline buildkite controlla le differenze tra il ramo master e ciò che è in esecuzione in produzione.

Se le differenze sono le modifiche previste dal PR, lo sviluppatore può sbloccare questo passaggio finale e Skeema applica le modifiche al cluster di database MySQL di produzione. Ciascuno di questi passaggi è un passaggio di blocco che richiede l'approvazione del team di progettazione responsabile della modifica richiesta prima di passare al passaggio successivo.

Per quanto riguarda i guardrail, abbiamo configurato Skeema per non consentire modifiche distruttive dello schema in produzione come impostazione predefinita.

Sono consentite modifiche distruttive nei nostri ambienti di test e staging.

Abbiamo anche configurato Skeema per utilizzare pt-online-schema-change per apportare modifiche allo schema. Questo è lo stesso strumento di modifica dello schema con cui il team di DataOps ha familiarità ed è in uso in SendGrid da molti anni. Abbiamo sviluppato una serie di opzioni ragionevoli per pt-online-schema-change per ripristinare le modifiche se la replica rimane indietro o i thread attivi nel database diventano eccessivi.

La configurazione di Skeema in questo modo rimuove i potenziali errori derivanti dalla presenza di passaggi manuali per l'applicazione e la codifica manuale dei comandi pt-online-schema-change da parte dei membri del team di DataOps.

Con l'aggiunta di guardrail programmatici, i singoli team possono essere responsabili della gestione dei propri schemi di database MySQL e dell'applicazione di tali modifiche agli ambienti di pre-produzione e produzione con relativa sicurezza. Se vengono colpiti i guardrail, la modifica dello schema avrà esito negativo e verrà eseguito il rollback. I motivi dell'errore di modifica dello schema vengono visualizzati nei registri di compilazione per un'ulteriore revisione.

Consentire agli sviluppatori di guidare le loro modifiche dal test locale su un laptop alla produzione migliora notevolmente l'autonomia degli sviluppatori e la proprietà del database che supporta la loro applicazione. L'automazione e l'integrazione di Skeema nel nostro processo di gestione del database MySQL copre facilmente circa il novanta percento delle nostre attività generali di gestione delle modifiche allo schema.

La maggior parte delle modifiche allo schema riguarda l'aggiunta di colonne, la modifica dei campi enum, la modifica delle impostazioni predefinite e l'aggiunta di indici. Il restante dieci percento delle modifiche allo schema riguarda casi speciali di tabelle di grandi dimensioni, database molto attivi o tabelle partizionate. A partire da questo post, Skeema non si occupa ancora di apportare modifiche allo schema alle tabelle partizionate, ma ho sentito che è un'aggiunta spesso richiesta e lo sviluppatore di Skeema sta chiedendo attivamente aiuto per implementare quella funzionalità.

La combinazione di Git, pt-online-schema-change, Skeema e una pipeline CI Buildkite offre un processo programmatico affidabile, ripetibile alle modifiche dello schema del database MySQL. Consente agli sviluppatori di gestire in sicurezza lo schema dei loro database e controllare la velocità con cui le funzionalità e le correzioni vengono implementate in produzione.

L'inclusione di guardrail appropriati nei file di configurazione per Skeema e pt-online-schema change, fornisce una misura di fiducia per gli sviluppatori che implementano modifiche allo schema e fornisce un feedback prezioso sui possibili modi per procedere con la modifica dello schema se tali guardrail vengono colpiti.

Il team delle operazioni sui dati rimane disponibile per assistere il restante dieci percento dei casi a cui questo processo non può essere applicato e lavorerà su strumenti aggiuntivi per migliorare questo processo in futuro.