Scuola Politecnica e delle Scienze di Base
Corso di Laurea in Ingegneria Informatica
Elaborato finale in Basi di Dati
Sistemi BigData e strumenti di Analisi
Anno Accademico 2015/2016
Candidato:
Paolo Valletta
matr. N46002073
[Dedica]
Indice
Indice .................................................................................................................................................. III
Introduzione ......................................................................................................................................... 4
I grandi magazzini di informazioni: Big Data ................................................................................. 5
Cenni storici ..................................................................................................................................... 8
Capitolo 1: Il mondo dei Big Data System ........................................................................................ 11
1.1 Le caratteristiche di un buon Big Data System ........................................................................ 11
1.2 Immutabilità vs. Paradigma Incrementale ............................................................................... 12
1.3 I limiti dello scaling ................................................................................................................. 13
1.4 Data Extraction: ETL o ELT? .................................................................................................. 14
1.4.1 Un approccio alternativo: ELT ........................................................................................ 15
Capitolo 2: Apache Hadoop ............................................................................................................... 17
2.1 Una soluzione: Apache Hadoop ............................................................................................... 17
2.3 Storage in un sistema Big Data ................................................................................................ 19
2.3.1 Filesystem distribuiti ......................................................................................................... 20
2.3.2 Problemi comuni ............................................................................................................... 21
2.3.3 Hadoop Distributed FileSystem ........................................................................................ 23
2.4 Data Computation .................................................................................................................... 24
2.5 MapReduce .............................................................................................................................. 24
Capitolo 3: Apache Pig ...................................................................................................................... 27
3.1 Apache Pig ............................................................................................................................... 27
3.2 Pig Latin ................................................................................................................................... 28
3.3 Perché usare PigLatin............................................................................................................... 28
3.4 Features del linguaggio ............................................................................................................ 29
3.5 Pig vs. SQL .............................................................................................................................. 29
Capitolo 4: Analisi di un caso pratico ................................................................................................ 33
4.1 Caso di studio ........................................................................................................................... 33
4.2 Setup dell’ architettura ............................................................................................................. 34
4.2.1 Apache Hadoop ................................................................................................................. 34
4.2.2 Apache Pig Latin ............................................................................................................... 35
4.3 Dati di input ............................................................................................................................. 36
4.4 Lo Script ................................................................................................................................... 38
Conclusioni ........................................................................................................................................ 42
Bibliografia ........................................................................................................................................ 43
Introduzione
Lo scopo di questo elaborato è trattare il mondo dei Big Data System, senza tralasciare gli
strumenti di analisi (analytics tools) ad esso collegati. In questa tesi si affronta tale tema
sviluppandolo in 4 capitoli, così da applicare un approccio sia teorico che pratico. Il titolo
adoperato, “Big Data System e strumenti di analisi”, vuole mostrare, difatti, la scelta di tali
approcci. Nei vari capitoli, il tema dei Big Data sarà sviscerato il più possibile, partendo
da una semplice presentazione del dominio trattato, passando poi ad una elencazione delle
problematiche e delle nuove sfide che nascono in tale ambiente, e arrivando infine a
provare e valutare un prodotto reale, utilizzato oggi da svariate aziende del settore.
Inizialmente, vi saranno dei paragrafi che introdurranno ai Big Data System, ovvero questi
grandi magazzini di dati (noti anche come data warehouse) sviluppatisi soprattutto nella
storia recente, le cui sfide ruotano intorno a come gestire questa grossa e vasta mole di
informazioni.
Il primo capitolo, che fa da contorno all’ introduzione stessa, effettua una disamina sulle
caratteristiche e le principali features che un sistema Big Data (correttamente strutturato)
debba possedere e manifestare. Si andrà, infatti, ad analizzare le proprietà e le features
richieste ad un buon sistema, che è possibile ottenere applicando determinate tecniche
durante la progettazione e lo sviluppo dell’ intera architettura. Da qui nascerà un discorso
riguardo il contrapporsi di due approcci differenti riguardo la gestione del data model,
quali immutabilità e paradigma incrementale. Verrà mostrato come quest’ ultimo risulterà
in affanno con i data warehouse e cederà quindi il passo all’ altro approccio, che meglio
calzerà le richieste dei developer e dei clienti finali. Successivamente, verrà accennato il
processo di data mining e saranno descritti due modalità di ottenimento, processazione e
memorizzazione dei dati: ETL (Extraction, Transform, Load) ed ELT (Extraction, Load,
Transform). Infine si parlerà di come il problema della scalabilità sia centrale nello
sviluppo dei Big Data System e di come questo influenzi le scelte di progettazione e
realizzazione dei sistemi finali.
Il capitolo due, invece, abbandonerà la linea di presentazione e descrizione che ha
4
contraddistinto il capitolo primo. Si parlerà qui di Apache Hadoop, introducendo questioni
ed analisi di problemi più tecnici riguardo tale piattaforma. Ovviamente, non mancherà
una disamina teorica della stessa, a partire dalla sua storia ed evoluzione per arrivare a
come oggi venga ampiamente adoperata, dato che realizza e soddisfa i principi cardini di
un sistema BigData corretto. In particolare, saranno presentati i due componenti su cui si
fonda l’ architettura, ovvero un file system distribuito (Hadoop Distributed File System) e
un sistema di computazione distribuita (MapReduce). Il problema dell’ archiviazione e
della gestione dei dati sarà sviscerato e trattato a fondo, presentando non solo le difficoltà
che si incontrano, ma anche dei confronti tra diversi approcci possibili, definendo infine le
soluzioni proposte ed offerte da Apache Hadoop.
I primi due capitoli serviranno, così, a gettare le basi per fondare ed entrare nel terzo
capitolo: qui sarà presentato un componente di Apache Hadoop chiamato Pig. Mantenuto e
sviluppato anch’ esso da Apache, si tratta di una piattaforma che offre allo sviluppatore
degli strumenti per realizzare task distribuiti in MapReduce. Il grande vantaggio che lo
caratterizza riguarda la forte libertà che offre al developer: oltre a consentire di scrivere
degli script adoperando un linguaggio più espressivo di un classico SQL, esso permette di
integrare tale codice con altro scritto in linguaggi differenti o addirittura legacy. Qui verrà
analizzato l’ intero strumento, presentando pro e contro che comporta la sua scelta. Il
linguaggio di Apache Pig che si andrà a discutere è Pig Latin, che vedremo presenta
caratteristiche versatili e agevoli im merito a Big Data System e di programmazione
distribuita
su
MapReduce
Jobs.
Infine, con l’ ultimo capitolo si proverà sul campo l’ efficacia e le potenzialità di Pig
Latin, tramite un caso di studio creato ad hoc. I risultati ottenuti potranno così confermare
quanto descritto e dicusso a riguardo, validando così quanto scritto su di esso.
I grandi magazzini di informazioni: Big Data
Oggi giorno, grazie alla diffusione di internet e dispositivi mobili, viene prodotta una
quantità di dati poderosa. Dai social network, ai siti di video-content fino ai “semplici”
blog, il web 2.0 ha permesso a chiunque di diventare un creatore di contenuti. Questi
5
contenuti, che tutti noi magari ci limitiamo a pensare siano posts, video, gifs di gattini e
mp3 del nostro cantante preferito, si tramutano in bit, tanti bit, tutti da memorizzare,
gestire, e organizzare.
Il termine utilizzato per indicare questa mole di dati vasta e eterogenea è Big Data. Come
stesso la parola ci suggerisce, stiamo parlando di qualcosa di sproporzionato rispetto alla
solita concezione comune di database o di quantità di informazioni gestite digitalmente.
Questo è sostanzialmente un
mondo da poco, e soprattutto
negli ultimi anni ha visto una
forte crescita. Questa è dovuta
molto agli interessi economici
di aziende in vari settori, che
hanno visto un’ opportunità di
crescita considerevole per i loro
business. Tali interessi ruotano
soprattutto intorno a ciò che viene chiamato “analitycs” dei dati, che consiste di un
insieme di operazioni e processi su queste informazioni al fine di trarne risposte utili per
diversi fini. Sicuramente, l’ aspetto più tangibile e vicino a noi, che ci può permettere di
capire perché è interessante e utile tener memoria di così tante informazioni, sono le
pubblicità mirate. Immaginiamo di visitare un sito di e-commerce, cerchiamo una camicia
o una maglia, e subito quel prodotto sembra iniziare a perseguitarci ovunque andiamo: la
nostra banale ricerca di un indumento è già finita in un grande magazzino di dati, è stata
elaborata e ora è usata a nostro vantaggio (o forse svantaggio?) per adattare i pop-up
pubblicitari ai nostri interessi. Sicuramente da alcuni sarà poco apprezzata tale pratica, ma
per l’ azienda è una miniera d’ oro, perché grazie alle analisi sui dati che ha raccolto
quando effettuiamo una ricerca, ora sa come prenderci “per la gola”, consigliando prodotti
a cui siamo più probabilmente interessati. Ovviamente, più dati una azienda raccoglie e
maggiori saranno le previsioni e le stime fatte, per questo si parla di quantità veramente
grandi. Altri esempi sono forse a noi meno evidenti, ma comunque di forte impatto:
6
Twitter e Facebook (per citarne due) fanno uso di strumenti di analytics per analizzare i
milioni di tweets e posts scritti dagli utenti ogni giorno, così da capire i loro interessi e le
loro abitudini. L’ analisi, poi, potrà essere utilizzata per diversi fini, che spaziano dalla
pubblicità, ancora una volta, alla rilevazione degli influencer del web, per arrivare fino alla
lotta e al contrasto del terrorismo. Dei “semplici” post possono rilevare tanto su di noi, e
con gli strumenti giusti che lavorano ed incrociano tanti dati (eterogenei od omogenei)
queste aziende possono ottenere tante informazioni sulla nostra persona. Difatti, queste
tecnologie, grazie alla mole di dati in gioco, riescono a dare risposte anche molto accurate
a domande a cui sono interessate sia aziende private, mosse da interessi economici, che gli
stati nazionali di mezzo mondo, mossi da interessi di sicurezza (quasi sempre).
Data la maturazione dei concetti legati ai Big Data System, bisogna sottolineare come oggi
venga fatta una differenziazione basata sull’ utilizzo finale dei dati. Parliamo, infatti, di
business intelligence e big data come concetti differenti, pur avendo origini e concezioni
comuni:
•
business intelligence utilizza la statistica descrittiva con dati ad alta densità di
informazione per misurare cose, rilevare tendenze, ecc., cioè utilizza dataset limitati, dati
puliti e modelli semplici;
•
big data utilizza la statistica inferenziale e concetti di identificazione di sistemi non
lineari, per dedurre leggi (regressioni, relazioni non lineari, ed effetti causali) da grandi
insiemi di dati e per rivelare i rapporti, le dipendenze, e effettuare previsioni di risultati e
comportamenti, cioè utilizza dataset eterogenei (non correlati tra loro), dati raw e modelli
predittivi complessi.
(FONTE: https://it.wikipedia.org/wiki/Big_data#Differenze_con_business_intelligence)
Dunque, volendo tirare le somme, possiamo affermare che oggi è chiaro e comprovato che
la gestione e lo sfruttamento di dati digitali è passato dall’ essere una “competenza
importante” ad una differenziazione fondamentale e cruciale per le aziende di tutte le
dimensioni. Qualunque sia il settore aziendale di riferimento, i dati possono essere la
chiave per il successo e la crescita. Questi possono influenzare in positivo le strategie
adottate, migliorandole totalmente. Di fatti, lo sviluppo di tecnologie all’ avanguardia per i
7
Big Data System non hanno visto il solo interesse di parte di aziende dell’ IT, interessate a
creare i prodotti giusti, ma anche di quelle di molti altri settori ingolosite dalle opportunità
offerte. I Big Data hanno dato un impulso innovativo sia allo sviluppo di nuovi mercati
che nel rivalutare e modificare totalmente vecchie strategie di marketing, rendendo
obsolete le società che non hanno saputo stare al passo con l’ innovazione. I Big Data
System non sono una semplice tecnologia nata nell’ IT, bensì un connubio di interessi
sviluppatasi anche grazie all’ inflenza di altri individui ed entità dei settori dell’ economia
di mezzo mondo.
Cenni storici
Essendo i Big Data System un recente campo dell’ informatica, nato con l’avvento di un
“web per tutti”, ci si è trovati con nuove sfide da fronteggiare. Dato che si è venuto a
creare in pratica un nuovo mercato, si è assistito ad una corsa di molte aziende ad
accaparrarsene quante più quote possibili. I primi sforzi per padroneggiare tutti questi dati
furono fatti senza produrre dei veri e propri nuove soluzioni software, bensì adattando ciò
che già esisteva. Dato che, negli ultimi 30 anni, nel campo dei database erano stati i
Relational
Database
Management
(RDBMS)
System
a
farla
da
padrone, i primi approcci
alla gestione di così tanti
dati
fu
mediante
tale
tecnologia. Dopo un po’,
però,
il
paradigma
relazionale ha mostrato i suoi limiti, che non permettevano un efficace controllo, utilizzo e
memorizzazione di questa grande mole di dati. Il grande problema con il quale ci si è
presto scontrati è stata la poca scalabilità che i sistemi RDBMS hanno dimostrato: i dati
sono cresciuti troppo, i database (o almeno, quelle tecnologie) non sono riusciti a stargli
dietro. Il classico modo di pensare (radicato nella maggior parte dei developer) della
8
“tupla che raccoglie tutti i dati di un’ entità” si è rivelato poco efficace in questa
situazione, dove la grande mole di informazioni necessitava di altri tipi di trattamenti.
Inoltre, dover effettuare query era sempre più complicato, dato che i sistemi non
riuscivano a maneggiare l’ intero dataset e restituire risposte in tempi accettabili. Scalare il
sistema aggiungendo HDD e processori in più non ha dato i frutti sperati, in quanto la
potenza di calcolo arrancava ugualmente. C’era bisogno, insomma, di un nuovo approccio,
di un nuovo paradigma.
Partendo dal problema della memorizzazione, si è aperta una nuova era che ha visto la
produzione dei primi programmi software che cambiavano radicalmente approccio verso
questo aspetto. Il core e il focus di questi sistemi era proprio sullo storage, ottimizzato per
i tanti dati in gioco: nascono i sistemi database denominati NoSQL. Comunemente
chiamati anche “Not Only SQL”, queste tecnologie rappresentano dei potenti framework
applicati ai database, con approcci totalmente rivisitati rispetto a prima. Tali software
risultano delle architetture ben disposte e organizzate, specializzate proprio nella gestione
di vaste moli di dati. Questo processo è reso efficiente da una particolare differenza
rispetto ai database relazionali: la natura intrinsecamente unstructured dei dati. Questo
permette di applicare tecniche e strategie che assicurano maggior velocità di gestione e
scalabilità del sistema stesso. In tali database il crescente aumento continuo dei dati viene
dominato grazie ad una scalabilità ad approccio orizzontale, ovvero mediante l’ aggiunta
di nuove macchine al sistema. Gli strumenti software NoSQL sono stati prodotti in larga
quantità dalle più disparate aziende, tra cui le stesse che avevano particolarmente bisogno
di tali soluzioni. Ci hanno provato, tra gli altri, i grossi colossi come Amazon e Google,
che hanno presentato così i loro nuovi prodotti database. Ovviamente, la risposta del
mondo open source non ha tardato ad arrivare, così che oggi abbiamo a disposizione anche
soluzioni a codice libero. Difatto, esistono tanti software NoSQL utilizzati in vari ambiti
dei Big Data, tra i quali possiamo sicuramente citare MapReduce (by Google), Dynamo
(by Amazon), Hadoop (Apache, open source), HBase, MongoDB e Cassandra.
In questo modo, gli strumenti NoSQL sono riusciti a dare alle aziende ciò di cui avevano
bisogno per affrontare con successo le sfide dei BigData. Tuttavia, nonostante
9
teoricamente tutto sembra funzionare ed andare per il verso giusto, la pratica si è rivelata
poi molto più ostica e articolata di come ce la si aspettava. Come esposto da una fine
analisi presenta da Nathan Marz nel libro “Big Data PRINCIPLES AND BEST
PRACTICES OF SCALABLE REAL-TIME DATA SYSTEMS”, notiamo che non è oro
tutto quel che luccica. Nonostante per molte situazioni queste soluzioni siano efficaci,
bisogna comunque tener conto che i database NoSQL in generale non sono la soluzione ad
ogni problema. Il mondo dei Big Data è molto complesso e sofisticato, generalizzare per
tutti i domini un determinato prodotto software database comporta grossi limiti e freni al
progetto complessivo. Questo nuovo mondo che è nato merita e necessita di qualcosa di
più di un semplice nuovo paradigma. Una delle soluzioni ideate, tra le altre, che merita di
essere citata è sicuramente la Lampda Architecture. Esso non è un semplice database
NoSQL creato ad-hoc per gestire una grossa mole di dati, bensì è un intero approccio
nuovo al problema, che trae fondamenta sia dall’ analisi e lo studio dei limiti nati dall’
adattamento dei database relazionali alle nuove esigenze, sia da quali specifici benefici
hanno dato i database NoSQL ai Big Data System. Esso prevede un’ intera architettura ben
definita e specializzata, fondata su tre layer. Ogni layer utilizza uno specifico tipo di
database (solitamente NoSQL , in base allo scopo che deve raggiungere), ha un proprio
compito e un proprio obiettivo: questa divisione permette una separazione del dominio di
interesse (dei singoli livelli) e un maggior controllo sulla complessità totale. Infine questa
strutturazione permette un ottimo compromesso tra storage, compression, retrieval e
analisi/consumo dei dati. Il pensiero alla base è tanto semplice quanto efficace e diretto:
utilizzare solo ciò che serve dove serve, facendo il giusto uso delle tecnologie adoperate ed
eliminando ogni superficialità.
10
Capitolo 1: Il mondo dei Big Data System
Dopo la presentazione dei problemi, delle analisi, delle nuove soluzioni e degli approcci
più recenti al mondo dei Big Data, si passa in questo capitolo a descrivere e mostrare più
nel dettaglio cosa ci si aspetta da un sistema valido e correttamente progettato.
Ovviamente si partirà dalle caratteristiche necessarie a tener su l’ intera architettura, per
poi passare a due approcci riguardanti l’ organizzazione dell’ informazione: immutabilità o
incrementale? Verrà inoltre toccata il tema del data mining, discutendo principalmente di
due approcci al “popolamento del database”: ETL o ELT? Entrambi saranno descritti e
proposti, e sarà fatto notare come entrambi siano validi, purchè applicati nella giusta
situazione. Infine sarà discussa la scalabilità che permette un sistema BigData, proprietà
concessa solo previa una buona progettazione, fatta seguendo pratiche e tecniche oggi
ampiamente diffuse, apprezzate e validate.
1.1 Le caratteristiche di un buon Big Data System
I nuovi software NoSQL prodotti appositamente per i sistemi Big Data sono nati da studi e
analisi effettuate sul problema e i limiti riscontrati precedentemente. Queste analisi hanno
permesso di individuare della caratteristiche o proprietà che un Big Data System deve
possedere, affinché porti a buon fine il proprio compito. Queste caratteristiche sono
ovviamente differenti rispetto alle necessità dei sistemi relazionali. Oltre alla scalabilità e
alla complessità (da tenere sotto controllo) che ho già accennato precedentemente,
necessitiamo di:
•
Robustezza e fault tolerance: è fondamentale che il sistema sia capace di “resistere”
ad errori umani, ad errori dovuti a problemi HW delle macchine, e ad errori che possono
compromettere la consistenza dell’ intero dataset;
•
bassa latenza per consumare e aggiornare i dati: nei Big Data si ha a che fare con
una spaventosa mole di dati, che arriva di continuo e fa crescere sempre più il dataset. Il
nostro sistema deve essere in grado di darci risposte esaustive in tempo ragionevole,
11
interrogando l’ intera base di dati;
•
scalabilità e estendibilità: il continuo aumento del dataset richiederà che di volta in
volta il nostro sistema andrà scalato, aumentando il numero di macchine nel cluster che lo
tiene in attività; è quindi importante che il sistema abbia una certa elasticità per queste
operazioni. Inoltre, l’aggiunta di feature al sistema sarà continua data l’ eterogeneità dei
dati, sui quali potrebbero variare di continuo le richieste di chi ne usufruisce;
•
manutenzione e debuggability: infine, un sistema così grande e articolato necessiterà
di essere incline ad una facile manutenzione, facilitando la fase di debug che molto spesso
è complicata da fare in un dataset anche relazionale.
Tutto ciò concorre alla produzione di un sistema strutturato, ben definito e valido nella
maggior parte delle situazioni. Se queste proprietà sono rispettate e seguite con successo, il
dataset sarà realizzato correttamente, la sua memorizzazione avverrà con successo e
potremo aggiungere di continuo features alla architettura che stiamo adoperando.
1.2 Immutabilità vs. Paradigma Incrementale
Nei sistemi Big Data troviamo enormi quantità di bit che vengono prodotti continuamente
e che necessitano di essere memorizzati adeguatamente. Nasce quindi spontanea una
domanda: come evolve il dataset in funzione di ciò? Andando a sviscerare l’ argomento e
tentando quindi di trovare una risposta, si scopre che u ruolo importante lo gioca il Data
Model. Per Data Model si intende la rappresentazione logica di come le informazioni sono
organizzate e rappresentate, ma ciò influisce anche su come avverrà il processo fisico di
memorizzazione dei dati. La scuola di pensiero legata al mondo relazionale adopera il
cosiddetto paradigma incrementale. Con tale termine si intende la pratica (molto diffusa
tra i developer di lungo corso) di utilizzare una tupla con le informazioni legate ad una
entità; quando un’ informazione viene aggiornata vi sarà un’ operazione di update su tale
tupla, che comporterà una sostituzione del vecchio dato con il nuovo. Da qui il nome, che
mostra per l’ appunto questa evoluzione incrementale che avviene. Tale sviluppo delle
informazioni fa si che queste rappresentino un vero e proprio stato in cui il sistema si trova
di volta in volta. Questo approccio è risultato obsoleto, invece, con i sistemi Big Data. Le
12
nuove necessità si scontravano ampiamente con questo punto di vista. In questi sistemi
infatti si utilizza un paradigma che rispetta una proprietà cruciale: l’ immutabilità dei dati.
Questo vuol dire che al centro del dataset non troviamo più una differenziazione e
rappresentazione per “entità” del dominio di interesse, bensì l’ informazione stessa. La
classica tabella, che prima conteneva le informazioni di tutte le entità dello stesso tipo
(insieme), viene ora vista spezzata in più tabelle, addirittura una per ogni colonna prima
memorizzata. Il dato viene visto nella sua versione più atomica possibile. Ad ogni
aggiornamento o modifica di un’ informazione già memorizzata, non si andranno più ad
eseguire degli update, ma dei nuovi inserimenti di records. Questi saranno corredati di un
timestamp, che permetterà di organizzare l’ informazione e tener traccia di come essa è
cambiata di volta in volta. Questo nuovo approccio permette di rispettare l’ immutabilità
dei dati e di poter beneficiare di varie “features”. Ad esempio, se in produzione viene fatto
il deploy di un bug che “sporca” la base di dati, sarà possibile tornare in modo naturale ad
una vecchia informazione nel dataset, eliminando quella sporcata. Altro aspetto cruciale è
il notevole aumento della resistenza ad errori umani, che possono essere eliminati
rimuovendo semplicemente i records incriminati. In entrambi i casi, si continuerà ad avere
un’ informazione valida; sicuramente si è persa l’ informazione più aggiornata, ma ciò che
resta è comunque vero: il timestamp stesso permetterà di dire che in quel determinato
istante quella tupla rappresentava una verità.
1.3 I limiti dello scaling
Quando ci si trova difronte ad un sistema che inizia ad arrancare nel proprio compito, si è
subito portati ad aumentarne le qualità tecniche, quali potenza di calcolo e storage.
Applicare questa tecnica ai RDBMS, per aumentarne l’ efficienza con i Big Data, si è
rivelato inutile: sia uno scaling verticale (aumentare CPU e HDD nelle macchine) che uno
orizzontale (più macchine unite a cluster) non hanno dato le risposte che ci si aspettava.
Questo è dovuto alla natura stessa dei Big Data: questi sistemi, oltre a memorizzare tanta
informazione, ne ricevono anche di continuo, portando ad una serie di difficoltà da
affrontare. Aumentare il numero di macchine disponibili nel cluster (il cosiddetto
13
sharding) ha solo aumentato la complessità dell’ intero sistema, comportando cosi il
sopraggiungere di nuovi problemi. Più macchine, ad esempio, vuol dire più hardware, e
quindi più probabilità di una rottura di questi: diminuisce il fault-tolerance generale.
Inoltre, tutti i dati che “arrivano, restano e vengono consumati” nella base di dati sono
soggetti a una facile corruzione se per sbaglio viene fatto il deploy in produzione di un bug
software che ne compromette la consistenza. Infine, l’ ennesimo grande problema che si
manifesta è la poca tolleranza agli errori umani. Questi sono molto frequenti e comuni, e
sono dovuti sia ad errori in scrittura nel database sia ai programmi software che
dovrebbero
validare
i
dati
prima
della
memorizzazione.
Tutto ciò ha reso l’ uso dei vecchi RDBMS impossibile nei Big Data System, e ha
spronato gli sviluppatori a cercare e realizzare le nuove soluzioni che oggi permettono di
assolvere a tutti i compiti necessari in questo nuovo mondo.
1.4 Data Extraction: ETL o ELT?
Come abbiamo visto, una delle implementazioni pratiche di un sistema BigData riguarda
le gestione di dati (personali e non) a fini statistici o analisi. Il primo passo nel
popolamento del database comporta il retrieval o la produzione dei dati. Una tecnica
utilizzata è la cosiddetta Web Scraping, che comporta la creazione di software (ad es.
parser) che girano per le pagine web dove carpire e raccogliere dei dati di interesse.
Ovviamente, prima di essere immessi nel dataset, questi andranno controllati e
eventualmente riformattati secondo una certa direttiva. Questa serie di operazioni, che
parte dal reperire i dati e finisce con l’ inserimento nel nuovo database, è detta ETL:
Extraction,
Trasformation
e
Load.
Nello specifico, queste fasi operano sui dati nel seguente modo:
•
estrazione dei dati: solitamente le sorgenti più usate sono pagine web, pdf,
14
documenti di word oppure database pre-esistenti. I dati vengono raccolti e convertiti
affinché possano entrare a far parte tutti dello stessa data warehouse;
•
trasformazione dei dati: una volta estratti, solitamente ci si trova davanti dei dati
grezzi, quasi sempre senza una struttura. Oltre a fornire una struttura comune e dei
metadati correlati, in questa fase si applicano azioni di derivazione, sorting, filtraggio, join
e disjoin in più o meno colonne. Questo, ovviamente, dipenderà dalle direttive con il quale
è stato formulato il nuovo dataset;
•
caricamento dei dati: solo a questo punto i dati possono essere caricati, passando per
repository temporanee oppure direttamente nel dataset finale.
1.4.1 Un approccio alternativo: ELT
ETL è di uso comune e quindi abbastanza diffuso. Nel mondo dei Big Data System, però,
in contrapposizione a questo ciclo vi è un approccio simile, ma per nulla uguale : ELT.
L’approccio ELT prevede una fase di LOAD prima della TRASFORMATION, che
risultano quindi scambiate in ordine. La fase di load, in questo caso, prevede il trasporto di
dati
in
tabelle di supporto. I dati grezzi, senza alcuna modifica, vengono prima trasferiti in una
locazione temporanea. Successivamente, da questa locazione saranno prelevati, trasformati
e inseriti nel dataset definitivo. Questo approccio risulta particolarmente positivo quando
si ha a che fare con grossi moli di dati: non viene “infastidita” di continuo la sorgente con
retrieval e trasformation, ma solo con un processo di copia. Questo può essere molto
vantaggioso quando la sorgente è su un server di produzione, in quanto si evita un calo
delle performace agli utenti utilizzatori del servizio. In questo modo, inoltre, oltre il mero
processo di copia dei raw data, è possiile utilizzare diversi linguaggi ottimizzati, come TSQL, per una trasformazione efficiente e vantaggiosa dei dati, con conseguente load nel
15
database finale. È possibile affermare che un approccio ELT risulta vantaggioso su uno
ETL nei seguenti casi:
•
vi sono in gioco grosse moli di dati;
•
il database sorgente e il database destinatario risultano gli stessi o sono sulla stessa
macchina (magari anche di produzione);
•
il database engine è specializzato nel trasporto di dati di dimensioni massicce in
tempi rapidi.
In breve, le tecniche ETL prevedono l’ aggravo delle operazioni sulla macchina sorgente,
mentre i processi ELT spostano il carico sul target. Di contro, ELT necessiterà di più
memoria per essere portato a termine. Questo è dovuto alle tabelle di supporto utilizzate
temporaneamente. In base alle situazioni e valutando i vari casi, può essere utile scegliere
ELT al posto di ETL.
16
Capitolo 2: Apache Hadoop
Il primo capitolo ha fatto da introduzione al mondo dei Big Data System. Dopo averne
visto storia, problemi e potenzialità, si andrà in questo capitolo a trattare un prodotto reale.
Come abbiamo visto, molte sono le sfide nate dallo storage di così tanti dati, mai visti
prima. Come si sono mossi gli sviluppatori? Quali aziende sono entrate in questo nuovo
mercato e con quali prodotti? Nello specifico, lo strumento in questione si chiama Apache
Hadoop. Si tratta di un software molto potente e versatile, mantenuto e sviluppato oggi da
Apache, una garanzia in merito a codice open source. Esso prevede un’ intera architettura
composta da più moduli, che insieme garantiscono ottime performance e rendimenti. Due
di questi moduli, quali un file system e un meccanismo di computazione distribuiti,
saranno discussi e approfonditi maggiormente nei prossimi paragrafi e in quelli del
capitolo seguente. La sfida principale che è stata affrontata, come vedremo, riguarda lo
storage: con che tecnologia e in che modo tengo memoria di questa vasta mole di dati?
Come posso rendere il tutto il più trasparente possibile ai developer? Queste sono due
delle domande a cui sarà trovata risposta. Ovviamente, date le dimensioni dei dataset e
quindi delle potente richieste per i calcoli, si vedrà che si sfruttano molteplici macchine
collegate come un unico cluster in rete. Una architettura così fatta si rende necessaria per
dominare la complessità e fornire la potenza necessaria a supportare un sistema BigData.
Inoltre, verrà mostrato ciò che comporta questo approccio e come sono stati risolti sia i
problemi di comunicazione che quelli di gestione e storage dei dati tra le varie macchine.
Infine, una volta “sistemato” il problema dello storage, sarà affrontata la questione della
parallel computation, resa necessaria in una architettura che si basa su più macchine poste
in cluster di rete per distribuire efficacemente il carico di lavoro.
Il tutto sarà affrontato riferendosi in particolare a due componenti della soluzione software
chiamata Apache Hadoop: il file system HDFS (Hadoop Distributed File System), per la
memorizzazione dei dati, e MapReduce, per la parallelizzazione delle operazioni.
2.1 Una soluzione: Apache Hadoop
17
Apache
Hadoop
framework
è
open
un
source
mantenuto oggi da Apache.
Esso
Doug
venne
realizzato
Cutting
e
da
Mike
Cafarella nel lontano 2002,
all’ Università di Washington. Inizialmente, gli fu dato il nome di Nutch. A quei tempi, il
mondo di internet era alla ricerca di un nuovo motore di ricerca. Hadoop, infatti, nacque
con questo scopo, assolutamente opposto a ciò per cui è usato oggi.
Nel 2006 Cutting fu assunto da Yahoo! che, partendo da papers di ricerca rilasciati da
Google sui BigData System, volle smantellare Nutch e prenderne parte dei componenti.
Dalle ceneri di questi nacque Hadoop.
Oggi, nel mondo dell’ IT, molte grandi aziende adoperano Hadoop. Le recenti statistiche
parlano, in particolare, di Facebook, Ebay, Yahoo, Yelp e Twitter. Tutte sfruttano le sue
caratteristiche di analisi ed elaborazione dei BigData per le proprie necessità.
Il progetto Hadoop fa parte del mondo dello sviluppo di codice libero, e le principali
features offerte si focalizzano su una elaborazione distribuita affidabile e scalabile. Esso
prevede la possibilità di realizzare cluster di macchine senza preoccuparsi del numero
effettivo, che può essere di una come di migliaia di server tutti connessi. Il framework si
preoccuperà di collegare il tutto e smistare il lavoro, così da ottenere un sistema di
parallelizzazione e distribuzione delle operazioni da effettuare. Il progetto è formato da
diversi moduli e plugin, quali Hadoop Common, Hadoop Distributed File System, Hadoop
Yarn e Hadoop MapReduce. Il framework mette a disposizione una piattaforma per lo
sviluppo e il deploy di applicazioni che possono lavorare in parallelo su dataset molto
vasti, esonerando il developer dal compito di occuparsi di come avviene la
parallelizzazione stessa e la comunicazione tre le macchine. Infine, particolare attenzione è
data alla tolleranza ad errori hardware di una macchina del cluster, tramite tecniche di
isolamento del nodo incriminato e metodi di ridondanza che permettono di tenere più
copie dei dati, in previsione di perdite di questo tipo.
18
2.3 Storage in un sistema Big Data
Nel primo capitolo è stato affrontato il tema dell’ immutabilità dei dati, particolarmente
rilevante quando si parla di Big Data System. Ciò porta ad analizzare un altro aspetto
cruciale nello sviluppo di queste architetture: la tecnologia di storage adoperata. Come
visto precedentemente, le soluzioni offerte dai sistemi Relation Database Management
(RDBMS) risultano inefficaci, dato che l’ enorme mole di dati non può essere gestita come
da essi fatto. Per affrontare il discorso, bisogna condurre uno studio sia sul dataset che sul
Data Model della base di dati, i quali influenza fortemente la decisione finale. L’ aspetto
da valutare si basa sul tipo di operazioni che è necessario fare sul disco: si parla
ovviamente di lettura e scrittura dei dati. Sia per quanto riguarda una write che per quanto
riguarda una read, sostanzialmente due sono gli approcci che vanno analizzati:
accesso/scrittura casuale oppure accesso/scrittura sequenziale. La prima opzione
garantisce che, ovunque siano posizionati i dati all’ interno del disco, essi siano
raggiungibili con egual costo. Un po’ come avviene in una struttura array. Ma questa
efficacia si traduce realmente in benefici per i sistemi in studio che ospiteranno una grossa
quantità di dati? In un grande data warehouse (magazzino di dati), di cosa si necessita? La
situazione è la seguente: di continuo arrivano nuovi dati (e ne arrivano tanti in poco
tempo) che necessitano di essere “appesi”, aggiunti alla grande massa di informazioni già
presente. Di fatti, come visto prima si segue il principio dell’ immutabilità: non si andrà
(quasi) mai ad eliminare dell’ informazione, piuttosto se ne aggiunge. Quando si vuole
effettuare un’ interrogazione, inoltre, l’ interesse volge all’ intera base di dati, e non a
parte di essa. Difatti, va interrogata e sfruttata da inizio a fine, tutto il dataset. Quando si
tratta di analisi statistiche per conto di aziende pubblicitarie, oppure seguire se un trend
viene apprezzato o meno, non avrebbe senso dare risposta su una parte dei dati, bensì si
vuole ridurre al minimo l’ incertezza e l’ errore. Di conseguenza, non si cerca
assolutamente uno storage ad accesso casuale, che non porterebbe beneficio alcuno.
Ricapitolando, si necessita di:
•
un rapido append in fase di write;
•
una certa dimistichezza alla scalabilità, sempre più dati entreranno, bisogna poter
19
facilmente aggiungere nuovo spazio;
•
operazioni di read per lo più sequenziali, che interessano l’ intero dataset;
•
sistemi di tuning dello spazio stesso, con possibilità di effettuare compressioni e
decompressioni utili con le dimensioni dei dati in ballo.
Tutto ciò porta all’ individuazione della soluzione più naturale di tutte: i filesystem,
ovviamente distribuiti.
2.3.1 Filesystem distribuiti
Una gestione a file calza totalmente con i bisogni di un sistema che gestisce grandi
dimensioni di dati. Difatti, una scrittura con append è impiegata naturalmente nei
filesystem. D’ altro canto, anche la lettura, che è fatta sequenzialmente su dati scritti in
append, rispecchia positivamente quanto richiesto. Inoltre, i file system prevedono tante
funzionalità che trovano impiego nei Big Data System, quali permessi sui dati, cifratura e
compressione (con relativa decompressione). Quest’ ultima si rivela particolarmente di
valore, in quanti in un sistema con tanti dati disparati, che aumentano di continuo e che
effettua molte append a file già esistenti, poter anche effettuare manutenzione con
compressione e decompressione diventa un vero e proprio must-have per lo sviluppatore.
Tutto ciò concorre a realizzare un vero insieme di strumenti di tuning e manutenzione, che
facilitano il compito dell’ uomo e permette di mantenere il sistema in uno stato di salute
continuo. Ovviamente, in questi casi non si parla di file system locali su macchine locali,
bensì di file system distribuiti che gestisono i dati e lo storage tramite più macchine che
fanno da nodi in un cluster di rete. Molti sono gli aspetti a cui un file system distribuito
deve badare a differenza del suo fratello minore. In particolare, è possibile citare
trasparenza e concorrenza. L’ utente, o un qualsiasi processo, che chiede di accedere ai
dati deve poterlo fare senza preoccuparsi degli aspetti tecnici che comporta la
memorizzazione sul cluster. Su quale nodo è memorizzato il dato o se intanto vi ci sta
accedendo qualcun altro non deve essere un pensiero dell’ utilizzatore finale, bensì del file
system stesso. Infatti, oltre le normali primitive e funzioni che ha qualsiasi filesystem, uno
distribuito deve anche occuparsi di scegliere la macchina dove memorizzare un nuovo
20
dato, in quante e quali copie memorizzarlo, ricomporre l’ informazione se una macchina
ha un errore HW che ne compromette l’ integrità, e deve, inoltre, preoccuparsi di creare
una infrastruttura di livello superiore che permette di vedere tutto lo spazio del cluster
come tutt’ uno. Essendo poi queste macchine in rete, altre problematiche comuni si
aggiungono: occuparsi di un nodo che non risponde o di un nodo cade ricade sempre sul
file system.
2.3.2 Problemi comuni
Ovviamente, come tutte le tecnologie, anche i file system distribuiti non sono esenti da
problemi e disagi. I filesystem distribuiti solitamente dividono i file in chunks, ovvero
blocchi di dimensione fissa memorizzati sulle macchine del cluster. Per quanto efficiente
sia questa procedura, è stato anche detto che, seguendo il principio di immutabilità dei
dati, si ha sempre nuova informazione da appendere a quella già esistente. Di
conseguenza, il BigData System non chiederà quasi mai al proprio file system di operare
una delete o update sui dati (e chunks) già memorizzati. Altro punto su cui riflettere:
quando arriva nuova informazione e viene appesa, molto spesso questa è di dimensione
inferiore ai chunks regolari. Si viene così a creare col tempo un problema di
frammentazione dei dati, che regolarmente va risolto con delle operazioni di tuning che
effettuano una compattazione e ricostruzione dei chunks memorizzati. I file system, in
particolare quelli ideati per le piattaforme di BigData, prevedono delle operazioni di
deframmentazione dei dati, volte a ripristinare quanto possibile delle performance nel
retrival dei dati dal disco. Ovviamente, questa operazione porta via tempo e risorse della
macchina, che potrebbe risultare anche offline per l’ intera operazione. Se, infatti, si pensa
a tutti i dati e chunks da muovere, si può subito intuire quanto sia esosa una operazione di
tale portata. Inoltre, bisogna tener sempre a mente che queste macchine sono in rete, per
cui probabilmente la deframmentazione non dovrà solo spostare i dati nell’ HDD di una
macchina, ma anche tra i nodi stessi. La rete, di fatti, può costituire un altro deterrente all’
intera operazione. I problemi, purtroppo, non finiscono qua: si pensi alla situazione in cui
si esegue sull’ intero dataset una query in cui è presente una clausola restrittiva (ad
21
esempio un where). In un DBMS relazionale, la struttura tabellare dell’ informazione
permette velocemente di “tagliare” i dati restituendo quanto richiesto. Qui, invece, si ha un
enorme dataset fatto di moltissimi bit, sparsi in rete. Una soluzione è, ovviamente, scorrere
tutti i bit del file system, reperire i dati e poi tagliare quelli che non interessano. Questo è
molto esoso, sia per quanto riguarda il tempo necessario che per quanto riguarda la
memoria utilizzata. Un possibile approccio risolutivo del problema è il cosiddetto vertical
partitioning. Nei Big Data System si ha un dataset in cui, come detto prima, al centro vi è
l’ informazione stessa, e non la tupla che rappresenta un’ entità. Di conseguenza, è
possibile pensare di organizzare il file system in cartelle che, a partire dalla root, divide l’
informazione in base al contenuto, oppure la raggruppa tenendo conto delle query più
frequenti che vengono eseguite sul dataset. Questa soluzione è implementata da molti file
system distribuiti specializzati in BigData, ed è una operazione ad alto livello che prevede
la conoscenza del data model del sistema. La struttura delle cartelle permette di navigare
più velocemente tra i dati, e di conseguenza l’ esecuzione delle query dette prima ne trae
enormi benefici.
Infine, è possibile analizzare e riflettere sull’ approccio di basso livello offerto dai
filesystem distribuiti. Come visto prima, questa tecnologia era preesistente ai Big Data
System. Ad esempio, vi erano prodotti come NFS ( di Sun Microsystem), AFS (sviluppato
dalla dalla Carnegie Mellon University) e CIFS. Quando essi sono stati impiegati per le
basi di dati si è notato come le loro API rappresentavano un accesso troppo grezzo al
sistema di archiviazione. Questo portava a molte problematiche a cui badare nella scrittura
del software di sistema. Difatti, questo rappresentava una vera complicazione per i
developer nello sviluppo dei loro applicativi software.
Tutto ciò ha portato alla scrittura di nuovi prodotti, basati su filesystem distribuiti e
specializzati nella gestione di grandi moli di dati. Quello di cui i developer chiedevano era
sicuramente delle interfacce di utilizzo ed accesso complete ai dati mediante API di alto
livello, meccanismi di tuning del sistema in modo tale da tenerlo sempre efficiente e
strumenti di manutenzione in modo da mantenere costantemente valido il rapporto
performance/spazio occupato.
22
2.3.3 Hadoop Distributed FileSystem
Una soluzione molto valida, realizzata da Apache ed open source, è Hadoop Distributed
File System. Esso fa parte dell’ architettura Hadoop, software realizzato in Java
specializzato nella gestione di BigData. Hadoop, in particolare, implementa l’ HDFS su
tutte le macchine del cluster, il quale si occuperà di offrire un servizio di storage
trasparente ed efficace
per memorizzare tutti i
bit del dataset.
HDFS gestisce il cluster
dividendo le macchine in
due
nodi,
denominati
namenode e datanode. Il
primo è una sorta di
database,
che
tiene
traccia delle posizioni dei
vari pezzi di ogni file, mentre il secondo tipo di nodo memorizza i dati veri e propri.
Questi pezzi di file sono detti chunk, hanno una dimensione fissa configurabile e sono
solitamente replicati su più macchine. Quando un nuovo file deve essere memorizzato,
Hadoop segna nel Namenode su quali Datanode memorizzerà i chunks, ed eventualmente
quante ridondanze genera. Quando viene richiesto l’accesso ad un file, Hadoop dovrà
semplicemente contattare il namenode per ottenere la lista dei chunk con relative
macchine che li ospitano. Vari sono i benefici che porta con sé questa tecnica: se una
macchina è offline (per manutenzione o problemi) si hanno copie dei chunk su altri nodi,
una distribuzione su più macchine dei file facilità una computazione parallela (molto
importante sui grandi dataset), infine si ha una facile scalabilità aggiungendo nuove
macchine e notificando ad Hadoop la disponibilità di nuove.
23
2.4 Data Computation
Come visto fin’ ora, qualsiasi sistema Big Data, per la sua natura intrinseca, si appoggia su
cluster di macchine in rete. Tra i principali vantaggi che questo porta bisogna menzionare
sicuramente la possibilità di ampliare il parco nodi (e di conseguenza lo spazio e la
potenza di calcolo disponibili) e la naturale parallelizzazione dei calcoli effettuati. Infatti,
essendo i dati sparsi per la rete, si necessita di una piattaforma di elaborazione centrale che
organizza le varie macchine e le coordina per le operazioni di computazione necessarie.
Quindi, come ottenere i vantaggi della parallelizzazione senza gravare troppo sui compiti
del developer? Si necessita di qualcosa che solleva lo sviluppatore da questi oneri e che si
occupi in modo automatico di tali processi. L’ infrastruttura Hadoop, di cui è stato già
descritto il file system, è corredata di uno strumento che permette quanto appena descritto.
Questo strumento si chiama MapReduce.
2.5 MapReduce
MapReduce
è
framework
realizzato
di
un
Google
appositamente
per i data warehouse. La
sua peculiarità è la capacità
di parallelizzare calcoli e
lavoro
sulle
disponibili,
adattarsi
macchine
nonché
di
autonomamente
all’ ampliamento del sistema e all’ aggiunta di nuovi elaboratori. Il nome rappresenta
proprio le due funzioni che esso esegue: Map e Reduce. La funzione di map prende in
input l’ intero dataset o una sua parte, in base a ciò di cui necessita l’ elaborazione. Lo
script di Map viene distribuito sulle varie macchine della rete, che la eseguiranno sulla
parte di dataset che ospitano. Questa scelta si basa su una semplice osservazione: i Big
Data system ospitano enormi quantità di dati, impossibili da muovere sulla rete ogni volta
24
che si necessita di una computazione. Meglio, difatti, spostare la funzione di Map.
Solitamente, la funzione di map esegue una emit dei dati in ingresso, basata sullo scopo
dell’ elaborazione. Una volta completate tutte queste esecuzioni, la macchina centrale
delegata a dirigere le operazioni muove i risultati delle singole funzioni di Map sulle
macchine destinate alla funzione di Reduce. Questa, infatti, è eseguita solitamente su un
sottoinsieme delle macchine disponibili. La funzione di Reduce riorganizza e ordina le
chiavi, in modo tale da avere vicine quelle uguali. Successivamente, visita la struttura Map
che ha in ingresso e accorpa i valori, così da restituire in output una struttura con i risultati
finali della computazione.
Nell’ esempio più classico, il “contatore di parole”, vengono eseguiti i seguenti passaggi:
1.
la funzione di map riceve in ingresso un testo;
2.
per ogni riga conta il numero di parole;
3.
per ogni parola effettua una emit key/value che ha per chiave la parola stessa e per
valore 1;
4.
si scelgono quali macchine eseguiranno la funzione Reduce. Solitamente si utilizza
una macchina per ogni chiave;
5.
le macchine scelte visitano le Map ricevute e conteranno le occorrenze per la parola
delegatagli;
6.
infine, i risultati dei singoli Reduce saranno inviati al nodo centrale che presenterà
così l’ output finale che prevede una struttura map con le parole come chiavi e le loro
occorrenze totali come valori.
Un’ ottima analogia per capire come agisce il framework di MapReduce può essere ciò
che facevano i funzionari romani per contare la popolazione dell’ impero. Il censimento
era gestito da un bureau centrale che dirigeva le operazioni: venivano aperti uffici di
censimento in ogni città conquistata, delegati a contare la popolazione locale, questi poi
mandavano i risultati alla città centrale e successivamente la capitale riduceva i risultati a
un conto unico per stimale la popolazione complessiva dell’ impero. Era molto più
semplice di mandare una singola persona a contare la popolazione in giro per l’ intero
impero!
25
MapReduce, in unione con HDFS, lavora sul cluster di macchine dirigendo le operazioni
da fare. In particolare, quando viene richiesta una computazione, il nodo centrale contatta i
nodename per scoprire dove risiedono i chunks necessari, successivamente avvia tanti task
Map in proporzione alla grandezza dell’ input. Anche in questo caso avere tanti file di
piccole dimensioni porta a scompensi nell’ elaborazione: saranno necessari più task map
del dovuto. Una volta che le strutture Map sono tutte complete, e solo ad allora, il nodo
centrale fa un rapido check della rete e della situazione: ora dovrà individuare le macchine
da utilizzare per la funzione Reduce. In questo caso, ci saranno dei dati da spostare in rete
(ovvero l’output delle funzioni Map), per cui ci saranno diverse valutazioni correlate da
fare. Ora, però, l’ operazione di spostamento dei dati è più fattibile in quanto gli output
prodotti dalle funzioni Map non sono estesi quanto l’ intero dataset. Una volta individuate
le macchine che eseguiranno il processo successivo, queste saranno provviste delle Map
necessarie alle loro elaborazioni, solitamente assegnando un task Reduce per ogni key
univoca presente in esse. Infine, l’ elaborazione e l’ output finale saranno restituiti al nodo
centrale che potrà così presentare il risultato della computazione. Un approccio così fatto
permette una certa efficienza su grandi dimensioni di dati, dando la possibilità di
mantenere performance elevate aumentando i nodi elaboratori all’ interno del cluster.
26
Capitolo 3: Apache Pig
Il terzo capitolo entra nel merito per quanto riguarda uno strumento di analisi realmente
adoperato. Si tratta di Apache Pig, sviluppato dalla stessa azienda di Hadoop come il nome
suggerisce. Esso si appoggia sull’ infrastruttura presentata nel precedente capitolo,
sfruttandone file system e il sistema di esecuzione parallela di MapReduce tasks. Come
vedremo, esso propone al developer un sistema di compilazione di codice di alto livello,
permettendo una traduzione in codice Java per MapReduce. Questo porta enormi benefici
al developer, dovuti sia alla natura procedurale del linguaggio offerto sia alla potenza di
espressività e controllo sugli operatori e implementazioni built-in già presenti. Il
linugaggio che la piattaforma permette di utilizzare si chiama Pig Latin: saranno presentati
pro e contro, features che lo particolarizzano e sarà fatta un’ analisi di confronto con il ben
più noto SQL.
3.1 Apache Pig
Un freno all’ utilizzo di MapReduce in modo diretto (crudo, o “standalone”) è
rappresentato dalle sue API. Esse, infatti, sono realizzate in Java e possono risultare così
ostiche e scomode per alcuni sviluppatori poco familiari con l’ approccio OOP (object
oriented programming). A supporto dei programmatori però sono state realizzate varie
piattaforme e framework, come ad esempio Apache Pig.
Pig è una piattaforma nata nel 2006 in Yahoo! e successivamente nel 2007 trasferita nel
progetto di Apache Software Foundation. Essa venne realizzata per l’ analisi e la
computazione su dataset molto vasti. È parte integrante del framework Hadoop. Pig
permette l’ esecuzione delle operazioni sfruttando layer sottostanti come MapReduce,
Apache Tez o Apache Spark. La piattaforma PIG mette a disposizione un linguaggio
procedurale all’ utente. Il compilatore di cui è provvista elabora il codice suddividendolo
in tanti Hadoop Jobs, realizzati ad esempio in MapReduce. Il linguaggio procedurale
messo a disposizione si chiama Pig Latin, è procedurale ed offre sia funzioni built-in che
27
un sistema estendibile, grazie al quale l’ utente può definire delle proprie funzioni. L’
input di questi programmi sono solitamente grosse moli di dati, mentre l’ output viene
raccolto dagli Hadoop Jobs e memorizzato sfruttando il file system installato (che
potrebbere essere stesso HDFS). Il compilatore precedentemente nominato produce e
organizza gli output delle funzioni di MapReduce e offre dei tools di ottimizzazione del
codice.
3.2 Pig Latin
Pig Latin è il linguaggio di programmazione offerto dalla piattaforma Apache Pig. Esso
offre sia una serie di funzioni base, sia la possibilità di estendere il sistema e definirne di
nuove. Queste sono chiamate User defined functions (UDF). Esso permette di manipolare
con facilità grandi moli di dati e ottenere in output il risultato delle elaborazioni fatte
mediante il layer sottostante. Uno di questi layer può essere MapReduce. Pig Latin
produce codice Java per conto del developer, a cui può risultare difficoltoso, permettendo
agilità nella scrittura delle applicazioni. Apache Pig è responsabile della conversione del
codice Pig in task MapReduce.
3.3 Perché usare PigLatin
Il linguaggio Java di MapReduce può essere un ostacolo per alcuni programmatori,
specialmente per chi non è familiare al mondo OOP. Inoltre, Pig Latin offre anche altri
aspetti che fanno propendere per il suo impiego:
•
Pig Latin offre un approccio multi-query: questo vuol dire che mentre in Java alcune
funzioni necessitano di molte LoC (linee di codice) per essere definite, in Pig Latin si
necessita di molte meno per effettuare le stesse operazioni. Questo riduce notevolmente il
tempo di sviluppo di software;
•
Pig Latin è un linguaggio SQL-like, così da risultare di facile utilizzo a chi ha già
conosciuto il mondo relazionale;
•
Pig Latin offre di base molti operatori e funzioni per le query, come filtri, join, e
ordinamenti. Inoltre, esso offre strutture dati particolari come tuple, bags e mappe che
28
risultano assenti in MapReduce;
3.4 Features del linguaggio
Le features che questo linguaggio offre sono numerose. Sicuramente, bisogna citare in
particolare:
•
un set di operatori molto corposo, per eseguire funzioni anche complesse in poco
codice;
•
facile usabilità, essendo esso molto simile al tanto noto SQL;
•
forte ottimizzazione, grazie a dei tools interni che permettono di migliorare il codice
e gli Hadoop Jobs prodotti, così che il developer debba preoccuparsi solamente della
semantica del linguaggio;
•
estendibilità, offerta dalla possibilità per l’utente di realizzare delle funzioni proprie
e di richiamarle nelle applicazioni che realizza;
•
UDF, che permette non solo di estendere le funzionalità ma anche di importare
codice scritto con altri linguaggi come Java o Phyton;
•
gestione completa dei dati, siano essi in forma sia strutturata che non strutturata.
3.5 Pig vs. SQL
Nello sviluppo di query ad un dataset si è quasi sempre portati ad utilizzare SQL,
linguaggio ampiamente conosciuto e padroneggiato dai developer di tutto il mondo.
Analizzando però affondo ciò che avviene nella stesura ed esecuzione di una data pipeline,
possiamo notare come questa scelta non è sempre conveniente. Per data pipeline, qui e
nelle righe a seguire, si intende una serie di operazioni che vanno dalla lettura dei dati alla
produzione di un output valido, passando per la loro trasformazione. I motivi per cui il
linguaggio Pig è da preferire, in particolar modo quando si parla di bigdata, possono essere
riassunti nel seguenti punti:
•
Pig Latin è procedurale, mentre Sql dichiarativo;
•
Pig permette ai developer di scegliere dove fissare dei checkpoint nel loro flow di
lavoro;
29
•
Pig permette di specificare quali operatori e implementazioni utilizzare nel load e
trasformation dei dati;
•
Pig supporta lo split della pipeline;
•
Pig permette di inserire codice quasi ovunque all’ interno del listato;
Di seguito verranno ora analizzati punto per punto e discussi i su detti aspetti.
Pig Latin è procedurale, mentre SQL è dichiarativo. Questo obbliga il developer a seguire
determinate strutture nella dichiarazione della query. Ad esempio, un FROM segue un
SELECT mentre un WHERE segue un FROM e così via. Questo porta alla generazione di
un set di operazioni disgiunte, in cui sarà il motore del DBMS a scegliere come
organizzare e ottenere i dati dalle varie tabelle. In Pig, invece, il developer ha il controllo
sul retrieve di ogni porzione di dati, il che gli permette di gestirlo e organizzarlo come
vuole. Ancora, la rigida struttura della query non ne permette una facile inquadratura,
rendendo difficile la lettura del data flow. Invece, la natura simile ad un linguaggio di
programmazione di Pig permette di creare un codice ben strutturato e espressivo,
concedendo coì al developer la possibilità di una pulita definizione dell’ intero listato.
Pig permette ai developer di scegliere dove fissare dei checkpoint nel loro workflow.
Immaginiamo la scrittura di una query in cui siano presenti dei JOIN da varie tabelle. Il
developer non ha il controllo sul set di dati prodotti, se non alla fine della query con il
risultato in output. Difatti, se qualcosa non va bene lo noterà soltanto nell’ output, non può
controllare prima la data pipeline poiché il controllo lo ha il motore SQL. La soluzione
sarebbe creare tante tabelle temporanee o materializzate da utilizzare, che complica sia la
vita all’ ottimizzatore SQL che all’ utente quando deve leggere la query. Tramite le
funzioni di load, invece, Pig da completo controllo al developer sui dati caricati,
permettendo di fissare dei checkpoint ovunque nel codice, molto utili soprattutto in fase di
debug. Inoltre, nel caso in cui vi sia un failure all’ interno della pipeline, questa non dovrà
essere ri-eseguita nella sua totalità, cosa molto interessante quando ci si trova a lavorare su
enormi dataset.
Pig permette di specificare quali operatori e implementazioni utilizzare nel load e
trasformation dei dati. Questa feature di SQL la si può definire come “fede nell’
30
ottimizzatore di query”. Infatti, data la natura dichiarativa del linguaggio, lo sviluppatore
deve scrivere solo ciò che vuole, senza preoccuparsi di come sarà fatto. Questa
preoccupazione, però, gli sviluppatori di data pipeline per Big Data vogliono averla,
poiché su ciò si base anche l’ ottimizzazione globale e l’ efficienza del sistema. Sono
proprio questi tuning (che nei normali DBMS vengono spesso omessi) a fare poi la
differenza tra un buon sistema ed uno poco efficiente. Bisogna appuntare che SQL
permette, certamente, degli hint, ovvero dei suggerimenti che il developer dà all’
ottimizzatore sull’ usare questa o quell’ altra implementazione di un’ operazione o
processo. Tutto ciò però resta un suggerimento, che il motore SQL può anche ignorare. Pig
dal suo canto invece permette di scegliere per ogni operazione tra diverse
implementazioni, così come permette l’ uso e la scelta degli operatori appropriati da
sfruttare. Sarà il developer ad aver parola su ogni aspetto dell’ esecuzione della data
pipeline, così che possa sistemare il tutto come meglio crede.
Pig supporta lo split della pipeline. Mentre SQL importa i dati come specificati nelle
SELECT, FROM e JOIN della query, Pig dà il pieno controllo sul data import flow nella
pipeline. Questo permette, ad esempio, di caricare dati da diverse tabelle, ordinarli su
chiavi diverse e poi utilizzarli con il codice appropriato. Questo era impraticabile in SQL,
a meno che di non utilizzare tabelle temporanee. Questa differenze è permessa dall’ uso
dei DAG (grafi aciclici diretti) con cui lavora Pig, mentre SQL sfrutta gli alberi. Tutto
questo, inoltre, porta ad un altro beneficio: la gestione separata e completa dello stream di
dati permette di ottimizzare l’accesso al disco per reads e writes, aspetto importantissimo
nei BigData Systems. Lo split, infine, dà benefici anche al compilatore Pig, al quale
possiamo meglio indicare come produrre i MapReduce Jobs, permettendo una maggiore
efficienza nella loro realizzazione.
Pig permette di inserire codice quasi ovunque all’ interno del listato. Tramite UDFs e
streams, Pig permette all’ utente di importare ed utilizzare codice nativo di altri linguaggi,
come ad esempio Java. Questo può essere utile quando si deve importare dati da sorgenti
che non siano il database. Con SQL, invece, tutto deve passare per la base di dati, e spesso
per far ciò bisogna far ricorso software di terze parti costosi e ostici. Questo aspetto di
31
Pig, inoltre, gli permette di accettare anche codice legacy: eseguibili esterni di software
non più supportato possono essere lanciati e sfruttati i qualunque punto del codice. Per
un’azienda tutto ciò porta vari benefici: non deve insegnare nuovi linguaggi o nuovi
pacchetti sw di terze parti ai propri developer; spesso si trova a lavorare con codice legacy
ormai obsoleto che però torna a “nuova vita” sfruttandolo nelle operazioni Pig.
32
Capitolo 4: Analisi di un caso pratico
Quest’ ultimo paragrafo sarà caratterizzato da un’ impronta puramente pratica. Difatti, a
questo punto è possibile toccare con mano e sperimentare come si comportano le soluzioni
fin’ ora analizzate. In particolare, saranno adoperati i prodotti presentati nei capitoli due e
tre: Apache Hadoop e Pig Latin. Di conseguenza, in questo capitolo verrà mostrato uno
script realizzato con tale linguaggio, per mostrarne peculiarità e caratteristiche. Il tutto sarà
accompagnato sia da un’ analisi tecnica del processo di messa in funzione della macchina
utilizzata, che da una riflessione sui risultati ottenuti.
4.1 Caso di studio
Si immagini una situazione in cui vi sia una applicazione lanciata sul mercato dal 2015,
che a poco a poco è cresciuta ed è diventata sempre più popolare. Senza che ce lo si
aspettasse, il prodotto ha avuto un forte impatto sul pubblico e si è diffuso a macchina d’
olio, tanto che è stata successivamente avviata una società e costruito un business plan ad
hoc intorno all’ app. Man mano che questa si è diffusa, la società si è ingrandita ed
espansa, ed è giunto il momento di fare il salto di qualità: convincere nuovi investitori (e
quindi soci) ad entrare nel progetto, cercando di guadagnare anche degli inserzionisti di
rilievo. Si pensi, quindi, al capo della società, che deve realizzare un report da presentare
sullo “stato di salute” del suo software. Secondo lui non ci saranno problemi: l’
applicazione è apprezzatissima dal pubblico e usata da tantissimi utenti. Nel bel mezzo
della relazione, però, ci si rende conto di una cosa: c’ è bisogno di dati analitici che
confermino e supportino la tesi riguardo la diffusione e l’ utilizzo effettivo dell’ app.
Bisogna quindi utilizzare una fonte da cui attingere dei dati sui login degli utenti. Si
immagini, quindi, di avere a disposizione tali file, in cui vi è segnato per ogni utente il
numero di minuti in cui è stato connesso in ogni giorno di utilizzo dell’ app. Dato il grande
successo che ha riscosso in circa due anni di vita, salta subito fuori un problema: i file di
log contengono centinaia di migliaia di records. Non è facile gestire tutti questi dati in
modo efficace, soprattutto se vi si approccia in modo sbagliato. Utilizzando le tecnologie
per Big Data System, però, si può agilmente venire a capo del problema e risolverlo con
33
forte efficacia. In particolare, per risolvere questo caso di studio tornano utili Apache
Hadoop e Pig Latin. Il primo permetterà di realizzare un’ infrastruttura di macchine in
cluster di rete, così da scalare facilmente il sistema se la potenza di calcolo risulterà
insufficiente. Il secondo, invece, metterà a disposizione un linguaggio di scripting molto
valido che permetterà in poco tempo di realizzare quanto necessario. Tutto ciò permetterà
di dimostrare che la suddetta applicazione è un prodotto solido, fortemente utilizzato e con
un bacino d’ utenti di età media molto giovane.
4.2 Setup dell’ architettura
Nei
test
e
implementazioni
effettuate, è stata realizzata un’
architettura
con
una
sola
macchina, data l’ impossibilità
pratica di poter creare e gestire
un cluster di più elaboratori in
rete. In particolare, è stata
adoperata una macchina virtuale
con sistema operativo Ubuntu 16.04 LTS equipaggiata con un processore quad core, 4 GB
di RAM, 128 MB di scheda video e 30GB di spazio. Il tutto, ovviamente, emulato tramite
Oracle VM VirtualBox 5.1.6. Entrambi i software di casa Apache, per poter funzionare
correttamente, necessitano di una Virtual Machine Java. Per tale motivo, è stata installata
precedentemente Java JDK nel sistema, in versione 1.8. La piattaforma Apache Hadoop
utilizzata, invece, è in versione 2.7.3 (ultima release corrente). Infine, la versione di Pig
Latin adoperata è la 0.16.0 (ultima release corrente).
4.2.1 Apache Hadoop
In fase di installazione è stato scompattato l’ archivio in una cartella dedicata, impostato
delle variabili d’ ambiente necessarie ad individuare la posizione in cui era presente Java
(JAVA_HOME e HADOOP_HOME) e configurato il tipo di utilizzo di Hadoop: nel caso
34
in questione si tratta di una singola macchina nel cluster con processi che fanno da
Datanode, da Namenode e da ResourceManager. Questi, in particolare, si avviano come
deamon di sistema e restano in ascolto di richieste su tre porte specifiche, rispettivamente
50010, 50070 e 54310. Questo è possibile osservarlo in ben tre modi:
•
tramite il comando jps da console (che fa parte del pacchetto Java) è possibile
vedere i tre processi contestuali avviati, quali ResourceManager (MapReduce Jobs
executer), DatanodeManager e NamenodeManager;
•
tramite il comando netstat è possibile vedere i tre processi in ascolto sulle rispettive
porte;
•
tramite l’ indirizzo http://localhost:50070 che riporta una UI web con varie
informazioni su Apache Hadoop riguardo i nodi in esecuzione, il suo stato attuale, quello
del filesystem e quello dei processi avviati.
Dopo aver configurato i tre processi fondamentali, è stato creato appositamente un disco
nel filesystem di Hadoop (HDFS), successivamente formattato tramite l’ apposito
comando e messo poi a disposizione del datanode manager. I vari chunk, da
configurazione di default, sono grandi 128MB. Infine, prima di poter avviare il tutto, è
stata verificata la presenza sulla macchina di un gestore di connessioni ssh (ssh e sshd),
dato che la comunicazione con i processi Apache Hadoop avviene tramite tale protocollo.
Fatto ciò, è stato possibile avviare l’ intero sistema, tramite l’ apposito script start-all.sh
(deprecato) oppure richiamando prima start-dfs.sh e po start-yarn.sh.
4.2.2 Apache Pig Latin
Le operazioni per l’ installazione di Apache Pig risultano simili a quanto fatto per Apache
Hadoop. Difatti anche in questo caso è stato scompattato l’ archivio scaricato dal sito
ufficiale in una cartella apposita, sono state sistemate delle variabili d’ ambiente
(JAVA_HOME, HADOOP_HOME e PATH) e infine è stata configurata la modalità di
esecuzione dell’ engine, ovvero Mapreduce Mode (che è anche la modalità di default). Per
testare il funzionamento del sistema e verificare che l’ operazione di setup fosse andata a
buon fine, è stato provato un semplice script di esempio suggerito nella guida ufficiale di
35
Pig. Questo prevede di leggere il file passw di Ubuntu e creare un MapReduce Job
(tramite linguaggio Pig Latin) che mostri i nomi di tutti gli utenti presenti nel sistema. Per
far ciò, è stato dapprima copiato il file passwd dal file system locale ad Hadoop
Distributed File System, tramite il comando:
hdfs dfs –copyFromLocal /etc/passwd passwd
Una volta che il file è copiato nel file system, è possibile richiamarlo nello script. Il codice
di esempio adoperato è molto semplice:
A = LOAD 'passwd' USING PigStorage(':');
B = FOREACH A GENERATE $0 AS id
STORE B INTO 'id.out';
Questo codice può essere mandato in esecuzione in due modi, avviando la shell di pig ed
eseguendo istruzione per istruzione, oppure creando un file .pig da eseguire direttamente
tramite riga di comando. In particolare, il codice prende il file passwd, lo legge riga per
riga e divide l’ informazione di ogni riga tramite il separatore “:”. Successivamente, per
ogni riga, crea un nuovo relational nella variabile B: questo conterrà l’ id di ogni utente.
Infine, tramite il comando STORE, viene scritto su un file “id.out” il nome di ogni utente e
questi sarà memorizzato nel filesystem HDFS. Per salvarlo in locale nel file system di
Ubuntu, è possibile usare l’ apposito comando da terminale:
hdfs dfs –copyToLocal id.out /path/to/my/folder/id.out
oppure effettuare un download del file dall’ interfaccia grafica web apposita, all’ indirizzo
http://localhost:50070/explorer.html.
4.3 Dati di input
Come accennato precedentemente, il programma Pig Latin che realizzato effettua delle
elaborazioni sui dati di login degli utenti. Di conseguenza, l’ input riguarda proprio tali
informazioni. Due sono i file utilizzati:
•
users.csv è un file che contiene le informazioni riguardanti i vari utenti. In
particolare, in esso vi si trova id, username, nome, cognome e età;
36
•
logs.csv invece è un file contenente i dati di login veri e proprio. Ogni riga del file
indica l’ id di un utente, il numero di minuti per cui si è utilizzato l’ app e il giorno a cui
questi fanno riferimenti.
Di seguito è possibile vedere degli esempi di come sono strutturati i due file. A sinistra è
riportato un ritaglio del file users.csv, mentre a destra vi è un ritaglio del file logs.csv.
I file .csv sono stati prodotti tramite dei programmi scritti appositamente usando un altro
linguaggio, che li ha realizzati mettendo casualmente insieme dei nomi utente e dei nomi
di persona presi da archivi liberi online. Stessa cosa è state fatta per il file di logs, prodotto
generando casualmente delle date e dei “minuti online” per ogni utente. Dato l’ utilizzo di
una semplice macchina PC (in particolare un portatile), i dati di input utilizzati sono stati
forzatamente limitati. Difatti, per i vari test sono stati utilizzati solo 34 utenti e 17000 dati
di login (ne sono stati generati 500 per utente). I due file, per essere utilizzati e richiamati
nello script, sono stati copiati nella cartella di default in Hadoop Distributed File System.
L’ operazione è stata eseguita tramite i comandi messi a disposizione da Apache Hadoop:
hdfs dfs –copyFromLocal /var/users.csv users.csv
hdfs dfs –copyFromLocal /var/logs.csv logs.csv
La presenza dei file sul file system distribuito è possibile verificarla, infine, tramite la
comoda
UI
37
web:
4.4 Lo Script
Le domande a cui si vuole rispondere tramite gli strumenti di analytics offerti da Apache
Hadoop sono sostanzialmente due: quanto tempo passa mediamente un utente all’
applicazione e qual è l’ età media dell’ utenza. Il linguaggio utilizzato sarà, come già
preannunciato, Pig Latin. Questi permetterà di avere una certa malleabilità dello script,
consentendo di scegliere ed utilizzare determinati operatori al posto di un altro. Anche se il
caso in esempio è semplificato e lavora su relativamente pochi dat, queste accortezze
diventano sempre più fondamentali su basi di dati vaste, tanto da rendere notevolmente
cruciale l’ uso delle tecnologie proposte fino a qui. Per sommi casi, lo script dovrà
effettuare le seguenti operazioni:
1.
prendere in input i due file con i dati;
2.
caricare in memoria in apposite variabili (relational) queste informazioni;
3.
calcolare il totale dei minuti spesi sull’ applicazione da tutti gli utenti e dividerli per
i giorni di cui tengono traccia i log;
4.
dividere questo totale per il numero di utenti. La prima risposta è così ottenuta;
5.
effettuare un ragionamento simile per l’ età media. La seconda risposta è così
ottenuta;
6.
salvare (eventualmente) i risultati ottenuti su disco.
Le potenzialità e la semantica offerta da Pig Latin permettono di operare tutto ciò senza
particolari
problemi.
Il
codice
utilizzato
è
riportato
di
seguito:
(1) users = LOAD 'users.csv' USING PigStorage(',');
(2) raw_users = FILTER users BY $0>1;
(3) users_details = FOREACH raw_users GENERATE $0 AS
userId, $1 AS username, $2 AS name, $3
AS age;
(4) log = LOAD 'logs.csv' USING PigStorage(',');
(5) raw_log = FILTER log BY $0>1;
(6) logs_details = FOREACH raw_log GENERATE $0 AS userId,
$1 AS date, $2 AS minutes;
(7) grp_logged = GROUP logs_details BY userId;
(8) sum_logged = FOREACH grp_logged GENERATE GROUP AS
userId, SUM(logs_details.minutes) AS
online_minutes;
38
(9) join_sum_logged = JOIN sum_logged BY userId,
users_details BY userId;
(10) join_data = FOREACH join_sum_logged GENERATE $0 AS
userId, $1 AS online_minutes, $3 AS
username, $5 AS age;
(11) total_group = GROUP join_data all;
(12) avg_minutes_online = FOREACH total_group GENERATE
SUM(join_data.online_minutes)/(43*609);
(13) avg_age = FOREACH total_group GENERATE
SUM(join_data.age)/34;
(14) STORE avg_minutes_online INTO 'out1.log';
(15) STORE avg_age INTO 'out2.log';
Prima di analizzare e commentare il codice, sono necessarie delle note a riguardo: il
calcolo del tempo medio di utilizzo dell’ app da parte degli utenti è stato calcolato
sommando prima tutti i minutaggi presenti e dividendo poi questi per il numero di utenti
moltiplicato per i giorni a cui i log si riferiscono (dal 1 gennaio 2015 al 31 Agosto 2016)
ovvero 609 giorni. Infine, va precisato che il numero di utenti nel file csv è di 34.
Premesso ciò, è possibile passare ad un’ analisi più precisa del codice riga per riga.
1)
viene caricato il contenuto del file users.csv all’ interno della variabile users; questo
viene fatto utilizzando l’ operatore LOAD accompagnato dalla funzione da utilizzare per
effettuare il read dei dati. In questo caso è stata utilizzata una funzione built-in chiamata
PigStorage. Se i dati sono memorizzati in modo non processabile dalle funzioni messe a
disposizione dal linguaggio, è possibile definirne una ad hoc;
2)
la seconda riga del codice, invece, utilizza una funzione FILTER. Questa non fa
altro che filtrare i dati, ovvero selezionare le tuple su condizioni specifiche. Nel caso
specifico, la condizione è che la prima colonna sia maggiore di 1. Questo escamotage è
fatto per eliminare la prima riga dei dati caricati da users.csv, dato che il file presentava
una intestazione. In questo modo essa viene scartata, per non farla rientrare nel processo di
elaborazione;
3)
la terza riga del codice serve per trasformare i dati, tramite il costrutto
FOREACH/GENERATE. Questi infatti permette di scorrere le righe dei dati fin’ ora
caricati e specificare un identificativo per ogni colonna; si ottiene così la variabile
relational da utilizzare in seguito per le elaborazioni;
4)
viene qui caricato il contenuto del file logs.csv;
39
5)
viene qui filtrato il contenuto, eliminando di conseguenza la prima riga dei dati;
6)
viene poi creata la variabile relational associata ai logs tramite l’ operatore di
trasformazione FOREACH;
7)
con il codice a tale riga si raggruppano le tuple della relazione log_details. Questo è
fatto sulla base dell’ userId;
8)
a questo punto, si sfrutta la relazione creata precedentemente per crearne una nuova,
contenente per ogni id quanti minuti è rimasto online;
9)
con il codice alla riga 9 si effettua un’ operazione di JOIN di due relazione. Nello
specifico vengono giunte sum_logged e users_details sulla base del contneuto della
colonna userId. Questo produrrà una relazione che mostra sia i dettagli dell’ utente (userId,
name, age, username) che quanti minuti è rimasto online nell’ applicazione negli ultimi
due anni;
10)
in tale riga si crea un’ ulteriore relazione, chiamata join_data, che sarà utilizzata
successivamente per il calcolo finale della media;
11)
in questa riga viene utilizzato di nuovo l’ operatore GROUP, stavolta però con la
keyword ALL. Questa permette di raggruppare tutti i dati in un solo gruppo;
12)
a questo punto, è possibile sommare tutti i minuti di tutti gli utenti. L’ operatore
utilizzato è SUM, che somma i dati della colonna online_minutes della relazione
join_data. Questi sono divisi infine per il numero totale di utenti (34) e il numero di giorni
a cui si riferiscono i log. Dal 1 Gennaio 2015 al 31 Agosto 2016 sono 609 giorni. In questo
modo, si ottiene la prima risposta ai quesiti iniziali.
13)
infine, il codice in questa riga utilizza ancora la relazione join_data, questa volta per
trovare la somma di tutte le età. Tale risultato sarà poi diviso per 34 (numero di utenti).
Viene così ottenuta la seconda e ultima risposta cercata.
14)
Tramite il comando STORE viene salvato il risultato della prima elaborazione nel
file out1.log. Questo sarà memorizzato sul file system distribuito di Hadoop;
15)
Tramite il comando STORE viene salvato il risultato della seconda elaborazione nel
file out2.log. Questo sarà memorizzato sul file system distribuito di Hadoop.
I due file di output, out1.log e out2.log, possono poi essere letti sia da riga di comando,
40
utilizzando hdfs, che dalla UI web all’ indirizzo indicato precedentemente. Il loro
contenuto sarà 19.75, che rappresenta i minuti trascorsi online in media al giorno, e 25.53,
che rappresenta l’ età media degli utilizzatori dell’ applicazione.
41
Conclusioni
Lo scopo di questo elaborato è stato focalizzato sul presentare una situazione reale in cui i
Big Data System potevano essere la chiave di volta per ottenere con efficacia dei risultati
interessanti. Per tale motivo, la strutturazione del testo è stata volutamente impostata in
modo da creare e definire le basi teoriche nei primi capitoli, in modo tale da affrontare e
arrivare al quarto con buona conoscenza e coscienza di quanto si stave discutendo. Come
si è visto, i Big Data System si rivelano una vera e proprio miniera di possibilità in diverse
situazioni, in particolare in quelle estreme dove i dati sono molti e tutti importanti. Le
soluzioni che oggi si sono affermate risultano essere valide e fortemente collaudate, tanto
da rappresentare una vera e proprio sicurezza in questo settore. I sistemi Big Data si sono
quinfi affermati come una parte fondamentale del business di molte aziende. Mentre prima
potevano sembra uno strumento in più, oggi la loro “validazione” (da parte dalle stesse
aziende che hanno provato i benefici) ha fatto si che questi siano arrivati sempre di più al
core del business, stravolgendolo e arricchendolo incredibilmente. Con il passare del
tempo, si andrà sempre di più verso aziende che dovranno macinare e consumare dati ogni
giorno per rimanere alte e competitive nel mercato. I dati sono sempre più la vera
ricchezza e potere: saperli usare è cruciale. La società sempre più connessa pronosticata in
molti libri e ricerche dell’ ultimo decennio sta prendendo forma, e scommettere sul ruolo
da protagonist che avranno I Big Data System è banale: la loro importanza è già oggi
scontata. Ovviamente le sfide non finiscono qui. Uno sguardo alle stime ci fa notare che
queste quantificano (almeno indicativamente) i dati prodotti ogni giorno parlando di 2.3
trilioni di gigabyte in tutto il mondo, e si arriverà nel 2020 a circa 43 trilioni. Tutto ciò
continuerà a rappresentare una sfida continua, poichè non sarà comunque facile a star
dietro a quantità che crescono così spaventosamente di giorno in giorno. Di fatto, si sta già
viaggiando verso il futuro che ha già un nome: Data Management, termine con il quale si
riuscono discipline nell’ ambito dei Big Data, nonchè le nuove figure professionali che
questi stanno generando. Il future è alle porte, le tecnologie ci sono, gli strumenti sono
pronti: le aziende sapranno partecipare alle nuova rivoluzione industriale?
42
Bibliografia
[1]
Nathan Marz e James_Warren, “Principles and best practices of scalable real-time
data systems”;
[2]
“Comparing Pig Latin and SQL for Constructiong Data Processing Pipelines”,
https://developer.yahoo.com/blogs/hadoop/comparing-pig-latin-sql-constructing-dataprocessing-pipelines-444.html;
[3]
https://en.wikipedia.org/wiki/Pig_(programming_tool);
[4]
https://www.quora.com/What-is-the-history-of-Hadoop;
[5]
https://www-01.ibm.com/software/data/infosphere/hadoop/mapreduce/;
[6]
https://gigaom.com/2013/03/04/the-history-of-hadoop-from-4-nodes-to-the-future-
of-data/;
[7]
http://hadoop.apache.org/#What+Is+Apache+Hadoop%3F;
[8]
https://www.tutorialspoint.com/apache_pig/;
[9]
https://datajobs.com/what-is-hadoop-and-nosql;
[10] https://www.mongodb.com/big-data-explained;
[11] http://hadoop.apache.org/;
[12] https://pig.apache.org/;
[13] https://pig.apache.org/docs/r0.7.0/piglatin_ref2.html;
[14] http://hortonworks.com/hadoop-tutorial/how-to-process-data-with-apache-pig/;
[15] http://www.bogotobogo.com/Hadoop/BigData_hadoop_Install_on_ubuntu_single_node_cluster.php;
[16] http://www.michael-noll.com/tutorials/running-hadoop-on-ubuntu-linux-singlenode-cluster/;
[17] http://datawarehouse4u.info/ETL-process.html;
[18] http://www.jamesserra.com/archive/2012/01/difference-between-etl-and-elt/
[19] http://www.franzrusso.it/inweb-2-0/futuro-big-data-data-management-ebook/
43