Introduzione ai database NoSQL

di , in LINQ,

NoSQL... cos'è?

Il termine NoSQL indica, in modo generico, un'ampia famiglia di nuovi database che non seguono i popolari e consolidati principi dei database relazionali (o RDBMS), ovvero non memorizzano i dati in classici schemi tabelle-relazioni e non viene usato SQL come linguaggio di interrogazione e manipolazione. Come molte delle nuove tecnologie che si sono affacciate negli ultimi anni, l'approccio NoSQL è in parte avvolto da una nebbia di incertezza e recentismo che fa sì che gli sviluppatori si dividano sostanzialmente in tre gruppi:

  • chi lo ama e ha iniziato ad esplorarlo trovando una collocazione nelle proprie applicazioni, al costo mantenendosi continuamento aggiornato sugli sviluppi che interessano questa tecnologia;
  • chi lo rifiuta, in parte per le carenze specifiche di questi database o semplicemente perché dubita della loro efficacia;
  • chi li ignora, semplicemente perché aspetta che questa tecnologia sia più matura e arrivi ad una sorta di "standardizzazione", così come è avvenuto per SQL, oppure ritiene che sia una moda passeggera destinata a ridimensionarsi , oppure è all'oscuro della loro esistenza o non ha idea di come usarli.

NoSQL non è un singolo prodotto o tecnologia ma sono emerse decine di implementazioni. Per capire il motivo di una simile esplosione, bisogna cogliere cosa "non va" nei database relazionali. Lo scenario più critico è la memorizzazione e l'elaborazione di enormi quantità di dati generate da un flusso abbastanza caotico o poco strutturato tipico del contesto Web. I database relazionali presuppongono una struttura rigida, detta schema, per cui si presuppongo le proprietà che i dati dovranno avere e le relazioni tra di essi. Tutto questo viene definito in modo statico e predefinito. Si assume inoltre che gli indici possano essere definiti in modo consistente su un determinato insieme di dati in modo da rendere più veloce l'interrogazione. Sfortunatamente i flussi che arrivano da sorgenti massive presentato notevoli irregolarità e mancano di strutture omogenee. Si dice che i RDBMS presuppongo un tipo di dato denso, mentre nel web si hanno dati più sparpagliati o sparsi. Questo scenario è anche detto Big Data.

Per poter gestire queste situazioni gli RDBMS richiedono delle forzature, ad esempio: denormalizzazione delle tabelle, eliminazione di vincoli di consistenza, riduzione delle garanzie di transazionalità, e così via; ma dopo tutte queste modifiche si arriva ad un RDBMS molto simile ad un NoSQL.

In questo contesto sono stati elaborati database che riducono i problemi imposti dai modelli classici riuscendo a lavorare con grosse moli di dati sparsi al prezzo della perdita alcune funzionalità come, per esempio, l'integrità transazionale. Ironicamente una delle caratteristiche che sono andate perse è stato proprio il linguaggio SQL.

Storicamente il soggetto più all'avanguardia nell'adozione di queste tecniche è stato Google. Per poter assemblare e integrare in modo efficiente tutti i suoi prodotti (Search, Maps, Finance, GMail, ecc.) Google ha costruito una infrastruttura scalabile per l'elaborazione "parallela" di enormi quantità di dati usando un filesystem distribuito, un datastore non relazionale column-oriented (chiamato BigTable) e un ambiente di esecuzione parallela basato sull'algoritmo Map-Reduce. Il lavoro svolto da Google, e successivamente pubblicato, ha ispirato l'intero mondo OpenSource (e non solo).

In prima battuta citiamo il motore di ricerca Lucene di cui è disponibile una versione .NET (Lucene.net), a sua volta integrato in RavenDB (un popolare database NoSQL di classe documentale particolarmente adatto a chi sviluppa in ambiente .NET). Gli sviluppatori di Lucene si unirono in seguito a Yahoo dove elaborarono un ambiente di elaborazione parallela che riproduceva tutti i pezzi del sistema Google. Il risultato è stato il progetto opensource Hadoop.

Microsoft stessa ha adottato Hadoop sulla sua piattaforma Azure nell'ambito della sua offerta di servizi per la gestione di scenari Big Data.

Parallelamente Amazon ha sviluppato e rilasciato diversi prodotti basati su tecnologie proprietarie adottati internamente, prima Amazon SimpleDB e poi Amazon DynamoDB, di fatto un vero e proprio servizio distribuito di database oltre al servizio Amazon Elastic MapReduce che usa un framework Hadoop per permettere l'elaborazione di enormi quantità di dati.

Oggetti, strutture dati relazionali, ORM e Caching

In linguaggi orientati gli oggetti come C#, ma anche Java, Python o PHP, si è portati a progettare e sviluppare le applicazioni partendo dal cosiddetto Domain Model e a descriverlo mediante classi. Nel momento in cui vogliamo persistere il nostro modello su una base dati relazionale ci troviamo di fronte a quello che viene definito impedance mismatch, ovvero un insieme di difficoltà tecniche e concettuali nell'adattare un modello a oggetti su un modello relazionale. Inoltre dobbiamo scrivere un sacco di codice SQL per gestire il passaggio tra i due "mondi".

La soluzione più diffusa al problema sono gli ORM (Object Relational Mapper) che forniscono, mediante un'interfaccia orientata agli oggetti, tutti i servizi inerenti alla persistenza dei dati, astraendo nel contempo le caratteristiche implementative dello specifico RDBMS utilizzato. I tool più completi e popolari in ambito .NET sono: Entity Framework e NHibernate. Ma esistono anche framework più "leggeri" come: Simple.Data e Dapper.

Sebbene tutti questi tool facciano un lavoro ragionevolmente buono, nessuno di essi adempie perfettamente allo scopo. Innanzitutto è necessario ricordarsi "sempre" che si ha a che fare con un database relazionale che funziona in termini di tabelle, righe, colonne, indici e join. In secondo luogo gli ORM hanno un prezzo da pagare: essi aggiungono complessità all'applicazione e un certo overhead. Inoltre espongono solo un sotto-insieme delle funzioni di SQL e dello specifico database sottostante.

L'apprendimento adeguato di un ORM può essere molto più impegnativo di quella di SQL e dobbiamo tener conto che sebbene gli ORM risolvano molti difetti o problemi di SQL a loro volta ne introducono di propri. Parliamo di performance. Sul sito di Dapper sono riportati i risultati di un benchmark che confrontano diversi ORM della piattaforma .NET in rapporto all'esecuzione di query SQL dirette con comandi ADO.NET. Il test esegue una query che estrae 500 righe da un database e ne effettua il mapping su altrettanti oggetti:

ADO.NET SqlDataReader (quindi uso di SQL diretto) 47ms
Dapper (comando SQL con mapping su oggetto POCO) 49ms
NHibernate SQL 104ms
NHibernate HQL (query SQL generata da NHibernate) 118ms
Entity framework ExecuteStoreQuery (query SQL creata manualmente) 631ms
Entity framework (query SQL generata da EF) 859ms

Entity Framework, nel suo uso comune, risulta quasi 20 volte più lento di un comando SQL diretto. Premesso che questi dati sono stati pubblicati più di un anno fa e che l'ultima versione di EF porta notevoli miglioramenti in termini di performance, il punto in questione non è di criticare EF (che è una libreria straordinaria) ma piuttosto di sottolineare come l'approccio ad oggetti su un sistema relazionale sia decisamente critico.

Un altro aspetto controverso è il caching dati. Tutte le piattaforme web che richiedono elevate prestazioni real time su una mole di dati notevole e con un alto traffico di utenti richiede di introdurre un ulteriore livello di accesso ai dati "più veloce" tra lo strato di middleware e la base dati.

In ASP.NET possiamo usare gli oggetti di caching disponibili nel framework che mantengono i nostri oggetti nella memoria del server su cui viene fatta la richiesta o addirittura salvare l'intero HTML generato usando OutputCache.

Uscendo da .NET il prodotto universalmente più adottato è Memcache; gli ingegneri di Facebook hanno sviluppato un architettura estremamente complessa per armonizzare un cluster di decine di migliaia di server Memcache con un backend MySQL in cui ogni utente ha una vista dati del tutto personalizzata e diversa da tutti gli altri.

L'approccio del caching è molto semplice in quanto si tratta di un "database" interrogabile in una sola dimensione: la chiave primaria. Quando eseguiamo una query sulla base dati principale ne salviamo il risultato nella cache assegnandogli una "chiave" che ci permetta di identificare in modo significativo la query stessa (per esempio "prodotti-piu-venduti-categoria-1"). La prossima volta che abbiamo bisogno di eseguire la query verifichiamo se prima ne abbiamo una versione in cache abbastanza recente e usiamo quella (recuperabile per chiave primaria diretta in modo molto veloce) ed evitiamo di interrogare del tutto il database.

La necessità stessa di questo livello intermedio è di per sé un chiaro segnale che "qualcosa non va" nei database convenzionali. MongoDB, RavenDB e CouchDB, per esempio, permettono di non usare affatto un server di caching in quanto nel momento in cui leggiamo da disco i dati di una query questi vengono mantenuti "in memoria" disponibili in modo istantaneo per una lettura successiva. I database convenzionali operano con un continuo I/O su disco e sono ottimizzati per questo. Inoltre questo approccio permette di leggere e scrivere i dati in modo "consistente".

Molti database NoSQL non solo leggono ma anche scrivono i dati in memoria, eseguendo le operazioni di persistenza in un momento successivo, secondo il semplice principio: "la RAM è veloce il disco è lento". Per capire l'abissale differenza consideriamo un hard disk da 1TByte (1000 GByte) con un accesso di 300 Mbit/s e una velocità di rotazione di 7200 giri/min: per leggere l'intero disco si impiegano circa 55 minuti. Tuttavia questo risultato non tiene conto che man mano che scriviamo su disco i dati questi tendono a frammentarsi impedendo una lettura sequenziale e costringendo la testina a continui salti e relativi ritardi; i tempi reali sono quindi di gran lunga superiori. In uno scenario Big Data questi tempi sono inaccettabili.

4 pagine in totale: 1 2 3 4
Contenuti dell'articolo

Commenti

Visualizza/aggiungi commenti

Introduzione ai database NoSQL 1010 8
| Condividi su: Twitter, Facebook, LinkedIn, Google+

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti