giovedì 12 maggio 2011

Hadoop HBase

HBase è un database distribuito column-oriented, scritto in Java, la cui progettazione è stata fortemente influenzata da Google BigTable e che fa uso del filesystem HDFS per la persistenza delle informazioni.
HBase è l'applicazione di Hadoop da utilizzare quando si richiede accesso real-time (read/write) ai dati in modalità random-access per una grande quantità di dati (diversamente da MapReduce che è batch-oriented).
Esso permette di archiviare una grande quantità di dati offrendo un architettura, fault-tolerant, orientata alla scalabilità attraverso l'aggiunta di nodi commodity al cluster e l'integrazione nativa con MapReduce e HDFS. Fornisce anche l'accesso alle risorse attraverso delle semplici API REST e la possibilità di operare in memoria per aumentare le performance.
Per quanto riguarda il data model, le applicazioni che utilizzano HBase, archiviano le informazioni in tabelle composte da righe e colonne, le cui intersezioni (le celle) sono versionate e possono contenere contenuti di vario genere in quanto formalmente sono considerate un array di byte. Di default il numero di versione è un timestamp auto generato da HBase in fase di inserimento della cella. Anche le chiavi (key) delle righe sono un'array di byte e teoricamente possono contenere qualsiasi cosa: da stringhe a dati binari. Le righe nelle tabelle vengono ordinate attraverso la row key e è quest'ultima che permette di accedere alle informazioni contenute nella riga attraverso le opportune query. Le colonne invece vengono raggruppate in column families e possono essere aggiunte a run-time(specificando la column family attraverso un prefisso). Fisicamente tutte le colonne di una column family vengono archiviate insieme nel filesystem.
Oltre al concetto di column, table e row, HBase utilizza anche le region. Infatti, le tabelle in HBase vendono automaticamente partizionate orizzontalmente in regions che vengono distribuite nel cluster. Ogni region comprende un sotto-insieme di righe di una tabella e in questo modo una tabella che è troppo grande per essere contenuta in un server può essere distribuita in diversi server del cluster.
Inoltre in HBase gli aggiornamenti sulle righe sono atomici, indipendentemente dal numero di colonne che costituiscono la riga.
Per quanti riguarda i dettagli implementativi, in HBase esiste un nodo master che gestisce il cluster composto da uno o più regionserver slave (fig. 11). Il nodo master è responsabile di inizializzare il cluster, di assegnare region ai regionserver registrati nel cluster e di sopperire alle failure dei regionserver. Come abbiamo detto i regionserver gestiscono uno o più region e forniscono le funzionalità di read/write. Gestiscono anche i dati (split) inviati dal nodo master contenenti informazioni riguardo i nuovi nodi del cluster.
HBase usa il file system di Hadoop HDFS per la persistenza dei dati anche se si possono usare altre implementazioni quali : local filesystem, Amazon S3, KFS filesystem e altri.
Quando una richiesta di scrittura arriva ad una regionserver (fig. 12), questa viene prima appesa al commit log e poi aggiunta alla cache in memoria. Quando la cache è piena, il suo contenuto viene scritto su filesystem. Il commit log è archiviato su HDFS, in modo da renderlo disponibile anche in presenza di un regionserver crash. In fase di lettura, viene in primo luogo consultata la cache in memoria della region, se viene trovata un'occorrenza questa viene ritornata, altrimenti viene avviata una fase di ricerca nel file archiviato su filesystem alla ricerca del record partendo dai dati che hanno un numero di versionamento più recente.

Hadoop MapReduce

MapReduce è un modello di programmazione per il data processing introdotto da Google per supportare il calcolo distribuito su grandi dataset in sistemi cluster. Come si può capire dal nome stesso, un job MapReduce consiste in task di due tipi:
1. Map: Il nodo master prende in input i dati (una coppia di key/value), estrae da essi alcuni (generando un altra coppia di key/value), creando di fatto dei sotto-problemi e gli distribuisce ai nodi worker. Quest'ultimi elaborano le informazioni e ritornano i risultati indietro ai nodi master.
2. Reduce: Il nodo master, che ha ricevuto le risposte da tutti i nodi designati all'elaborazione dei sotto-problemi, combina insieme le informazioni (unendo tutti i valori intermedi associati alla stessa chiave) e fornisce i risultati in output.
Un programma scritto seguendo queste specifiche viene automaticamente parallelizzato e può essere eseguito in un cluster commodity di grandi dimensioni. Le specifiche librerie MapReduce, infatti, tengono in conto e gestiscono automaticamente il data partitioning , lo scheduling dei job sulle diverse macchine hardware, gestiscono i failures delle macchine e le comunicazioni tra i diversi nodi di cui è composto il cluster.
Tutto ciò permette a programmatori che non hanno particolare esperienza nell'ambito del calcolo parallelo e distribuito di scrivere applicazioni che possono gestire una grande quantità di dati ed essere scalate su cluster di grandi dimensioni.
In dettaglio, ci sono due tipi di nodi che controllano il job: jobtracker e diversi tasktracker. Il jobtracker coordina tutti i job, schedulando i task ai relativi tasktracker. I tasktracker eseguono i task e inviano di tanto in tanto dei report sullo stato del processo ai jobtracker. Se un task fallisce, il jobtracker lo rischedula ad un altro tasktracer.
Hadoop divide l'input al job MapReduce in blocchi di dimensioni fisse chiamati split e crea per ogni split un task di tipo map che esegue una particolare funzione definita dallo sviluppatore per ogni record nello split.
In generale, è consigliabile avere degli split piccoli per avere un carico di lavoro bilanciato tra i diversi nodi, anche se la dimensione non deve essere inferiore ad una certa soglia (64 MB) altrimenti l'overhead per gestirli diventa più importante del tempo totale per eseguire l'operazione vera e propria.
Hadoop nel processo di map legge i dati in input da HDFS, mentre scrive i dati in output su filesystem locale in quanto questi sono risultati parziali che dovranno essere rielaborati in un secondo momento dai reducer per produrre l'output finale. Invece l'output finale prodotto dai reducer è normalmente archiviato su HDFS per garantire l'affidabilità.
MapReduce di Hadoop ha librerie scritte in differenti linguaggi di programmazione, quali : C++, C#, Java, Erlang, Ruby, Python e altri.
Esso viene usato in svariate applicazioni quali : distribuited grep, distribuited sort, web link-graph reversal, costruzione di inverted index7, document clustering e altri. In particolare MapReduce viene usato di tanto in tanto per rigenerare completamente l'indice di Google del World Wide Web.