Alta affidabilità e bilanciamento di carico con Zope e Plone
Note: Return to tutorial view.
Introduzione
Questo documento è una libera traduzione di HA-Cluster with loadbalancing for Zope (and Plone) scritto da Goldmund, Wyldebeast & Wunderliebe.
Un HA-Cluster presuppone una disponibilità (quasi) continua, anche nel caso di un guasto hardware. Tuttavia non raggiunge l'alta affidabilità reale o, parlando in termini commerciali, un uptime del 99.999% (vedere per esempio WikiPedia):in questo modo il vostro sistema può essere indisponibile soltanto per 5 minuti all'anno, ed è evidente che questo lascia pochissimo tempo per eventuali interventi… Inoltre, per essere davvero Highly Available, altamente disponibile, non solo c'è bisogno di più di una macchina per ovviare ad un guasto hardware, ma occorre avere anche una ridondanza geografica, per fare fronte a un guasto del data center o della data backbone.
Per poter risolvere un problema hardware o software occorre configurare almeno due macchine, ed ogni macchina dovrà essere in grado di fornire gli stessi servizi agli utenti, senza che si noti il guasto. C'è da dire che alcuni utenti specifici potrebbero accorgersi di un'interruzione dei servizi: se nel mezzo di una request il web server si blocca , o se una CPU si guasta, ci potrebbe essere una conseguenza, ma le operazioni possono essere riprese in fretta.
In seguito prenderemo in considerazione una semplice configurazione di due macchine nello stesso ambiente fisico: sia chiaro che non è una limitazione pratica, ma soltanto un esempio per chiarire l'argomento.
Per maggiori informazioni riguardanti il clustering e le tecniche di load-balancing su altri casi d'uso, fare riferimento al sito http://www.ultramonkey.org/.
Presupposti/Prerequisiti
La configurazione utilizzata include i seguenti componenti:
Apache2;
Heartbeat;
NFS;
mod_proxy_balancer (opzionale, ma molto efficiente in termini di uso dell'hardware);
Squid (opzionale, la configurazione di Squid per Zope non è descritta in questo documento);
ZEO;
Un nostro script di sincronizzazione (che attualmente ha il nome syncPozo).
Su un sistema Linux tutti questi componenti sono pacchetti pronti all'uso, ad esclusione dello script di sincronizzazione.
Setup
Entrambe le macchine hanno Apache2 installato, così come hanno pronta un'istanza Zope con ZEO. Heartbeat viene usato per verificare il normale funzionamento del cluster (ovvero verifica se il master è attivo). Entrambe hanno accesso ad internet con il proprio indirizzo IP, e con un indirizzo IP dinamico che deve puntare al master, o allo slave quando il primo è non attivo.
Per maggiori informazioni potete consultare il sito di heartbeat.
La configurazione può essere rappresentata graficamente dal seguente schema:

La linea rossa indica l'itinerario che sarà attivo dopo il failover. Le linee nere indicano gli itinerari normali di funzionamento. Questo setup presuppone l'uso di Apache2 con mod_proxy_balancer
Il cluster viene contattato nel suo insieme con l'indirizzo IP dinamico, che normalmente è configurato sul master. Il server master riceve tutte le richieste sulla porta 80 ed usa il mod_proxy_balancer per distribuire le richieste sulle due macchine, o verso Squid o direttamente agli Zope. Il bilanciamento del carico non è una parte essenziale di questa configurazione, ma permette un uso più efficiente dell'hardware. Gli Zope client utilizzano uno ZEO server come backend. Lo ZEO server gira sul master ed è raggiunto con l'indirizzo IP dinamico dagli ZEO client. I dati del master (il Data.fs) sono sincronizzati con lo slave. Sullo slave lo ZEO server viene tenuto non attivo.
Nel caso di failover, heartbeat si prende cura del' assegnazione del indirizzo IP dinamico allo slave e ne avvia lo ZEO server. Da quel momento in poi sarà questo ZEO server quello utilizzato dagli ZEO client: il passaggio avverrà automaticamente. Se possibile, lo ZEO server sul master sarà bloccato ed il processo di sincronizzazione disattivato. Il recupero dal failover non è automatizzato a causa dell'alto rischio di errori in questa procedura.
Il recupero include:
verifica dell'integrità dei dati sullo slave;
copia dei dati modificati dallo slave al master;
arresto dello ZEO server sullo slave;
avvio dello ZEO server sul master;
riattivazione della sincronizzazione sullo slave.
riattivazione di heartbeat sul master.
Se si desidera, si può automatizzare il recupero, ma abbiamo scelto di effettuare l'intervento manuale per assicurarci di poter verificare completamente la natura del guasto prima del recupero, nel corso del quale ci potrebbe essere un intervallo molto breve in cui gli utenti noteranno l'indisponibilità del servizio. Infatti ad un certo punto lo ZEO server della macchina slave deve essere interrotto prima della copiatura del Data.fs sul master. Si può studiare la possibilità di non arrestare lo ZEO server durante la copia, ma farlo soltanto dopo che il master ha ripreso il suo ruolo.
Configurazioni
Apache
Apache è configurato per caricare almeno i moduli per proxy, proxy_balancer and proxy_http. Approssimativamente, il bilanciamento è realizzato dalla seguenti configurazioni, che potrebbero essere per esempio all'interno di una dichiarazione host virtuale:
<Proxy balancer://lb>
BalancerMember http://192.168.1.10:8080
BalancerMember http://192.168.1.11:8080
</Proxy>
...
ProxyPass / balancer://lb/VirtualHostBase/http/somesite.foo.bar:80/ploneinstance/VirtualHostRoot/
Ipotizzando di avere due nodi funzionanti sulla porta 8080, gli indirizzi IP sono 192.168.1.10 e 192.168.1.11, il vostro Plone si chiama “ploneinstance” e state utilizzando Virtual Host Monster per mappare somesite.foo.bar sull'istanza Plone.
Heartbeat
Il processo Heartbeat sulla macchina master invece non è (ri)avviato automaticamente (in questo modo, l'indirizzo IP dinamico non tornerà al master automaticamente) data l'esigenza di effettuare un recupero manuale in caso di crash: occorre rimuovere i link di start e stop di Heartbeat da tutti i runlevels in /etc/rc.<x> e avviarlo manualmente usando /etc/init.d/heartbeat.
Configurate Heartbeat a seconda del vostro hardware, preferibilmente usando almeno due canali di comunicazione per il controllo sullo stato del cluster. La configurazione più diffusa prevede un'interfaccia seriale ed una ethernet tra entrambe le macchine. Le vostre macchine dovrebbero dunque avere due interfacce ethernet, una per le comunicazioni esterne ed una dedicata ad Heartbeat. La configurazione di Heartbeat sullo slave, deve contenere le direttive per l'avvio dello ZEO cluster e dello stop della sincronizzazione in caso di crash. La configurazione sul master non ha bisogno di quest'ultima, ma dovrebbe comunque fermare lo ZEO cluster.
Aggiungere le seguenti direttive al file /etc/heartbeat/haresources:
<master> <floating IP address>/24/<ethernet interface> zeodove master è il nome che identifica il nodo master su entrambe le macchine, descritto nel file /etc/hosts.
Il nome 'zeo' è arbitrario, questo identificatore dovrebbe essere il nome dello script nella directory /etc/heartbeat/resource.d che si occupa di fermare ed avviare lo zeo cluster, e di fermare la sincronizzazione sullo slave.
Controllate i file zeo allegati per vedere una configurazione di esempio su master e slave. Entrambi gli script assumono che ci sia un'istanza localizzata in /opt/zope/instance0, ma ovviamente questa può trovarsi ovunque vogliate.
NFS
Il nodo master deve condividere la directory contenente il file Data.fs, che deve poi essere montata sullo slave. Sul nodo master, aggiungete la seguente riga al file /etc/exports:
/data0 192.168.80.1(ro,sync)
Ciò presuppone che i vostri dati sul nodo master siano nella partizione /data0, e che l'indirizzo IP del nodo slave (preferibilmente su una seconda interfaccia ethernet) sia 192.168.80.1. Assicuratevi inoltre che il nodo slave possa montare condivisioni di tipo NFS. Potreste aver bisogno di leggere i manuali per NFS e Portmap qui linkati.
Ora aggiungete la seguente linea al file /etc/fstab sul nodo slave:
192.168.80.2:/data0 /mnt/master/data0 nfs defaults 0 0assumendo che l'indirizzo IP del nodo slave sia 192.168.80.2, la condivisione sia /data0 ed il mount point sia /mnt/master/data0.
Sincronizzare
* * * * * . .profile; $HOME/bin/syncData.sh <MASTER DATA DIR> <SLAVE DATA DIR> >> $HOME/var/log/syncData.log 2>&1dove MASTER DATA DIR punta alla directory in cui la partizione NFS è stata montata e dove risiede il Data.fs; SLAVE DATA DIR punta alla directory in cui risiede il Data.fs slave.
Il profilo utente (identificato con .profile) contiene alcune impostazioni e variabili d'ambiente, come ad esempio il PYTHONPATH.
Lo stato della sincronizzazione, che questa debba essere eseguita o meno, viene registrata nel file syncPozo.status. In caso di crash del nodo slave, la sincronizzazione viene disabilitata. Il file contiene una sola riga:
SYNCING=[0|1]Il valore 0 indica che il sistema di sincronizzazione non è attivo.
I sorgenti di entrambi i file syncPozo.py (il vero sincronizzatore) e syncData.sh (il controller script) sono in allegato.
Il file di log relativo all'uso di cron si trova in $HOME/var/log sotto il nome syncData.log.
Al suo interno potreste leggere uno o più dei seguenti messaggi:
- Start syncing
- Lo script ha iniziato la sincronizzazione
- missing or empty .dat file (full backup)
- Nessun file Data.fs è stato trovato sullo slave, è stato quindi effettuato un backup completo
- No handlers could be found for logger "ZODB.FileStorage"
- Non è stata settata la variabile PYTHONPATH per contenere le librerie Python prima di invocare lo script syncPozo.py. Il path delle librerie di Zope è <ZOPE INSTANCE>/lib/python.
- Slave (backup) file has grown since last syncing...
- Il nodo slave è stato rimosso dalla sincronizzazione col master. E' consigliata la completa rimozione del Data.fs slave, e la forzatura di un backup completo.
- NOT SYNCING FROM MASTER
- SYNCING è settato a 0 in syncPozo.status.
- Finished syncing
- E' tutto per questo round, gente!
Nota: assicuratevi che le librerie Python per Zope siano indicate correttamente nella variabile d'ambiente PYTHONPATH.
Casi d'uso
ZEO è attivo solo sul nodo master ed è connesso al Data.fs localizzato su di esso. Apache invia le richieste ai client sia sul nodo master che sul nodo slave; quest'ultimo fa riferimento allo ZEO cluster situato sul nodo master usando l'indirizzo IP dinamico. Il nodo slave sincronizza continuamente (in base a determinati intervalli di tempo) il proprio Data.fs tramite quello presente sul master (montato in locale tramite NFS) usando lo script syncPozo.py (con questo script vengono sincronizzati solo i cambiamenti e la sincronizzazione risulta molto veloce).
IL NODO MASTER NON E' ATTIVO
Quando Heartbeat (attivo sul nodo slave) rileva che il nodo master non è attivo, vengono eseguite queste operazioni:
- la sincronizzazione automatica del Data.fs si ferma definitivamente fino a quando non verrà riavviata manualmente. Ciò serve ad evitare che dopo lo stop e il riavvio del master, il vecchio Data.fs non sovrascriva quello più aggiornato presente sul nodo slave;
- il processo Heartbeat sul nodo slave modifica la stringa syncing del file /var/run/syncPozo.status in "SYNCING=0";
- l'indirizzo ip dinamico viene sostituito;
- ZEO sul nodo slave viene avviato.
ZOPE2 si riconnette automaticamente a ZEO2.
IL NODO SLAVE NON E' ATTIVO
Non accade nulla
IL NODO MASTER RITORNA ATTIVO DOPO LA DISATTIVAZIONE
Non viene eseguita nessuna azione in modo automatico: ZEO1 rimane disattivo, il nodo slave conserva l'indirizzo IP dinamico.
Devono essere eseguite delle operazioni manuali (per OGNI sito!):
- fermare ZEO2 (il sito non è attivo al momento!);
- copiare il Data.fs dallo slave al master;
- avviare ZEO1.
Dopo aver compiuto, per ciascun sito, questi passaggi fondamentali , bisogna :
- sostituire l'indirizzo IP dinamico (il sito è di nuovo attivo, dopo che i client ZOPE si saranno automaticamente riconnessi allo ZEO1);
- avviare i processi syncPozo modificando il file /var/run/syncPozo.status in SYNCING=1;
- controllare il processo di sincronizzazione: se è il caso, cancellare il Data.fs dal nodo slave, per effettuare un backup completo dal nodo master.
Alternative
Naturalmente esiste più di una strada per raggiungere simili risultati. Le alternative non verranno mostrate in questa guida nel dettaglio, ma sono di seguito indicate:
