# Sistema distribuito

La locuzione sistema distribuito, in informatica, indica genericamente una tipologia di sistema informatico costituito da un insieme di processi interconnessi tra loro in cui le comunicazioni avvengono solo esclusivamente tramite lo scambio di opportuni messaggi. Ogni nodo del sistema esegue un insieme di componenti che comunicano tra di loro utilizzando uno strato software detto middleware che permette all'utente di percepire il sistema come un'unica entità. Con il termine processo si indica, in genere, una qualsiasi entità capace di comunicare con un qualsiasi altro processo e di eseguire un algoritmo distribuito. A differenza di un algoritmo tradizionale è necessario includere nella definizione di algoritmo distribuito anche i messaggi che vengono scambiati tra i vari processi, poiché anch'essi sono essenziali nell'esecuzione e nella terminazione dell'algoritmo. I sistemi distribuiti nascono da esigenze sia di tipo economico che tecnologico.

## Descrizione
### Definizione

Esistono più definizioni (più o meno equivalenti fra loro) di un sistema distribuito, fra cui:
* "Un sistema distribuito è una porzione di software che assicura che un insieme di calcolatori appaiano come un unico sistema coerente agli utenti del sistema stesso" (Maarten van Steen, 2016).
* "Un sistema distribuito consiste di un insieme di calcolatori autonomi, connessi fra loro tramite una rete e un middleware di distribuzione, che permette ai computer di coordinare le loro attività e di condividere le risorse del sistema, in modo che gli utenti percepiscano il sistema come un unico servizio integrato di calcolo" (Wolfgang Emmerich, 1997).
* "Un sistema distribuito è un sistema in cui il fallimento di un computer che non sapevi neppure esistere può rendere il tuo computer inutilizzabile" (Leslie Lamport, 1987).

### Caratteristiche

Tra le caratteristiche di un sistema distribuito possiamo citare:
* Remoto: le componenti di un sistema distribuito devono poter essere trattate allo stesso modo sia che siano in locale che in remoto.
* Concorrenza: è possibile eseguire contemporaneamente due o più istruzioni su macchine differenti; non esistono strumenti che permettono di gestire in maniera semplice la sincronizzazione (come lock e semafori nella programmazione concorrente su multicore).
* Assenza di uno stato globale: non esiste un modo per determinare lo stato globale del sistema in quanto la distanza e l'eterogenità del sistema non permette di definire con certezza lo stato del sistema. La mancanza di un clock globale, in questo contesto rende impossibile riuscire a sincronizzare perfettamente gli orologi di tutti i processi e questo comporta l'impossibilità di ordinare, in modo preciso ed univoco, tutti gli eventi che occorrono all'interno del sistema. Tale risultato è dovuto alle differenze strutturali, di natura per lo più elettronica, dei vari dispositivi per la generazione del segnale di clock all'interno dei microprocessori. Differenze dovute anche a parametri fisici come la temperatura relativa al dispositivo, allo stato di utilizzo o all'età del dispositivo.
* Malfunzionamenti parziali: Ogni componente del sistema può smettere di funzionare correttamente indipendentemente dalle altre componenti del sistema; questo non deve compromettere le funzionalità dell'intero sistema. I fallimenti che possono affliggere i processi possono essere di varia natura, ma tipicamente è possibile raggrupparli in due categorie: fallimenti di tipo crash e fallimenti bizantini. Nel primo caso abbiamo che il processo che va in crash smette improvvisamente di funzionare mentre nel secondo caso è impossibile, in genere, fare qualsiasi tipo di assunzione sulla causa o sugli effetti del fallimento. In quest'ultimo caso infatti il comportamento del processo che fallisce in modo bizantino è tipicamente arbitrario.
* Eterogeneità: un sistema distribuito è eterogeneo per tecnologia sia hardware che software. Si realizza in tutti i contesti come rete di comunicazione, protocollo di rete, linguaggi di programmazione, applicazioni, etc.
* Autonomia: un sistema distribuito non ha un singolo punto dal quale può essere controllato, coordinato e gestito. La collaborazione va ottenuta inviando messaggi tra le varie componenti del sistema e gestita tramite politiche di condivisione e di accesso che devono essere rigorosamente seguite.
* Evoluzione: un sistema distribuito può cambiare sostanzialmente durante la sua vita, sia perché cambia l'ambiente sia perché cambia la tecnologia utilizzata. L'obiettivo è quello di assecondare questi cambiamenti senza costi eccessivi.
* L'essere sincrono o asincrono. Questa distinzione è essenziale poiché alcune problematiche nell'ambito dei sistemi distribuiti possono essere risolte o meno proprio in base a queste caratteristiche. Un sistema distribuito si dice sincrono quando è possibile calcolare le seguenti proprietà, altrimenti si dice asincrono:
** L'intervallo di tempo massimo e minimo per l'esecuzione di un'istruzione da parte di un processo.
** L'intervallo di tempo massimo per la trasmissione di un messaggio dalla sorgente alla destinazione.
** E la massima deviazione del valore di ciascun orologio locale (clock drift rate) rispetto al tempo reale.

### Requisiti non funzionali

La realizzazione di un sistema distribuito comporta la necessità di considerare altri aspetti, oltre a quelli sopra descritti, che non sono propriamente legati alle specifiche del sistema ma vengono utilizzati come linee guida per la progettazione e la manutenzione dei sistemi distribuiti. Tali aspetti sono i requisiti non funzionali che un sistema distribuito deve soddisfare:
* Aperto: deve supportare la portabilità di esecuzione e di interoperabilità secondo standard noti e riconosciuti sia per non legare il sistema ad un singolo fornitore che per far evolverlo (aggiungendo nuove componenti).
* Integrato: deve incorporare al proprio interno sistemi e risorse differenti senza dover utilizzare strumenti ad-hoc.
* Flessibile: deve dare la possibilità di integrare sistemi legacy al proprio interno e di poter gestire le modifiche a run-time riconfigurandosi dinamicamente.
* Modulare: ogni componente dovrebbe essere autonomo e con un certo grado di interoperabilità con il resto del sistema.
* Supporto alla federazione di sistemi: deve permettere di unire diversi sistemi sia dal punto di vista amministrativo che architetturale, per lavorare e fornire servizi in maniera contigua.
* Scalabile: cioè la capacità di erogare le medesime prestazioni, in termini di throughput e latenza, rispetto agli utilizzatori nonostante l'aumento del carico operativo sul sistema. Per aumento carico si possono intendere picchi di carico di accesso alle risorse dovuto all'aumento degli utenti del sistema in conseguenza all'evoluzione nel contesto aziendale.
* QoS: fornire i servizi con vincoli di tempo, di disponibilità e di affidabilità anche in presenza di malfunzionamenti parziali che possono sempre verificarsi in ambito distribuito. Tale qualità non viene soddisfatta da un sistema centralizzato che è particolarmente intollerante ai malfunzionamenti.
* Sicuri: Gli utenti non autorizzati non devono poter accedere al sistema.
* Trasparenti: devono mascherare i dettagli e le differenze dell'architettura sottostante permettendo un'agevole progettazione e programmazione. Questa trasparenza non deve essere comunque totale poiché chi progetta/programma un sistema distribuito deve sapere che sta lavorando su componenti remote.

### Esempi

Un'altra applicazione tipica dei sistemi distribuiti sono i sistemi di elaborazione distribuiti (computer cluster) a livello locale o geografico (ad es. per il calcolo distribuito) all'interno di un sistema informatico e connessi tra loro tramite rete locale o geografica. Un altro esempio di sistema distribuito è la rete Internet stessa, che si estende a livello mondiale comprendendo risorse fisicamente molto distanti tra loro, in cui processi con funzioni diverse e connessi da reti di vario tipo si scambiano messaggi informativi basati su disparati protocolli di comunicazione.

## Esigenze economiche
### Esigenze aziendali

L'economia di mercato è costituita da numerose e frequenti acquisizioni, integrazioni, fusioni aziendali e downsizing. La necessità delle aziende è quella di poter effettuare queste operazioni in maniera rapida ed efficiente integrando , per esempio in una fusione aziendale, diversi sistemi in un unico sistema in grado di gestire entrambi i sistemi delle due aziende o, nel caso del downsizing, mantenere un certo livello di integrazione con il resto delle aziende del gruppo in una sorta di federazione di sistemi che complica la gestione prevedendo, ad esempio, diversi livelli di accesso al sistema: all'interno dell'azienda, all'interno della federazione e dall'esterno.

### Esigenze di mercato

Oltre alle necessità aziendali, i sistemi distribuiti permettono di velocizzare il processo di creazione e messa sul mercato di un prodotto. Il mercato infatti ha la necessità di ridurre quanto più possibile il Time To Market (tempo per arrivare al prodotto finale) passando per le varie fasi quali ideazione, progettazione e realizzazione. Durante la fase di realizzazione è possibile che una funzionalità possa essere implementata utilizzando componenti off the shelf ( componenti preesistenti) che hanno però differenze sia hardware che software. I sistemi distribuiti permettono di integrare componenti off the shelf facendoli cooperare nonostante le differenze implementative.

### Esigenze di rete

La diffusione di internet ha fatto sì che diversi servizi potessero essere accessibili da una grande platea di utenti attraverso la rete. Un servizio quindi può avere dei picchi di carico (più utenti richiedono contemporaneamente l'accesso a tale servizio) a seguito magari di una pubblicità positiva. Se il servizio viene offerto utilizzando un sistema centralizzato ci sarebbe bisogno di una grande capacità di calcolo per gestire la grande quantità di richieste; i sistemi distribuiti permettono di distribuire il carico di lavoro su più calcolatori così da rendere il servizio scalabile al crescere della rete.

## Esigenze tecnologiche

L'evoluzione dell'informatica si è sempre basata sullo sviluppo delle tecnologie hardware. Ogni anno vi è un aumento delle prestazioni che una macchina può offrire. Alcuni leggi empiriche descrivono questo fenomeno applicandolo sia all'evoluzione delle componenti fisiche (legge di Moore) che alla crescita del valore di una rete secondo le leggi di Sarnoff, Metcalfe e Reed. Questo sviluppo ha portato alla creazione di metodi per lo sviluppo di sistemi software complessi in grado di utilizzare al meglio queste componenti sempre più evolute.

### Programmazione concorrente

Si può ridurre il concetto di sistema distribuito a quello di programmazione concorrente che permette di dividere il carico di lavoro di una singola macchina su tutti i core che mette a disposizione. Si pensi infatti che la maggior parte dei programmi, nonostante l'hardware migliori, non viene eseguito in minor tempo perché non sono stati scritti in modo da adattarsi al miglioramento dei processori.

### Integrazione

Quando si prende in considerazione un sistema questo è costituito da diverse componenti le quali hanno caratteristiche e prestazioni differenti (sistema eterogeneo); quando si vogliono aumentare le prestazioni di un sistema è più conveniente integrare nuove componenti (con prestazioni più alte) piuttosto che aggiornare o rifare il sistema daccapo. Un sistema distribuito permette di avere componenti diverse sia dal punto di vista hardware che software. Per integrare diversi sistemi è stato introdotto lo standard RM-ODP per risolvere i problemi di comunicazione; tale modello punta ad astrarre e standardizzare il concetto di portabilità e di trasparenza all'interno di un sistema distribuito inglobando ed estendendo il modello ISO/OSI, utilizzando quest'ultimo come modalità per la comunicazione tra componenti eterogenee.