2012-01-24 4 views
20

Su Heroku, non appena si preme il nuovo codice, le istanze di pubblicazione Web vengono riavviate ... anche se le aggiunte/modifiche dello schema del database sottostante (tramite syncdb o migrazione a sud) non sono state ancora applicate.Su Heroku, c'è un pericolo in una migrazione di Django syncdb/South dopo che l'istanza è già stata riavviata con il codice del modello modificato?

In molti casi, questo potrebbe solo causare errori innocui e il syncdb/migrazione viene eseguito subito dopo. Ma sono preoccupato che in alcuni casi, il nuovo codice possa semiadavoro apportare modifiche inaspettate nel database di pre-migrazione.

Qual è il modo giusto per essere sicuri contro questo rischio?

Una tecnica potrebbe essere quella di aggiungere syncdb/migrate al Procfile in modo che venga eseguito prima del riavvio del web. Ma, nel caso di più istanze, o forse anche di un caso in cui l'istanza di codice precedente viene lasciata in esecuzione fino al momento in cui è nota l'unica istanza di codice nuovo, c'è ancora una variante del problema in cui il codice è parlando con un DB con uno schema non corrispondente.

Esiste una funzionalità di "sospensione di tutte le istanze Web" (o best practice comune) per consentire la migrazione completa senza traffico web?

O sono eccessivamente preoccupato per un rischio trascurabile nella pratica?

+2

+1 ottima domanda. Ho esattamente la stessa domanda e credo che questo sia un rischio serio che deve essere evitato. Se syncdb/migrate va bene, il tuo sito sarà inattivo per meno di un minuto. Ma se fallisce per qualsiasi motivo, il tuo sito sarà inattivo finché non lo risolverai ... – Spike

+1

Ho lo stesso problema. In realtà è accaduto che il mio sito fosse inattivo, perché la mia migrazione verso sud non ha avuto successo. Fortunatamente, sono stato in grado di eseguire il rollback delle modifiche utilizzando il comando "heroku rollback". – duduklein

+4

Si consiglia di un'istanza di gestione temporanea per "mettere in pratica" la migrazione prima di tentarla sul proprio sito di produzione effettivo. http://devcenter.heroku.com/articles/multiple-environments –

risposta

9

Il modo più sicuro per gestire le migrazioni di questa natura, Heroku o no, è di adottare un approccio rigorosamente compatibilità con lo schema e il codice:

  • Ogni additivo o modifica dello schema di trasformazione devono essere compatibili con le versioni precedenti;
  • Ogni modifica distruttiva dello schema deve essere eseguita dopo il codice che dipende da esso è stato rimosso;
  • Ogni modifica del codice deve essere:
    • durevole contro la possibilità che non sono ancora state apportate modifiche schema associati (per esempio, la rimozione di un modello o di un campo su un modello) o
    • fatta solo dopo la modifica dello schema associato è stato eseguito (l'aggiunta di un modello o di un campo su un modello)

Se avete bisogno di fare una trasformazione significativa di un modello, questo approccio potrebbe richiedere i seguenti passaggi:

  • creare una nuova tabella di database per tenere la vostra nuova struttura del modello, e distribuire che la migrazione
  • creare un nuovo modello con la nuova struttura, e il codice per copiare le modifiche dal vecchio modello per il nuovo modello, quando il vecchio Modifiche al modello e implementazione di tale codice
  • Eseguire un'azione di migrazione o codice per copiare tutti i dati del modello precedente nel nuovo modello
  • Aggiornare il codice base per utilizzare il nuovo modello anziché il vecchio modello, eliminare il vecchio modello e distribuire quel codice
  • Eseguire una migrazione per eliminare il vecchio modello Struttura dal database

Con qualche pensiero e di pianificazione, può essere utilizzato per modifiche più drastiche così:

    codice
  • Distribuire che rimuove completamente dipendenza da una sezione della base di dati, presumibilmente sostituendo quelle sezioni del sito con pagine di manutenzione
  • Distribuire una migrazione che apporta modifiche drastiche che non funzionano per qualsiasi motivo con il flusso di lavoro doppio modello precedente
  • Distribuire il codice che riporta le sezioni interessate con la nuova struttura del modello supportata

Questo può essere difficile da organizzare e richiede una disciplina rigorosa e ferma la comprensione delle interazioni del vostro codice con il database, ma in pratica, è fa permettono per la maggior parte modifiche da apportare con non più i tempi di inattività del riavvio del server stesso impone.

1

Sembra che il passaggio rapido ai database sia la strada da percorrere, ma richiede un database dedicato.

http://devcenter.heroku.com/articles/fast-database-changeovers

In alternativa, ecco un tutorial per copiare i dati da un database (ad esempio, la produzione) a un altro database (ad esempio, messa in scena), facendo la migrazione dello schema/dati (ad esempio, utilizzando Django/sud), quindi passare all'app per utilizzare l'istanza del database appena aggiornata.

http://devcenter.heroku.com/articles/migrating-data-between-plans

sembra ragionevole, ma potenzialmente lento se c'è una grande quantità di dati.

1

Il metodo consigliato è questo:

  • modifiche Aggiungi database per le vostre nuove funzionalità per il codice esistente
  • Fai il codice esistente compatibile con il nuovo schema
  • Deploy
  • Aggiungi le nuove funzionalità alla base del codice
  • Distribuisci

Ciò significa che le modifiche al database sono già in atto quando il codice inizia a richiederle.

Tuttavia ....

Ci sono un paio di problemi con questo. Prima di tutto, non conosco un negozio di sviluppo che sia abbastanza organizzato per essere in grado di gestirlo, poiché le funzionalità vengono semplicemente create ad-hoc e, in secondo luogo, non stai salvando nulla.

In generale, a meno che non si apportino grandi modifiche a un enorme database, le modifiche non richiederanno molto tempo per essere applicate e sono solitamente terminate in un paio di secondi che uno sviluppatore può risolvere tranquillamente emettendo riavvii, ecc. Quando necessario. Il rischio è che un utente possa ricevere una pagina di errore. Se le modifiche sono maggiori, hai alcune alternative.Uno sta usando la modalità di manutenzione per spegnere il sito per alcuni secondi.

Per essere onesti, non esiste un modo chiaro per come gestirlo correttamente, poiché per definizione è necessario che il codice sia pronto per l'avvio delle modifiche del database. Il modo migliore che ho trovato per affrontare il problema è quello di esaminare ogni cambiamento individualmente e elaborare il percorso più semplice per ciascuno, caso per caso.

Le ripetizioni delle distribuzioni su un ambiente di staging riducono il rischio di una distribuzione che va male e ti danno un'idea dell'impatto.

1

Heroku ha recentemente rilasciato "buildpacks" che sono gli script che utilizzano per configurare un ambiente per l'applicazione, dalla gestione delle dipendenze al riavvio delle istanze. Essenzialmente è uno Procfile più completo che puoi personalizzare.

È possibile inserire lo Python buildpack e modificare lo script per l'esecuzione nella sequenza desiderata. Aggiungere il comando eseguito a syncdb alla fine di bin/steps/django. Impegnati e metti questo repo su Github.

Purtroppo fin d'ora non è possibile modificare il buildpack di un Heroku un'applicazione esistente, quindi dovrete cancellarlo e ricreare uno che punta al tuo buildpack repo:

heroku create --stack cedar --buildpack [email protected]:... 

questo è il migliore soluzione perché

  • non costa nulla
  • non richiede di adattare il codice per Heroku
  • sincronizza solo il db ONC e per distribuzione

Spero che questo aiuti.