Quali strategie posso utilizzare per ottenere tempi di inattività pari a zero (pianificati) in un'app Web supportata da database?

6

Stavo leggendo Perché sono siti web (anche questo) a volte "Down for Maintenance"? , e mi sono reso conto che il mio settore accetta i tempi di fermo pianificati come dati nonostante l'interruzione del personale e il costo (per lo più nascosto) dell'azienda.

Quali strategie posso utilizzare per ottenere tempi di inattività pari a zero (pianificati) in un'app Web supportata da database? Aggiornamenti specifici che richiedono modifiche dello schema db.

PS Ho pensato di utilizzare un 'livello di astrazione del database' (esiste?), o utilizzare un processo di aggiornamento a due fasi in cui il primo stadio aggiorna lo schema e inizia a usarlo in parallelo al vecchio schema e al secondo stadio ritira il vecchio schema dall'uso? (Qualcuno lo fa? È pazzesco?)

PPS Suppongo di dover avere un paio di server di applicazioni Web che colpiscono lo stesso database.

PPPS un esempio di modifica dello schema cambierebbe la tabella degli utenti, passando da un campo di testo a nome singolo a una combinazione di colonne nome e cognome. (Questo è l'esempio più semplice)

    
posta Stephen 27.11.2016 - 12:30
fonte

1 risposta

4

Hai centrato i due approcci principali. Tuttavia, li useresti come parte di una strategia su più fronti come la seguente:

  • Non mantenere lo stato della sessione sul server

    Se si mantiene lo stato in memoria per una sessione utente, è necessario conservare la vecchia distribuzione fintanto che ci sono sessioni attive. Questo vale per la distribuzione qualsiasi , non solo una con modifiche allo schema DB, ma non volevo che venisse trascurata.

  • Le modifiche allo schema sono additive; nessuna ristrutturazione o rimozione

    Se tutte le modifiche sono aggiunte sul campo, è possibile implementarle utilizzando nuove tabelle con relazioni 1: 1 alle vecchie tabelle. Ciò evita il problema del DDL che interferisce con DML, ma significa che il codice diventerà più complesso. Significa anche che alla fine avrai un sacco di tabelle sussidiarie, che saranno un incubo di manutenzione.

    Sul lato positivo, questo semplifica una distribuzione AB: utilizzare la replica del database per mantenere aggiornate le tabelle comuni, distribuire la nuova app nel data center B, trasferire il traffico, quindi rimuovere le autorizzazioni dal database A (o dalla replica di inversione) . A seconda dell'applicazione, potresti o meno voler mantenere l'affinità del client per evitare ritardi di replica.

  • Disaccoppia API dall'implementazione

    Questo è il tuo "livello di astrazione del database", sebbene la parola chiave corrente sia "micro-servizi". Se hai un singolo servizio responsabile per un'area della tua applicazione, puoi evolvere i dati che supportano il servizio mantenendo la costante dell'API.

    Per utilizzare il tuo esempio di modifica del nome di un utente. La versione 1 ha un campo con un solo nome, la versione 2 ha due campi. Tuttavia, è possibile implementare un'API versione 1 combinando i campi del database della versione 2 o implementando l'API versione 2 suddividendo il campo da un database versione 1.

    Più importante, è possibile implementare il servizio in modo tale che migra i dati in una nuova tabella sull'accesso. Questo risolve in gran parte il problema delle "tabelle esplosive" del primo punto. Tuttavia, dovrai migrare i dati che non sono attualmente accessibili. E dovrai evolvere l'implementazione del servizio per ignorare la vecchia tabella.

    Nota anche che "servizio" non implica "servizio web". Potrebbe essere una libreria all'interno della tua applicazione.

  • Spingi nuovamente la logica nel client

    Se si implementa un'architettura basata sui servizi esterna all'applicazione (ad esempio, i servizi Web anziché una libreria di servizi), è possibile iniziare a pensare a rendere l'applicazione più affidabile durante l'errore. Qualcosa di semplice come un tentativo potrebbe appianare una modifica di implementazione, anche se ovviamente l'API non può cambiare senza la ridistribuzione del client.

  • Disaccoppia aggiornamento e recupero

    In questo approccio, le modifiche vengono implementate utilizzando la messaggistica asincrona, il pattern Command. Sul lato client, è possibile memorizzare nella cache una vista del mondo con tali modifiche applicate, oppure è possibile progettare la propria applicazione in modo coerente: si apporta una modifica e si accetta che non venga applicata immediatamente.

    Questo ti dà un'enorme flessibilità per mantenere le implementazioni di servizi paralleli: ogni servizio mantiene i propri dati e applica i comandi a modo suo. Quando sei pronto per utilizzare il nuovo servizio, i dati saranno già lì.

    Tuttavia, l'idea di un'eventuale coerenza è un duro affare per gli uomini d'affari, che si sono illusi che i programmi per computer siano deterministici.

Un ultimo commento: a parte il primo, tutte queste tecniche sono più utili quando si ha un'applicazione matura. Se stai apportando modifiche drastiche al DB sottostante, probabilmente stai meglio spegnendo le applicazioni per farlo. Puoi ancora scegliere un momento di tranquillità per farlo e prepopolare tutti i dati.

    
risposta data 27.11.2016 - 21:00
fonte

Leggi altre domande sui tag