La disponibilità (availability) di un sistema, nota anche come “disponibilità di un servizio” (service availability), è una metrica utilizzata comunemente per misurare in maniera quantitativa la resilienza di un sistema, oltre che constatare il raggiungimento degli obiettivi di resilienza, possibilmente accordati da Service Level Objective (SLO).
La disponibilità di un sistema è definita come la percentuale di tempo in cui un sistema è utilizzabile.
Con “utilizzabile” si intende che il sistema è capace di eseguire correttamente le proprie funzionalità quando richiesto.
La percentuale viene calcolata in relazione ad un periodo di tempo, come ad esempio un mese o un anno, o anche tre anni.
La disponibilità è ridotta ogni volta che l’applicazione non è in grado di operare normalmente, quindi vengono incluse sia interruzioni programmate che non.
La definizione formale di disponibilità (availability) è la seguente:
$latex availability = \dfrac{available\ for\ use\ time}{total\ Time} $Disponibilità misurata con i “number of nines”
Assumiamo di avere una applicazione web che nell’arco di un anno è stata offline per un totale di 3 giorni e 15 ore ( o 5220 minuti) complessivi, quindi non per forza consecutivi ma sparsi nel corso dell’anno.
Un anno è composto da 525600 minuti.
La disponibilità per quell’anno è stata quindi
$latex availability = \dfrac{availabile\ for\ use\ time}{total\ time} =$
$latex =\dfrac{total\ time – unavailable\ for\ use}{total\ time} =$
$latex =\dfrac{525600-5220}{525600} = 0.9900 = 99%$
Quindi il nostro applicativo è stato disponibile il 99% del tempo.
In gergo, la disponibilità di un sistema viene comunicata tramite “numero di nove” (number of nines), ovvero quanti 9 ci sono nella percentuale di disponibilità. Ad esempio, 5 nove si traduce in 99.999% di disponibilità.
E’ importante capire che più si cerca di avvicinarsi al 100% più diventa costoso mantenere il sistema. Ad esempio, dovremo replicare geograficamente la nostra applicazione, usare hardware ad hoc o impiegare operatori e macchinari specifici atti al monitoraggio del sistema. A seconda dello scopo del sistema, raggiungere una disponibilità elevata potrebbe non avere senso o comunque essere troppo costoso.
Ecco una tabella che, date delle percentuali di disponibilità, mostra quanto tempo di downtime possiamo permetterci:
Disponibilità | Limite massimo di tempo | Esempi di applicativi |
99% | 3 giorni e 15 ore | Batch processing |
99.9% | 8 ore e 45 minuti | Tool interni (knowledge management, project tracking etc.) |
99.95% | 4 ore e 22 minuti | Ecommerce |
99.99% | 52 minuti | Video delivery |
99.999% | 5 minuti | transazioni all’ATM, Telecomunicazioni |
Come calcolare la disponibilità in un sistema replicato
Un pattern architetturale comune per mantenere una disponibilità elevata consiste nel replicare il nostro servizio e metterlo dietro ad un load balancer o reverse proxy. In questo modo, le richieste vengono distribuite fra i vari worker, di cui il load balancer controlla periodicamente lo stato (“in salute” / “non in salute”).
Quando una replica risulta “non in salute” – e fintanto che il suo stato non torna ad essere “in salute” – il load balancer smette di assegnargli del lavoro. Il load balancer, però, si accorge di eventuali variazioni non appena invia la propria sonda ad ispezionare lo stato della replica. Nel tempo fra l’ultimo controllo effettuato e il successivo, la replica potrebbe diventare “non in salute” e smettere di lavorare alle richieste dei client.
Assumiamo che in un dato momento, ci siano 3 repliche (di cui una non in salute) e che venga inviata una richiesta da 3 client differenti per un totale di 3 richieste. Il load balancer assegnerà una richiesta ad ogni nodo.
In quel dato momento, il sistema risulterà funzionante per 2 utenti su 3.
Facendo riferimento alla formula sopra, come facciamo ora a calcolare la disponibilità del nostro sistema?
Sì perchè, in quel “momento”, il sistema era disponibile per una parte degli utenti.
Conta quindi come tempo di indisponibilità o no?
Possiamo quindi usare la formula alternativa che semplifica questo calcolo:
$latex availability = \dfrac{successfull\ responses}{valid\ requests}$
In questo modo, la disponibilità è calcolata come l’ammontare di risposte corrette inviate rispetto ad una certa quantità di richieste valide.
Se non ci sono richieste valide in un dato lasso di tempo, il periodo viene (giustamente) contato come disponibilità 100%!
Questa formula è dal mio punto di vista anche più corretta della precedente, perché solitamente i momenti in cui il nostro sistema diventa indisponibile tendono ad essere anche quelli di maggiore stress.
Quindi “8 ore di indisponibilità” (calcolata usando il tempo) non suggerisce la gravità della situazione se quelle 8 ore di assenza coincidono con il Black Friday per un sito di e-commerce che in quel lasso di tempo avrebbe ricevuto il 50% di richieste dell’intero anno. Usando la prima formula avremo 99.9% di disponibilità, con la seconda il 50%.
Hard dependencies e disponibilità in serie
Le hard dependencies sono dipendenze delle quali il nostro sistema non può fare a meno per funzionare correttamente.
Se la pagina di pagamenti del nostro e-commerce non può contattare il componente esterno che gestisce i pagamenti, avremo nei suoi confronti una hard dependency.
Se la pagina con i dettagli del nostro prodotto non riesce a comunicare col componente adibito a mostrare i “prodotti correlati”, questa è una soft dependency perchè la nostra pagina riuscirà comunque a compiere le proprie funzionalità di business.
Quando introduciamo una disponibilità in serie, possiamo visualizzare il nostro sistema come una pipe o un tubo, il cui output finale dipende dalla capacità di tutti i componenti coinvolti di funzionare correttamente.
Per questo motivo, la probabilità di avere un output dipende dalla probabilità condizionata che il secondo componente funzioni dato il primo componente funzionante.
La disponibilità in serie di un sistema x
, con hard dependencies i sistemi y
e z
, è quindi calcolata come segue:
$latex availability = availability_x * availability_y * availability_z$
Ad esempio:
$latex 99.99\% * 99.99\% * 99.99\% = 99.97\%$
Quindi aggiungere hard dependecies può solo *ridurre* la disponibilità del nostro sistema.
Componenti ridondanti e disponibilità in parallelo
Come premesso in precedenza, l’utilizzo di componenti ridondanti è un ottimo modo per migliorare la disponibilità di un sistema.
Per calcolare la disponibilità teorica massima di un sistema composto da parti ridondanti, possiamo utilizzare la formula per il calcolo della disponibilità in parallelo, che si basa sulla probabilità incondizionata che in un dato momento almeno uno dei due componenti si trovi nello stato in salute:
$latex availability = 1 – ((1 – availability_x) * (1- availability_y) * ( 1- availability_z))$
Assumendo che $latex availability_{x,y,z} = 0.9999$ possiamo ridurlo a:
$latex availability = 1 – (1-0.99)^3 =$
$latex = 1 – (0.1)^3 = 1 – (0.1)^3 = 1 – 0.000001 = 0.999999$
O 99.9999% (sei 9) di disponibilità.
Uno shortcut valido solo per numeri in cui è presente solo il 9, è sommare il numero di 9. Dati 3 servizi da 99% (due 9), il sistema risultante avrà sei 9, o 99.9999%.
Stimare la disponibilità di un sistema
Nel caso in cui una nostra dipendenza non offra informazioni sulla propria percentuale di disponibilità, un semplice esercizio per avere una stima è utilizzare il Mean Time Between Failure e il Mean Time Between Recovery. Questi offrono un’altra prospettiva sulla disponibilità. Il MTBF è il tempo medio che passa fra un incidente e l’altro, e il MTBR indica il tempo medio necessario per riportare il sistema online. Con questi due parametri, possiamo stimare la disponibilità in questo modo:
$latex availability_{est} = \dfrac{MTBF}{MTBR + MTBF}$
Se il MTBF è di 150 giorni e il MTBR è di 60 minuti:
$latex avalability_{est} = \dfrac{216000}{60 + 216000} = \dfrac{216000}{216060} = 0.9997 = 99.97%$
Conclusione
La disponibilità di un sistema è una metrica spesso presente fra i vari SLA, SLO e SLI di un dato servizio. Le tecniche descritte in questo articolo, sono applicabili in maniera analoga a sistemi cloud distribuiti, a circuiti elettronici e a sistemi in maniera generica – anche se viene fatto riferimento solamente ai primi.
Con il loro 99.999% di disponibilità, i sistemi di telecomunicazione hanno imposto aspettative e standard che i nostri utenti si aspettano di riscontrare mentre usano i nostri applicativi.
Comunque, se siamo disposti a pagare, la ridondanza può facilmente migliorare la disponibilità di un componente poco affidabile.
È bene ricordare che aggiungere dipendenze rigide può seriamente ridurre la disponibilità del nostro sistema.
Inoltre, più il sistema è complicato più risulta difficile riuscire a calcolarne la disponibilità.
Infine, usare il numero di richieste fallite invece del tempo di downtime effettivo, non solo è tecnicamente meno complicato ma il numero risultante tiene in considerazione il fattore utente: se nessuno stava utilizzando il nostro sistema, per quel che conta, possiamo pubblicizzarlo come disponibile al 100%.
Referenze:
- AWS Availability
- System Reliability and Availability
- The art of scalability (libro)