Saturday’s Talks: I database relazionali non sono dinosauri, ma squali

2

Quanto qui esposto è già stato scritto da altri, probabilmente anche meglio. Per questo pezzo abbiamo preso spunto in particolare da un articolo apparso sul blog di simple thread, di cui abbiamo preso in prestito anche il titolo.

Nel mondo dello sviluppo software, non solo in quello OpenSource, la rivoluzione dei paradigmi dovuta alle tecnologie web e cloud è più che evidente. Se il software non è strutturato a microservizi, in container orchestrabili, semplicemente non è moderno. E in informatica, qualsiasi cosa non sia moderna è direttamente obsoleta: da buttare.

Oggigiorno la caratteristica considerata fondamentale è la scalabilità, ovvero poter creare e mettere in linea più copie in parallelo dello stesso servizio per aumentare linearmente le prestazioni. L’esempio classico è il sito web: se le richieste sono troppe per un server solo, basta metterne due (con un bilanciatore davanti) per raddoppiare la capacità di offrire il servizio.
Ma non solo si aumentano le prestazioni, in questa maniera, ma anche l’affidabilità: avendo più istanze in parallelo, alcune possono andare perdute mentre le altre continueranno a fornire il servizio.
Quello che prima era l’alta affidabilità, ovvero la garanzia che un certo processo non sarebbe caduto, ora è diventata alta disponibilità: c’è sempre almeno una copia del servizio in piedi.

Possiamo dire che quasi tutte le applicazioni odierne sono strutturate su tre livelli:

  1. frontend – le app dei nostri cellulari, o un sito web, con cui noi interagiamo per ordinare un’operazione e visualizzare il risultato;
  2. backend – spesso un indirizzo web apposito con cui il frontend interagisce per effettuare l’operazione richiesta e recuperare il risultato;
  3. database – dove i nostri dati risiedono, che il backend interroga o manipola a seconda dell’operazione richiesta.

Mentre frontend e backend sono spesso applicazioni facilmente scalabili, i database presentano difficoltà di molto suoeriori.
In particolare, quelli tradizionali (come MySQL e Micosoft SQL Server), obbligano a prevedre l’organizzazione dei dati in tabelle e colonne piuttosto rigide, nonché la relazione tra di esse – tanto da essere definiti anche relazionali. In genere, su questi DB si opera tramite SQL, un linguaggio che possiamo definire tanto standard da identificare questo tipo di database.

Negli ultimi anni sono nati molti database non relazionali, come Redis, MongoDB ed ElasticSearch – per citarne alcuni, indicati in genere come NoSQL. Promettono prestazioni di scrittura e lettura di molto superiori ai database tradizionali, talvolta di decine di volte. Possono essere organizzati in cluster di nodi, così da scalare orizzontalmente: proprio come per il server web, quando serve più potenza (o ridondanza) basta aumentare il numero di nodi.

I DB relazionali fanno molti controlli durante le loro operazioni. Non solo perché devono rispettare le relazioni tra i dati (esistenti o da inserire), ma acnche perché forniscono garanzie sullo stato dell’intero database in ogni istante. Queste garanzie sono raccolte dall’acronimo ACID.

  1. Atomicity (atomicità) – ogni operazione complessa o viene eseguita completamente o non viene eseguita affatto, in modo da non avere mai stati sporchi o non validi.
  2. Consistency (consistenza) – durante le operazioni i dati rimangano validi. Il corollario è che in ogni istante i dati appaiono alla stessa maniera (ovvero con gli stessi valori) per tutti gli utilizzatori.
  3. Isolation (isolamento) – un’operazione non modifica i dati usati da un’operazione concorrente. Questo implica che le operazioni eseguite in parallelo avrebbero gli stessi risultati se eseguite in sequenza, una dietro l’altra, indipendentemente dall’ordine di esecuzione.
  4. Durability (persistenza) – una volta completata un’operazione, questa non può essere persa (perché memorizzata su un supporto durevole).

Sono queste stesse garanzie a rendere difficile – se non impossibile – la scalabilità dei DB relazionali. E infatti, i DB NoSQL riescono a raggiungere quelle prestazioni superiori solo sacrificando (almeno parte) di queste garanzie.

La prima garanzia a cui si deve rinunciare è la consistenza: se ho 3 nodi di un cluster, ed una operazione modifica un dato, questa modifica sarà registrata come fatta quando completata dal primo ma prima che tutti i nodi siano stati aggiornati. Questo vuol dire anche che se intanto un’altra chiamata legge gli stessi dati, vedrà il dato vecchio o quello nuovo a seconda di quale nodo fornirà la risposta.

Per lo stesso motivo, la seconda garanzia a cui si rinuncia è l’isolamento: operazioni concorrenti possono modificare gli stessi dati, e la situazione finale è difficilmente determinabile, dipendente solo dall’ordine con cui verranno effettuate le operazioni – e su come i vari nodi si aggiorneranno tra loro.

La terza garanzia a cui si rinuncia molto spesso è la persistenza: il più delle volte, invece di aspettare che i dati siano scritti sui dischi (anche gli SSD più veloci sono comunque lenti rispetto alla cache della RAM), il DB si accontenta di accodarli in memoria. Ma se per qualsiasi problema (errore hardware, o mancanza di corrente) quella macchina non dovesse riuscire a scrivere i dati sul disco, o a replicarli su altri nodi, quei dati andrebbero semplicemente persi.

Con questo vogliamo dire che i DB NoSQL non sono da usare? Assolutamente no. Ma come per ogni strumento, bisogna conoscere vantaggi e svantaggi per poter fare la scelta dello strumento adatto. E l’argomento vale anche per i DB relazionali: solo perché sono basati su principi vecchi, non vuol dire che siano obsoleti e da buttare.
Quindi, la valutazione del tipo di DB da usare per la propria applicazione non può basarsi solo sulle prestazioni, ma anche sul costo da pagare per quelle prestazioni.

Cosa c’entrano dinosauri e squali?

L’articolo citato all’inizio paragona i database relazionali ad animali antichi, che sono apparsi sulla terra molto, molto tempo fa. E sebbene molti addetti ai lavori – specie gli sviluppatori – ritengano questi animali non più adatti ai tempi, quindi in estinzione come i dinosauri, per l’autore dell’articolo è più corretto ritenerli squali: il massimo del loro campo.
Infatti la lunga esistenza ha permesso l’evoluzione al massimo grado di quelle caratteristiche che fanno degli squali dei predatori formidabili, tanto da essere ancora all’apice della catena alimentare.
I DB relazionali avrebbero subito lo stesso raffinamento delle loro caratteristiche, come le garanzie ACID. Laddove queste garanzie siano necessarie – e succede più spesso di quanto si voglia ammettere -, i DB relazionali sono squali: il massimo del loro campo.

Ho coltivato la mia passione per l’informatica fin da bambino, coi primi programmi BASIC. In età adulta mi sono avvicinato a Linux ed alla programmazione C, per poi interessarmi di reti. Infine, il mio hobby è diventato anche il mio lavoro.
Per me il modo migliore di imparare è fare, e per questo devo utilizzare le tecnologie che ritengo interessanti; a questo scopo, il mondo opensource offre gli strumenti perfetti.

2 risposte a “Saturday’s Talks: I database relazionali non sono dinosauri, ma squali”

  1. Avatar Rickyx
    Rickyx

    Anche la il discorso delle relazioni aiuta lo sviluppo: è pieno di esempi di migrazioni da NoSql proprio per la mole di lavoro necessaria dell’implementazione delle logiche di relazione su db non relazionali.

    Strumenti come PostgreSQL (che supporta i blob json!) sono abbastanza facili da scalare per le letture. Per molte scritture invece è tutto più complesso…

  2. Avatar JustATiredMan
    JustATiredMan

    Sarò anche un dinosauro, ma a me, francamente, gli SQLali piaccino molto come animali, e mi stanno pure simpatici 😀

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *