hadoop analyzerjr

111
Universit ` a degli studi di salerno Progetto di Sistemi Operativi Avanzati 2014-2015 Hadoop Analyzer JR Autori: Amedeo Leo Alessio Petrozziello Simone Romano Docente Giuseppe Cattaneo Supervisore: Gianluca Roscigno February 7, 2015

Upload: simone-romano

Post on 20-Jan-2017

198 views

Category:

Science


0 download

TRANSCRIPT

Page 1: Hadoop analyzerJR

Universita degli studi di salerno

Progetto di Sistemi Operativi Avanzati

2014-2015

Hadoop Analyzer JR

Autori:Amedeo LeoAlessio PetrozzielloSimone Romano

DocenteGiuseppe Cattaneo

Supervisore:Gianluca Roscigno

February 7, 2015

Page 2: Hadoop analyzerJR

2

Page 3: Hadoop analyzerJR

Contents

Introduzione 5

Dati da analizzare 6

1.1 Analisi dstat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

1.1.1 Client/server dstat . . . . . . . . . . . . . . . . . . . . . . 6

1.1.2 Analisi file ’.csv’ . . . . . . . . . . . . . . . . . . . . . . . 6

1.2 Analisi log Hadoop . . . . . . . . . . . . . . . . . . . . . . . . . . 8

1.3 Profiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

Output 10

2.1 Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

2.1.1 Web page . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

2.1.2 Warning . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

2.1.3 Profiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

2.2 R . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

2.2.1 Dati formattati excel . . . . . . . . . . . . . . . . . . . . . 17

2.2.2 SpeedUp ed efficienza . . . . . . . . . . . . . . . . . . . . 17

Manuale utente 19

Caso di studio 28

4.1 Configurazione cluster . . . . . . . . . . . . . . . . . . . . . . . . 28

4.1.1 Yarn-site.xml . . . . . . . . . . . . . . . . . . . . . . . . . 28

4.2 hdfs-site.xml . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

4.3 WordCount . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

4.4 Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

4.4.1 Specifiche delle macchine . . . . . . . . . . . . . . . . . . 39

4.5 Test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

4.6 Risultati . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

4.6.1 Analisi Dstat . . . . . . . . . . . . . . . . . . . . . . . . . 40

4.6.2 Analisi Log Hadoop . . . . . . . . . . . . . . . . . . . . . 42

4.7 Confronto esperimenti . . . . . . . . . . . . . . . . . . . . . . . . 46

3

Page 4: Hadoop analyzerJR

4 CONTENTS

Appendice 495.1 Java code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

5.1.1 Parser csv . . . . . . . . . . . . . . . . . . . . . . . . . . . 495.1.2 ChartGenerator . . . . . . . . . . . . . . . . . . . . . . . . 545.1.3 JFreeChartGenerator . . . . . . . . . . . . . . . . . . . . . 67

5.2 R code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 705.2.1 chart generator.R . . . . . . . . . . . . . . . . . . . . . . . 705.2.2 excel.R . . . . . . . . . . . . . . . . . . . . . . . . . . . . 855.2.3 graphHadoopGenerator.R . . . . . . . . . . . . . . . . . . 945.2.4 speedup.R . . . . . . . . . . . . . . . . . . . . . . . . . . . 98

5.3 C code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1005.3.1 client.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1005.3.2 server.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1045.3.3 AllSlaves.c . . . . . . . . . . . . . . . . . . . . . . . . . . 109

Afterword 111

Page 5: Hadoop analyzerJR

Introduzione

Lo studio proposto punta a realizzare uno strumento per analizzare il funziona-mento di un cluster che utilizza il framework Hadoop [9]. Diversi sono gli inputche il tool puo analizzare a seconda delle esigenze. In particolare analizza iseguenti tipi di file:

• ’.csv’ generati con dstat [6]

• ’.txt’ generati con il profiler java [7]

• ’.man’ che raccolgono i log generati dal framework Hadoop

Il tool genera grafici rappresentanti l’andamento di ciascuna macchina del clus-ter. I file ’.csv’ possono essere recuperati installando sul master e sugli slaverispettivamente un client e vari server appositamente realizzati. A tale scopoe possibile utilizzare librerie java o R[8]. In base alla modalita di generazioneselezionata dall’utente (R, java) e possibile istruire il tool al fine di generareeventuali ’warning charts’ che danno suggerimenti per utilizzare il cluster inmaniera pi efficiente. E possibile inoltre visualizzare una timeline dei task svoltidal framework Hadoop, generabile dando in input i file ’.man’ generati con unoscript python appositamente realizzato. L’output realizzato varia a secondadelle librerie selezionate dall’utente (R o java) e puo essere:

• Pagina web - java

• file pdf - R

I capitoli successivi analizzeranno in dettaglio quanto realizzato.

5

Page 6: Hadoop analyzerJR

Dati da analizzare

Introduzione

In questa sezione saranno analizzati i vari dati presi in input dal tool e il relativooutput generato dal tool.

1.1 Analisi dstat

Il tool analizza dunque file ’.csv’ generati con dstat[6] su ciascuno slave e sulmaster del cluster.

1.1.1 Client/server dstat

Il tool prevede la possibilita di raccogliere, da un solo terminale, di lanciare, inmaniera parallela, il software dstat su tutte le macchine necessarie del cluster.In particolare, sono stati sviluppati un client e un server in linguaggio C: ilserver e stato settato in avvio automatico sugli slave, il quale attende su unaspecifica porta (ad esempio 8080) le richieste effettuate dal master; il client, inesecuzione sul master, puo decidere quando avviare o terminare il software dstatsugli slave.

1.1.2 Analisi file ’.csv’

I file ’.csv’ recuperati con l’applicazione client/server ’c’ possono essere dunqueanalizzati con ’Hadoop Analyzer JR’. Come anticipato cio puo essere fatto uti-lizzando due diverse librerie:

• Java (Google-JfreeChart)

• R

Alcune delle opzioni selezionabili (vedi 2.2.2) variano a seconda della libreriautilizzata.

6

Page 7: Hadoop analyzerJR

1.1. ANALISI DSTAT 7

Figura 1.1: Esempio di file generato con dstat

Figura 1.2: Esempio di file preso in input dal parser

Analisi ’.csv’ java

Al fine di interpretare i file ’.csv’ generati con ’dstat’ e stato utilizzato un parser’.csv’ [3]. La classe java che si occupa di analizzare tali file e mostrata in 5.1.1.Tale classe analizza il file ’.csv’ e:

• ripulisce il file eliminando elementi superflui che danno problemi con ilparser

• ricava in automatico l’intervallo con cui ’dstat’ e stato lanciato sullemacchine del cluster

Il file che prende in input e mostrato in figura 1.1. Tale file viene dunque ripulitoper poterne effettuare il parsing. Il nuovo file e mostrato in figura 1.2. Sulnuovo file generato e dunque possibile andare ad estrarre di volta in volta lecolonne desiderate per ricavare informazioni necessarie per generare i grafici.

Analisi ’.csv’ R

E stato creato uno script in linguaggio R per la creazione dei grafici relativiall’analisi dei dati di dstat. Lo script prende in input un file di configurazionecontenente diversi campi: - Tempo espresso in secondi, minuti o ore, relativoall ’asse delle ascisse per la timeline. - Un valore per definire la scelta dellacolorazione dei grafici (in scala di grigi o colorato). - Un valore per definire la

Page 8: Hadoop analyzerJR

8 CONTENTS

scelta delle linee (continue o tratteggiate). - Un valore per stabilire la presenzadel titolo nei grafici. - Un valore per scegliere come generare i grafici (un singolopdf o molteplici). - Un valore per scegliere la tipologia dei grafici (’single’,’average’, ’all nodes’). - Un valore per determinare la scelta dei valori dellaCPU desiderati (’usr’, ’sys’, ’idl’, ’wai’, ’hiq’, ’siq’). - Un valore per determinarela scelta dei valori della RAM desiderati (’used’, ’buff’, ’cach’, ’free’). - Unvalore per determinare l’upperbound della RAM desiderato. - Un valore perdeterminare la scelta di visualizzazione dell’I/O (su un solo grafico o separati).- Un valore per determinare la scelta di visualizzazione del paging, in e out (su unsolo grafico o separati). - Un valore per determinare la scelta di visualizzazionedell’utilizzo della rete, espresso in MB/s, in e out (su un solo grafico o separati).- Un valore per determinare la scelta di visualizzazione dell’utilizzo della rete,espresso in numero di pacchetti, ricevuti o inviati (su un solo grafico o separati).Attraverso il settaggio dei vari parametri, si puo avere un’ampia scelta sullagenerazione dei grafici. Dato un file dstat in formato csv, ne viene generatoun dataframe su cui, estrapolate le informazioni necessarie, saranno creati idiversi grafici. La timeline e espressa in secondi, minuti o ore a seconda dellascelta dell’utente; il delay tra le misurazioni e automaticamente riconosciutodallo script.

1.2 Analisi log Hadoop

Una parte fondamentale del nostro tool e l’analisi dei log generati dal framework.I log devono essere recuperati, in primo luogo, dall’Hadoop MapReduce HistoryServer. Le REST API dell’History Server permettono all’utente di ottenere lostatus delle applicazioni terminate. Tali risorse forniscono informazioni generalisull’History Server; attraverso delle URI e possibile ottenere dati partendo daun id specificato, Sono supportate operazioni HTTP come GET. Le rispostepossono essere in formato JSON o XML. Per recuperare i file di log, e statocreato uno script utilizzando il linguaggio Python; in particolare, dato in inputl’id del job, restituisce in output una cartella contenente solo i file utili pergenerare il grafico, in modo da evitare all’utente l’onere di scaricare a mano imolteplici file restituiti dall’History Server.

Esempio: Con l’URL http://localhost:19888/ws/v1/history/mapreduce/

jobs/job\_1419686689081\_0001 si ottengono varie informazioni sul job in in-put, come il ”submitTime”, utile per essere considerato come il tempo 0 del jobHadoop da inserire nel grafico. Con l’URL http://localhost:19888/ws/v1/

history/mapreduce/jobs/job\_1419686689081\_0001/tasks otteniamo le in-formazioni dei task di map e reduce. Effettuato il parsing della risorsa generata,si estraggono, per ogni task, alcune informazioni come gli ”attempts”: Di se-guito sono indicate le URL per estrarre le informazioni su uno specifico task esu suoi attempt.http://localhost:19888/ws/v1/history/mapreduce/jobs/job\_1419686689081\

_0001/tasks/task\_1419686689081\_0001\_m\_000001

http://localhost:19888/ws/v1/history/mapreduce/jobs/job\_1419686689081\

Page 9: Hadoop analyzerJR

1.3. PROFILER 9

_0001/tasks/task\_1419686689081\\\_0001\_m\_000001/attemptsPossono esistere piu ’attempts’ per lo stesso task: infatti, occorre fare la dif-ferenza tra task che possono essere ’SUCCEEDED’, ovvero quelli che terminanola computazione, ’KILLED’ o ’FAILED’, ovvero interrotti a causa di errorinell’esecuzione. Esistono diversi motivi per cui Hadoop pu fare il ’kill’ di untask:

• Il task non segnala progressi al termine di un timeout, che di default e di10 minuti.

• Il FairScheduler o il CapacityScheduler hanno bisogno dello slot per qualchealtro compito.

• L’esecuzione speculativa provoca risultati del task non necessari, poichlesecuzione e gia stata portata a termine.

1.3 Profiler

Laddove si e presentato un warning, il tool utilizza ulteriori informazioni perdare ulteriori dettagli sul ’malfunzionamento’ del cluster. Questi ulteriori det-tagli sono generati a partire dai file eventualmente generati con ’hprof’ (sel’utente ha utilizzato il profiler al run dell’esperimento). Per abilitare il pro-filer bisogna passare come parametro alla VM:

-agentlib:hprof=cpu=times,heap=sites,depth=6,interval=10000,force=n,

thread=y,verbose=n,file=prof.output

A questo punto, viene generato un file contenente informazioni sull’utilizzo dellerisorse da parte dei metodi invocati dall’applicazione Java. Tale file conterrainformazioni su un singolo task; di conseguenza l’output generato dal tool darainformazioni sul task descritto dal file.

Page 10: Hadoop analyzerJR

Output

Introduzione

In questo capitolo vengono illustrate le diverse modalita di output generabiliutilizzando il tool ’Hadoop Analyzer JR’. Tali modalita variano, ancora unavolta, in base alla libreria selezionata dall’utente (Google-JFreeChart o R).L’integrazione tra Java ed R e stata implementata richiamando sgli script dacodice Java, quindi in maniera del tutto trasparente all’utente. Nel tool si de-ciso di non utilizzare JRI, ovvero linterfaccia Java/R, che permette di eseguirecodice R all’interno di applicazioni Java. Questo perche, sebbene JRI forniscadelle API Java per R, occorre installarlo come libreria esterna.

2.1 Java

Qualora l’utente decidesse di utilizzare le librerie java (Google-JFreeChart) iltool realizzera un’applicazione web contenente i grafici generati. Per generarei grafici da java sono state utilizzate 2 librerie:

• charts4j[2]

• JFreeChart[1]

’charts4j’ consente di creare da codice grafici generabili con ’Google CHartTools’. Tale API fornisce dei metodi per generare grafici che effettuano inmaniera opportuna delle richieste Http. Cio che restituisce e dunque una url algrafico. E stato necessario utilizzare anche la lbreria JFreeChart perche quandosi tentava di generare i grafici contenenti tutti gli slave ed il master in un singolografico la libreria ’charts4j’ creava una richiesta http troppo grande lanciandol’eccezione ’Request-URI Too Large’. Le classi java che realizzano i grafici sonomostrate in 5.1.2 ed in 5.1.3.

2.1.1 Web page

I grafici generati utilizzando la modalita java saranno raccolti in una appli-cazione web divisa in sezioni. Ogni sezione raccoglie grafici relativi rispettiva-mente a:

10

Page 11: Hadoop analyzerJR

2.1. JAVA 11

• Cpu

• Ram

• Swap

• Disk

• Network packet

• Network throughput

• Paging

• Context swithces

• Interrupts

• Warning

• Profiler Information

La figura 2.3 mostra un esempio di output autogenerato dal tool in modalitaGoogle-JFreeChart. Un generico grafico mostra sull’asse delle x il tempo inminuti, secondi o ore in base alla scelta dell’utente; sull’asse delle y possiamoavere:

• percentuale se il grafico e relativo alla cpu

• numero di pacchetti per network packets

• MB se il grafico e relativo a qualsiasi delle altre risorseCpu

La sezione Cpu contiene i grafici relativi all’andamento della cpu. Per la cpu,utilizzando le librerie java, viene generato un grafico per ciascuna colonna delfile ’.dstat’ dato in input (cpu, sys, idl, syq, hiq, wai). E possibile inoltre darein input una combinazione di qualsiasi colonna ed il tool ne effettuera la sommagenerando il grafico relativo. La figura 2.4 mostra un esempio di grafico relativoalla cpu generato in modalita java. Memoria

In questa sezione saranno raccolti i grafici relativi all’utilizzo della memoriaprincipale. Per tale risorsa ’dstat’ fornisce diverse informazioni:

• used

• cach

• buff

• free

Il tool genera un grafico per ciascuna delle precendenti informazioni. E possi-bile, anche qui, dare in input una combinazione di qualsiasi colonna ed il toolne effettuera la somma generando il grafico relativo. La figura 2.5 mostra unesempio di grafico relativo alla memoria ram generato in modalita java.

Page 12: Hadoop analyzerJR

12 CONTENTS

Figura 2.3: Web page generata dal Hadoop Analyzer JR

Page 13: Hadoop analyzerJR

2.1. JAVA 13

Figura 2.4: Grafico cpu per lo slave 29

Page 14: Hadoop analyzerJR

14 CONTENTS

Figura 2.5: Grafico memoria ram per lo slave 29

Page 15: Hadoop analyzerJR

2.1. JAVA 15

2.1.2 Warning

Generati i grafici risulta interessante poter automatizzare un processo di clas-sificazione di questi ultimi. E di grande aiuto per l’utente avere una categoriadi grafici di ’warning’ che evidenziano eventuali colli di bottiglia presenti nelcluster. Uno scenario possibile e descritto di seguito:

• Warning positivi: Cpu, disk I/O e RAM utilizzati poco:

– se la cpu e usata poco l’esperimento dovrebbe essere I/O bound (pergiustificare il tempo in cui la cpu non lavora) o dovrebbe consumaremolta RAM (per giustificare il fatto di non aver usato al massimo laCPU);

– se l’I/O e la RAM sono utilizzati poco la cpu dovrebbe lavorare (ilprocesso e CPU bound); SUGGERIMENTO: si potrebbe ’caricare’maggiormente ogni cpu (aumentare il numero di task per slave)

• Warning negativi:

– SWAP alto (soglia stabilita dallutente):

– Rete sovraccarica (non sfruttiamo la massima localita dei dati)

– RAM sovraccarica SUGGERIMENTO: ridurre il numero di task perslave

L’utente dara in input:

• Warning positivi: % cpu, Mbyte I/O (disco) e RAM: se la cpu ha lavoratomeno della percentuale indicata dallutente e l’I/O e la RAM sono minoridi quella specificata dall’utente i grafici relativi andranno nella sezione diwarning

• Warning negativi:

– Mbyte swap: se lo swap e superiore ai megabyte inseriti dall’utenteil grafico relativo sara contrassegnato come warning chart

– Mbyte rete: se la rete e superiore di quanto specificato dall’utente ilgrafico relativo sara contrassegnato come warning chart

– Mbyte RAM: se la RAM utilizzata e superiore di quanto specificatodall’utente il grafico relativo sara contrassegnato come warning chart

Le figure 2.6 e 2.7 mostrano l’output generato.

2.1.3 Profiler

Inserendo il file generato da hprof nella cartella di input passata al tool (comedescritto nel manuale utente), il tool ne effettuera il parsing andando a ricavarei ’trace’. Per ciascun ’trace’ verra generato un link nella pagina web generata.Cliccando su ciascun link verra mostrata una tabella (autogenerata in html)contenente le informazioni sul ’trace’. Le figure 2.8 e 2.9 mostrano un esempiodi output.

Page 16: Hadoop analyzerJR

16 CONTENTS

Figura 2.6: Sezione relativa ai warning positivi dell’applicazione web autogen-erata

Figura 2.7: Sezione relativa ai warning negativi dell’applicazione web autogen-erata

Figura 2.8: Informazioni sul profiler

Page 17: Hadoop analyzerJR

2.2. R 17

Figura 2.9: Informazioni sul profiler - 2

2.2 R

In questa sezione sono descritte le principali funzionalita fornite dagli script R.

2.2.1 Dati formattati excel

E stato creato uno script in linguaggio R per l’aggregazione dei dati generati dadstat. In particolare, viene creato un file excel che contiene diversi sheet, uno perogni informazione ricevuta. Ad esempio, i primi 6 sheet sono relativi all’utilizzodella CPU nelle varie modalita (utente, sistema, ecc.). L’ultimo sheet presentainvece una versione ’aggregata’ dei dati, in modo da permettere all’utente unafacile interpretazione degli stessi.

2.2.2 SpeedUp ed efficienza

Lo speedup e una metrica relativa al miglioramento delle prestazioni mentre siesegue un task. Fu stabilita dalla legge di Amdahl, il quale era particolarmenteinteressato al calcolo parallelo. Comunque, lo speedup puo essere generalmenteusato per mostrare l’incremento delle performance. e definito dalla seguenteformula:

Speedup =Tseq

Tprl

In particolare, per tempo parallelo il tool si aspetta di ricevere in input dall’utenteun array contenente i tempi impiegati da ciascuna esecuzione su insiemi differ-

Page 18: Hadoop analyzerJR

18 CONTENTS

Figura 2.10: Tool per generazione speedup ed efficienza

enti di slave. L’efficienza di parallelizzazione e data da:

E = SN

dove S e lo speedup e N e il numero di slave. Dall’input dell’utente, il tool e ingrado di calcolare l’efficienza per ciascun insieme di slave. La figura 2.10 mostrala schermata dove l’utente puo inserire i parametri per lo speedup.

Page 19: Hadoop analyzerJR

Manuale utente

Introduzione

In questa sezione viene spiegato come installare ed utilizzare il tool.

19

Page 20: Hadoop analyzerJR

2014/2015

Amedeo Leo – Alessio Petrozziello –

Simone Romano

Progetto Sistemi Operativi Avanzati

2014/2015

Hadoop Analyzer JR User manual

Page 21: Hadoop analyzerJR

Hadoop Log Analyzer JR – User manual

Hadoop Log Analyzer JR – User manual

Installazione

Per iniziare, installare R dal sito http://cran.r-project.org (scegliere la versione binaria base).

Per utenti Windows:

Installare Rtools dallo stesso sito.

Occorre fare attenzione durante la fase di installazione di Rtools. È necessario procedere come di

seguito:

Terminata l’installazione, settare la variabile PATH facendola “puntare” alla cartella dei file di R. Ad

esempio,

Page 22: Hadoop analyzerJR

Hadoop Log Analyzer JR – User manual

Hadoop Log Analyzer JR – User manual

Installato Rtools, lanciare il file ‘install.bat’ presente nella cartella ’HadoopLogAnalyzer’.

Per utenti Mac:

lanciare il file ‘install.sh’ presente nella medesima cartella. Eventualmente assicurarsi che tale file

abbia i permessi di esecuzione.

E’ possibile settare tali permessi con:

chmod +x install.sh

Error

1. Nel caso in cui ‘R’ non fosse installato sulla macchina verrà mostrato a video il seguente

errore:

Si può risolvere installando R come spiegato precedentemente.

Page 23: Hadoop analyzerJR

Hadoop Log Analyzer JR – User manual

Hadoop Log Analyzer JR – User manual

Manuale utente

Il tool si presenta con questa interfaccia.

Come si può notare, è divisa in dstat, sulla sinistra, e Hadoop log, sulla destra. Di seguito sono

descritte le diverse caratteristiche.

01: Inserire la cartella di input dei file di dstat più il file “prof_output.txt” eventualmente generato

con l’attivazione del profiler. Per abilitare il profiler bisogna passare alla JVM la seguente riga:

-agentlib:hprof=cpu=times,heap=sites,depth=6,interval=10000,force=n,thread=y,verbose=n,file=prof.output

02: Inserire la cartella di output.

03: Scegliere il tool da utilizzare per generare i grafici (“R” creerà dei pdf, “Google/JFreeChart” una

pagina web).

04: Creazione del file excel contenente l’aggregazione dei dati generati da dstat.

05: Generazione dei grafici di dstat.

06: Possibilità di scegliere tra le varie percentuali di utilizzo della CPU. Nel caso in cui

“Google/JFreeChart” sia spuntato, saranno mostrati un grafico per ciascuna delle sei scelte e un

altro grafico per la somma delle percentuali scelte dall’utente. Nel caso in cui “R” sia spuntato, se

nessuna scelta è selezionata, saranno generati dei grafici per ciascuna scelta; se due o più scelte

sono selezionate, sarà mostrato all’utente un grafico contenete la somma delle scelte effettuate.

Nota: la somma delle percentuali verrà sempre normalizzata a 100.

07: Possibilità di scegliere tra le varie combinazioni della RAM. Nel caso in cui “Google/JFreeChart”

sia spuntato, saranno mostrati un grafico per ciascuna delle quattro scelte e un altro grafico per la

somma delle scelte dell’utente. Nel caso in cui “R” sia spuntato, se nessuna scelta è selezionata,

saranno generati dei grafici per ciascuna scelta; se due o più scelte sono selezionate, sarà mostrato

Page 24: Hadoop analyzerJR

Hadoop Log Analyzer JR – User manual

Hadoop Log Analyzer JR – User manual

all’utente un grafico contenete la somma delle scelte effettuate; inoltre viene data la possibilità di

inserire un upperbound al grafico della RAM.

08: Scelta della timeline in ore, minuti o secondi.

09: Scelta del tipo di grafico: nel caso in cui “Google/JFreeChart” sia spuntato, saranno mostrati i

grafici in una pagina web, in cui sono mostrati anche eventuali grafici di warning. Nel caso in cui

“R” sia spuntato, saranno mostrati i grafici in dei file pdf. La scelta effettuabile varia tra “Singles”,

“All in” e “Average”. Nel primo caso, se “Google/JFreeChart” è spuntato, verranno prodotti dei

grafici singoli in cui sarà mostrato il relativo slave e il master per ciascuna delle scelte effettuate;

se invece “R” è spuntato, saranno generati dei grafici singoli per ciascuno slave e per il master a

seconda delle scelte fatte. Nel caso “All in” viene generato, per ogni sezione (CPU, Memoria,

Network...) un solo grafico contenente tutti i nodi del cluster. Nel caso “Average”, infine, viene

mostrato, per ogni sezione, un grafico contenente il master e la media di tutti gli slave del cluster.

10: Scelta della colorazione del grafico (scala di grigi, di default è a colori).

11: Scelta dello stile della linea (tratteggiata, di default è continua).

12: Possibilità di inserire il titolo in ciascun grafico.

13: Altre possibilità date all’utente: dimensione del font e scelta del tipo di grafico, su un singolo

file o su più file; nel secondo caso, sarà possibile effettuare la scelta solo se “R” è stato spuntato.

14: Possibilità di scegliere se combinare in uno stesso grafico l’I/O del disco o in due grafici

separati. Sarà possibile effettuare la scelta solo se “R” è stato spuntato.

15: Possibilità di scegliere se combinare in uno stesso grafico il paging o in due grafici separati.

Sarà possibile effettuare la scelta solo se “R” è stato spuntato.

16: Possibilità di scegliere se combinare in uno stesso grafico i pacchetti ricevuti o inviati o in due

grafici separati. Sarà possibile effettuare la scelta solo se “R” è stato spuntato.

17: Possibilità di scegliere se combinare in uno stesso grafico l’utilizzo della rete in e out o in due

grafici separati. Sarà possibile effettuare la scelta solo se “R” è stato spuntato.

18: Nel caso in cui “Google/JFreeChart” sia attivato, l’utente può settare, per i grafici di warning

positivi, la percentuale di CPU, di utilizzo del disco (in MB/s) e della RAM (in GB). Se l’utilizzo di

CPU è minore della percentuale inserita dall’utente, se il disco è stato utilizzato meno di quanto ha

inserito l’utente e se la RAM è stata utilizzata meno di quanto inserito dall’utente, allora, per

ciascuno slave in cui tali assunzioni risultano vere, verrà segnalato un warning positivo.

19: Nel caso in cui “Google/JFreeChart” sia attivato, l’utente può settare, per i grafici di warning

negativi, lo swap (in MB), l’utilizzo della rete (in MB/s) e della RAM (in GB). Se almeno una delle

risorse è utilizzata più di quanto l’utente ha selezionato allora verrà dato un warning negativo.

20: Shell che mostra la computazione del tool.

21: Inserire la cartella di input dei log di Hadoop.

22: Inserire la cartella di output dei log di Hadoop.

Page 25: Hadoop analyzerJR

Hadoop Log Analyzer JR – User manual

Hadoop Log Analyzer JR – User manual

23: Generazione dei grafici dei log di Hadoop.

In caso di errore controllare che nella cartella di input dei log non siano presenti file diversi da

‘attempt*’.

24: Pdf viewer per i grafici generati dal linguaggio R.

25: Possibilità di visualizzare il file precedente o successivo all’interno della stessa cartella.

26: Permette di mostrare le label con i nomi degli slave.

27: Scelta della timeline in ore, minuti o secondi per i grafici relativi ai log di Hadoop.

Nel menù, cliccando su “File”, sono presentate queste scelte.

Il tool permette di inserire una configurazione precedentemente salvata dall’utente. Cliccando su

“Open”, l’utente può scegliere il file precedentemente creato.

Se l’utente desidera salvare la nuova configurazione, cliccando su “Save” sarà automaticamente

salvata al posto della precedente. Altrimenti, l’utente deve necessariamente cliccare “Save as…”

per poter salvare la configurazione. “Exit” permette di chiudere il programma.

Page 26: Hadoop analyzerJR

Hadoop Log Analyzer JR – User manual

Hadoop Log Analyzer JR – User manual

Nel menù, cliccando su “Tools”, si apre questa schermata.

Si permette all’utente di inserire i parametri di seguito descritti, in modo da generare i grafici

relativi allo speedup e all’efficienza.

01: Permette di aggiungere una riga alla tabella. In particolare, l’utente può inserire il numero di

nodi e il relativo tempo di esecuzione.

02: Permette di cancellare l’ultima riga della tabella.

03: Permette di inserire il tempo sequenziale.

04: Genera i grafici relativi a speedup e efficienza.

05: Pdf viewer per i grafici generati dal linguaggio R.

Nel menù, cliccando su “Help”, sono visualizzate due opzioni.

Page 27: Hadoop analyzerJR

Hadoop Log Analyzer JR – User manual

Hadoop Log Analyzer JR – User manual

Cliccando su “Manual”, sarà scaricato il manuale che si sta leggendo.

Cliccando su “About”, viene visualizzata questa schermata.

Page 28: Hadoop analyzerJR

Caso di studio

Introduzione

Per dimostrare la correttezza del tool, e stato testato su due casi d’uso: perentrambi si tratta del classico WordCount; tuttavia, nel primo sono state utiliz-zate le espressioni regolari per eliminare caratteri speciali, mentre nel secondoquesti ultimi sono stati sostituiti con dei controlli.

4.1 Configurazione cluster

Riportiamo di seguito i file ’.xml’ contenenti la configurazione del cluster durantela esecuzione dei test. E importante evidenziare che non viene utilizzata la cachedi Hadoop per il caricamento del file delle stop words utilizzate. Nei grafici dellarete mostrati si noteraun picco iniziale corrispondente al caricamento del file suivari nodi.

4.1.1 Yarn-site.xml

Di seguito il file ’yarn-site.xml’ utilizzato per l’esperimento. In particolare perciascun container sono stati predisposti 3GB di spazio.

<?xml version="1.0"?>

<!--

Licensed under the Apache License, Version 2.0 (the "License");

you may not use this file except in compliance with the License.

You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software

distributed under the License is distributed on an "AS IS" BASIS,

WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or

implied.

See the License for the specific language governing permissions and

limitations under the License. See accompanying LICENSE file.

-->

28

Page 29: Hadoop analyzerJR

4.1. CONFIGURAZIONE CLUSTER 29

<configuration>

<property>

<name>yarn.nodemanager.aux-services</name>

<value>mapreduce_shuffle</value>

</property>

<property>

<name>yarn.nodemanager.aux-services.mapreduce.shuffle.class</name>

<value>org.apache.hadoop.mpred.ShuffleHandler</value>

</property>

<property>

<name>yarn.resourcemanager.address</name>

<value>slave63:8032</value>

</property>

<property>

<name>yarn.resourcemanager.scheduler.address</name>

<value>slave63:8030</value>

</property>

<property>

<name>yarn.resourcemanager.resource-tracker.address</name>

<value>slave63:8031</value>

</property>

<property>

<name>yarn.resourcemanager.admin.address</name>

<value>slave63:8033</value>

</property>

<property>

<name>yarn.resourcemanager.webapp.address</name>

<value>slave63:8088</value>

</property>

<property>

<name>mapreduce.jobhistory.webapp.address</name>

<value>slave63:19888</value>

</property>

<property>

<name>mapreduce.jobhistory.address</name>

<value>slave63:10020</value>

</property>

<!-- Site specific YARN configuration properties -->

<property>

<name>yarn.nodemanager.resource.memory-mb</name>

<value>3072</value>

</property>

</configuration>

Page 30: Hadoop analyzerJR

30 CONTENTS

4.2 hdfs-site.xml

Tale file indica la size di caiascun blocco (nell’esempio 128MB) ed il numero direpliche fatte per ciascun blocco di dati (3 nell’esempio).

<?xml version="1.0" encoding="UTF-8"?>

<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>

<configuration>

<property>

<name>dfs.replication</name>

<value>3</value>

</property>

<property>

<name>dfs.blocksize</name>

<value>128m</value>

</property>

<property>

<name>dfs.namenode.name.dir</name>

<value>file:/home/user/mydata/hdfs/namenode</value>

</property>

<property>

<name>dfs.datanode.data.dir</name>

<value>file:/home/user/mydata/hdfs/datanode</value>

</property>

</configuration>

4.3 WordCount

Mostriamo di seguito entrambi i codici ’WordCount’ utilizzati. Il successivo e ilcodice ’WordCount’ che utilizza le espressioni regolari.

package hadoop;

import java.io.IOException;

public class WordCount extends Configured implements Tool {

/*

* NLineInputFormat which splits N lines of input as one split.

* In many "pleasantly" parallel applications, each process/mapper

processes the same input file (s),

* but with computations are controlled by different

parameters.(Referred to as "parameter sweeps").

Page 31: Hadoop analyzerJR

4.3. WORDCOUNT 31

* One way to achieve this, is to specify a set of parameters (one

set per line) as input in a control file

* (which is the input path to the map-reduce application, where as

the input dataset is specified via a config variable in

JobConf.).

* The NLineInputFormat can be used in such applications, that splits

the input file such that by default,

* one line is fed as a value to one map task, and key is the offset.

i.e. (k,v) is (LongWritable, Text).

* The location hints will span the whole mapred cluster.

*/

//run configurations: args[0]: INPUT args[1]:OUTPUT

public static final Integer N = 20000;

public static void main(String args[]) throws Exception {

int res = ToolRunner.run(new WordCount(), args);

System.exit(res);

}

public int run(String[] args) throws Exception {

Path inputPath = new Path(args[0]);

Path outputPath = new Path(args[1]);

Configuration conf = getConf();

Job job = Job.getInstance(conf, "word count");

FileInputFormat.setInputPaths(job, inputPath);

//NLineInputFormat.addInputPath(job, inputPath);

FileOutputFormat.setOutputPath(job, outputPath);

job.setJarByClass(this.getClass());

job.setInputFormatClass(TextInputFormat.class);

//job.setInputFormatClass(NLineInputFormat.class);

//NLineInputFormat.setNumLinesPerSplit(job, N); //Set the number

of lines per split

job.setOutputFormatClass(TextOutputFormat.class);

job.setMapOutputKeyClass(Text.class);

job.setMapOutputValueClass(IntWritable.class);

job.setOutputKeyClass(Text.class);

job.setOutputValueClass(IntWritable.class);

job.setMapperClass(Map.class);

job.setCombinerClass(Reduce.class);

job.setReducerClass(Reduce.class);

Page 32: Hadoop analyzerJR

32 CONTENTS

return job.waitForCompletion(true) ? 0 : 1;

}

public static class Map extends Mapper<LongWritable, Text, Text,

IntWritable>{

private final static IntWritable one = new IntWritable(1);

private final Text word = new Text();

HashMap<String, String> stopWords = new HashMap<String, String>();

@Override

public void setup(Context context) throws IOException,

InterruptedException{

super.setup(context);

Scanner in;

try {

//in = new Scanner(new File("stopWords.txt"));

in = new

Scanner(Map.class.getResourceAsStream("italianStopWords.txt"));

while(in.hasNextLine()){

//word.set(in.nextLine());

//stopWords.put(word.toString(),word.toString() );

String tmp = in.nextLine();

stopWords.put(tmp, tmp);

}

in.close();

} catch(NoSuchElementException e1){

System.out.println("no such....");

}

}

@Override

public void map(LongWritable key, Text value, Context context)

throws IOException, InterruptedException {

String line = value.toString();

line = myStringSplit(line);

StringTokenizer tokenizer = new StringTokenizer(line);

while (tokenizer.hasMoreTokens()) {

String tmp = tokenizer.nextToken();

tmp = tmp.trim();

if(stopWords.get(tmp) == null){

word.set(tmp);

context.write(word, one);

Page 33: Hadoop analyzerJR

4.3. WORDCOUNT 33

}

}

}

}

public static String myStringSplit(String s){

String result = s.toLowerCase();

String replacement = " ";

String regex =

"[=]|[.]|[;]|[:]|[,]|[’]|[\"]|[?]|[!]|[)]|[(]|[<]|[>]|[{]|[}]|[[]|

[\\]]|[#]|[*]|[-]|[&]|[_]|[$]|[‘]|[/]";

result = result.replaceAll(regex, replacement);

return result;

}

public static class Reduce extends Reducer<Text, IntWritable, Text,

IntWritable> {

@Override

public void reduce(Text key, Iterable<IntWritable> values, Context

context) throws IOException, InterruptedException {

int sum = 0;

for (IntWritable value : values) {

sum += value.get();

}

context.write(key, new IntWritable(sum));

}

}

}

Mostriamo ora il codice di ’WordCount’ che evita di utilizzare le espressioniregolari utilizzando il metodo dell’oggetto String ’charAt’.

package hadoop;

import java.io.IOException;

import java.io.Serializable;

import java.util.*;

import org.apache.hadoop.conf.*;

import org.apache.hadoop.fs.*;

import org.apache.hadoop.io.*;

import org.apache.hadoop.mapreduce.*;

import org.apache.hadoop.mapreduce.lib.input.*;

import org.apache.hadoop.mapreduce.lib.output.*;

import org.apache.hadoop.util.*;

public class WordCount extends Configured implements Tool {

Page 34: Hadoop analyzerJR

34 CONTENTS

/*

* NLineInputFormat which splits N lines of input as one split.

* In many "pleasantly" parallel applications, each process/mapper

processes the same input file (s),

* but with computations are controlled by different

parameters.(Referred to as "parameter sweeps").

* One way to achieve this, is to specify a set of parameters (one

set per line) as input in a control file

* (which is the input path to the map-reduce application, where as

the input dataset is specified via a config variable in

JobConf.).

* The NLineInputFormat can be used in such applications, that splits

the input file such that by default,

* one line is fed as a value to one map task, and key is the offset.

i.e. (k,v) is (LongWritable, Text).

* The location hints will span the whole mapred cluster.

*/

//run configurations: args[0]: INPUT args[1]:OUTPUT

public static final Integer N = 20000;

public static void main(String args[]) throws Exception {

int res = ToolRunner.run(new WordCount(), args);

System.exit(res);

}

public int run(String[] args) throws Exception {

Path inputPath = new Path(args[0]);

Path outputPath = new Path(args[1]);

Configuration conf = getConf();

Job job = Job.getInstance(conf, "word count");

FileInputFormat.setInputPaths(job, inputPath);

//NLineInputFormat.addInputPath(job, inputPath);

FileOutputFormat.setOutputPath(job, outputPath);

job.setJarByClass(this.getClass());

job.setInputFormatClass(TextInputFormat.class);

//job.setInputFormatClass(NLineInputFormat.class);

//NLineInputFormat.setNumLinesPerSplit(job, N); //Set the number

of lines per split

Page 35: Hadoop analyzerJR

4.3. WORDCOUNT 35

job.setOutputFormatClass(TextOutputFormat.class);

job.setMapOutputKeyClass(Text.class);

job.setMapOutputValueClass(IntWritable.class);

job.setOutputKeyClass(Text.class);

job.setOutputValueClass(IntWritable.class);

job.setMapperClass(Map.class);

job.setCombinerClass(Reduce.class);

job.setReducerClass(Reduce.class);

return job.waitForCompletion(true) ? 0 : 1;

}

public static class Map extends Mapper<LongWritable, Text, Text,

IntWritable>{

private final static IntWritable one = new IntWritable(1);

private final Text word = new Text();

HashMap<String, String> stopWords = new HashMap<String, String>();

@Override

public void setup(Context context) throws IOException,

InterruptedException{

super.setup(context);

Scanner in;

try {

//in = new Scanner(new File("stopWords.txt"));

in = new

Scanner(Map.class.getResourceAsStream("italianStopWords.txt"));

while(in.hasNextLine()){

//word.set(in.nextLine());

//stopWords.put(word.toString(),word.toString() );

String tmp = in.nextLine();

stopWords.put(tmp, tmp);

}

in.close();

} catch(NoSuchElementException e1){

System.out.println("no such....");

}

}

@Override

public void map(LongWritable key, Text value, Context context)

throws IOException, InterruptedException {

Page 36: Hadoop analyzerJR

36 CONTENTS

String line = value.toString();

line = myStringSplit(line);

StringTokenizer tokenizer = new StringTokenizer(line);

while (tokenizer.hasMoreTokens()) {

String tmp = tokenizer.nextToken();

tmp = tmp.trim();

if(stopWords.get(tmp) == null){

word.set(tmp);

context.write(word, one);

}

}

}

}

public static String myStringSplit(String s){

String result = s.toLowerCase();

char replacement = ’ ’;

for(int i=0; i<s.length(); i++){

char tmp = result.charAt(i);

if(tmp == ’=’){

result.replace(result.charAt(i), replacement);

continue;

}

if(tmp == ’.’){

result.replace(result.charAt(i), replacement);

continue;

}

if(tmp == ’;’){

result.replace(result.charAt(i), replacement);

continue;

}

if(tmp == ’:’){

result.replace(result.charAt(i), replacement);

continue;

}

if(tmp == ’,’){

result.replace(result.charAt(i), replacement);

continue;

}

if(tmp == ’\’’){

result.replace(result.charAt(i), replacement);

continue;

}

if(tmp == ’\"’){

result.replace(result.charAt(i), replacement);

continue;

}

if(tmp == ’?’){

Page 37: Hadoop analyzerJR

4.3. WORDCOUNT 37

result.replace(result.charAt(i), replacement);

continue;

}

if(tmp == ’!’){

result.replace(result.charAt(i), replacement);

continue;

}

if(tmp == ’(’){

result.replace(result.charAt(i), replacement);

continue;

}

if(tmp == ’)’){

result.replace(result.charAt(i), replacement);

}

if(tmp == ’<’){

result.replace(result.charAt(i), replacement);

continue;

}

if(tmp == ’>’){

result.replace(result.charAt(i), replacement);

continue;

}

if(tmp == ’{’){

result.replace(result.charAt(i), replacement);

continue;

}

if(tmp == ’}’){

result.replace(result.charAt(i), replacement);

continue;

}

if(tmp == ’[’){

result.replace(result.charAt(i), replacement);

continue;

}

if(tmp == ’]’){

result.replace(result.charAt(i), replacement);

continue;

}

if(tmp == ’#’){

result.replace(result.charAt(i), replacement);

continue;

}

if(tmp == ’*’){

result.replace(result.charAt(i), replacement);

continue;

}

if(tmp == ’-’){

result.replace(result.charAt(i), replacement);

continue;

}

Page 38: Hadoop analyzerJR

38 CONTENTS

if(tmp == ’&’){

result.replace(result.charAt(i), replacement);

continue;

}

if(tmp == ’_’){

result.replace(result.charAt(i), replacement);

continue;

}

if(tmp == ’$’){

result.replace(result.charAt(i), replacement);

continue;

}

if(tmp == ’‘’){

result.replace(result.charAt(i), replacement);

continue;

}

if(tmp == ’/’){

result.replace(result.charAt(i), replacement);

continue;

}

}

//result = result.replaceAll(regex, replacement);

return result;

}

public static class Reduce extends Reducer<Text, IntWritable, Text,

IntWritable> {

@Override

public void reduce(Text key, Iterable<IntWritable> values, Context

context) throws IOException, InterruptedException {

int sum = 0;

for (IntWritable value : values) {

sum += value.get();

}

context.write(key, new IntWritable(sum));

}

}

}

4.4 Input

Il file di input utilizzato, ovvero la Divina Commedia in un file formato txt, hadimensioni 38,19GB; tale file e stato ottenuto replicando il contenuto inizialedel testo. Sono stati effettuati tre test per ciascun caso d’uso. Iniziando dallarete a disposizione, i test sono stati effettuati presso l’Universita degli Studi di

Page 39: Hadoop analyzerJR

4.5. TEST 39

Salerno all’interno del Laboratorio RETI della Dipartimento di Informatica suuna griglia di 32 macchine.

4.4.1 Specifiche delle macchine

Seguono le caratteristiche hardware delle macchine utilizzate:

• SISTEMA OPERATIVO: Windows 7

• CPU: Intel(R) Celeron(R) CPU G530 @ 2.40GHz 3.0 GHz - Thread(s) percore 1, Core(s) per socket 1, Socket(s) 2 CPU MHz 3100.000 - Architecturex86 64, CPU op-mode(s) 32-bit, 64-bit, CPU(s) 2

• RAM: 4GB

• HARD DISK: 250GB

Hadoop e stato installato su una macchina virtuale VMWARE con sistemaoperativo Ubuntu Linux 12.04 LTS con 2CPU, 3100MB di RAM e HARD DISKda 120 GB. La versione di Hadoop utilizzata e 2.5.1 con Java 1.8.0 20.

4.5 Test

2 sono i casi d’uso analizzati:

• WordCount con espressioni regolari

• WordCount con controlli sui singoli caratteri

Per il primo caso d’uso sono stati effettuati 3 test che hanno impiegato24.53 minuti, 13.6 minuti, 12.55 minuti. Per il secondo caso d’uso, i test hannoimpiegato 9.29 minuti, 15.44 minuti, 8.40 minuti.

test1 test2 test3 mediaWord Count Regexp 24.53 13.60 12.55 16.89Word Count CharAt 9.29 15.44 8.40 11.04

4.6 Risultati

Di seguito sono mostrati, per ciascun sezione, i grafici generati dal tool utiliz-zando sia le librerie R che la modalita ChartsForJ/JFreeChart (librerie Java).In particolare analizzeremo il caso di studio Word Count Regexp e vedremocome, con l’aiuto del tool, si riescono ad evidenziare eventuali malfunzionamentidel cluster.

Page 40: Hadoop analyzerJR

40 CONTENTS

Figura 4.11: Media utilizzo CPU

4.6.1 Analisi Dstat

Per i dati generati con dstat sono state generate le 3 modalita di grafici che iltool consente di estrarre, ovvero:

• Single charts

• Average

• All in

Sono stati generati ed analizzati in primo momento i grafici in modalita aver-age per controllare l’andamento generale dell’utilizzo delle risorse da parte delcluster. Come prevedibile, il lavoro risulta CPU bound; l’utilizzo medio dellamemoria RAM e risultato sotto i 1400MB mentre l’andamento medio della cpue stato intorno al 70-80% come si puo vedere nella figura 4.11.

Per avere un maggiore livello di dettaglio si sono analizzati i grafici contenentitutti gli slave singolarmente. I grafici sono mostrati nelle figure 4.12 e 4.13.

In tali figure si nota che uno slave ha lavorato meno degli altri restando inmedia sotto il 60%. Per scendere ulteriormente nel dettaglio sono stati generatii grafici singoli. Per tali grafici abbiamo tentato di evidenziare, con l’aiuto deltool, gli slave la cui CPU ha lavorato sotto il 70%. Sono stati generati i grafici

Page 41: Hadoop analyzerJR

4.6. RISULTATI 41

Figura 4.12: Utilizzo CPU di tutti i nodi del cluster. Grafico generato conlibrerie Java.

Figura 4.13: Utilizzo CPU (campo ’usr’) di tutti i nodi del cluster. Graficogenerato con librerie R.

Page 42: Hadoop analyzerJR

42 CONTENTS

Figura 4.14: Warning chart per lo slave 83. La CPU ha lavorato meno del 70%per almeno il 60% dell’esperimento.

e, come da aspettativa, il tool ha generato un warning positivo per lo slave 83(vedi figura 4.14 e figura 4.15).

E stato possibile evidenziare con la modalita warning charts, inoltre, chelo slave 56 non ha proprio lavorato durante l’esperimento (vedi figura 4.16 efigura 4.17).

4.6.2 Analisi Log Hadoop

L’utente puo scegliere se visualizzare i nomi degli slave e la timeline. In questocaso, sono presentati i nomi dei nodi e la timeline in minuti, data la duratadell’esperimento. Come si puo vedere nella legenda sulla destra del grafico infigura, i task mostrati in rosso sono i ’SUCCEEDED’, i verdi sono ’FAILED’e i blu sono i ’KILLED’. In particolare, sono rappresentati i task per ciascunoslave. Qualora i task dovessero sovrapporsi, e stata generata una nuova lineaper ciascuna sovrapposizione, in modo da distinguere la computazione.

Page 43: Hadoop analyzerJR

4.6. RISULTATI 43

Figura 4.15: Warning chart per lo slave 83. La CPU ha lavorato meno del 70%per almeno il 60% dell’esperimento.

Page 44: Hadoop analyzerJR

44 CONTENTS

Figura 4.16: Warning chart per lo slave 56.

Page 45: Hadoop analyzerJR

slave53 / 1slave53 / 2slave53 / 3slave55 / 1slave55 / 2slave55 / 3slave58 / 1slave58 / 2slave58 / 3slave59 / 1slave59 / 2slave59 / 3slave60 / 1slave60 / 2slave60 / 3slave61 / 1slave61 / 2slave61 / 3slave62 / 1slave62 / 2slave62 / 3slave64 / 1slave64 / 2slave64 / 3slave65 / 1slave65 / 2slave65 / 3slave67 / 1slave67 / 2slave67 / 3slave69 / 1slave69 / 2slave69 / 3slave70 / 1slave70 / 2slave70 / 3slave71 / 1slave71 / 2slave71 / 3slave72 / 1slave72 / 2slave72 / 3slave73 / 1slave73 / 2slave73 / 3slave74 / 1slave74 / 2slave74 / 3slave75 / 1slave75 / 2slave75 / 3slave76 / 1slave76 / 2slave76 / 3slave77 / 1slave77 / 2slave77 / 3slave79 / 1slave79 / 2slave79 / 3slave80 / 1slave80 / 2slave80 / 3slave82 / 1slave82 / 2slave82 / 3slave83 / 1slave84 / 1slave84 / 2slave84 / 3slave85 / 1slave85 / 2slave85 / 3slave86 / 1slave86 / 2slave86 / 3slave87 / 1slave87 / 2slave87 / 3slave89 / 1slave89 / 2slave89 / 3slave94 / 1slave94 / 2slave94 / 3slave95 / 1slave95 / 2slave95 / 3

0 5 10 15 20

Time (m)

Nod

e

State

SUCCEEDED

FAILED

KILLED

Log Hadoop

Page 46: Hadoop analyzerJR

46 CONTENTS

4.7 Confronto esperimenti

Come riportato in tabella 4.5 l’esecuzione di ’WordCount’ con l’utilizzo delleespressioni regolari e risultata piu lunga. Le figure 4.18 e 4.19 mostrano i graficidell’utilizzo di CPU per i entrambi i casi. Si evince che il cluster non eviden-zia malfunzionamenti in quanto le CPU lavorano in entrambi gli esperimenti.L’utilizzo delle espressioni regolari richiede piu tempo di utilizzo di CPU peressere eseguito.

Page 47: Hadoop analyzerJR

4.7. CONFRONTO ESPERIMENTI 47

Figura 4.17: Warning chart per lo slave 56.

Figura 4.18: Grafico utilizzo CPU ’WordCount’ con espressioni regolari.

Page 48: Hadoop analyzerJR

48 CONTENTS

Figura 4.19: Grafico utilizzo CPU ’WordCount’ con utilizzo metodo ’charAt()’.

Page 49: Hadoop analyzerJR

Appendice

Introduzione

In questa sezione sono elencati estratti piu significativi del codice realizzato siaper la parte Java che per la parte di R.

5.1 Java code

Di seguito sono elencati le classi java che svolgono la parte piu significativa.

5.1.1 Parser csv

La seguente classe si occupa di analizzare i file ’.csv’ per estrarre le informazionisulle risorse utilizzate da ciascuna macchina del cluster.

package csvManipluators;

import java.io.File;

import java.io.FileNotFoundException;

import java.io.FileReader;

import java.io.PrintWriter;

import java.io.UnsupportedEncodingException;

import java.util.ArrayList;

import java.util.List;

import java.util.Scanner;

import java.util.logging.Logger;

import org.apache.commons.csv.CSVFormat;

import org.apache.commons.csv.CSVParser;

import org.apache.commons.csv.CSVRecord;

/**

*

* @author Romano Simone - www.sromano.altervista.org

* This class allows you to manipulate csv file.

*/

public class Parser {

49

Page 50: Hadoop analyzerJR

50 CONTENTS

private static Logger log = Logger.getLogger("global");

private static String csvHeader =

"time,usr,sys,idl,wai,hiq,siq,used,buff,cach,free,in,out,usedSwap,

\\ freeSwap,read,writ,recv,send,int,cntsw, recvTotPkt,sendTotPkt";

private static String MY_FILE_EXTENSION = "_Cleared.hla";

/**

* Return an arraylist of record with only column defined in toGet

array.

* @param csvFilePath file to read

* @param toGet value to return

* @return arraylist of record with only column defined in toGet

array.

* @throws UnsupportedEncodingException

* @throws FileNotFoundException

*/

public ArrayList<String> getDataFromCsv(String csvFilePath,

ArrayList<String> toGet){

String clearedFilePath = csvFilePath + MY_FILE_EXTENSION;

clearCsvFile(csvFilePath, clearedFilePath);

ArrayList<String> toReturn = new ArrayList<String>();

CSVParser parser;

try{

parser = new CSVParser(new FileReader(clearedFilePath),

CSVFormat.DEFAULT.withHeader());

for (CSVRecord record : parser) {

String subRecord = "";

for (String column:toGet){

if (subRecord.length() > 0)

subRecord = subRecord + "," + record.get(column);

else subRecord = subRecord + record.get(column);

}

toReturn.add(subRecord);

}

parser.close();

}catch(Exception e){

log.severe("Exception parsing csv File: " + e.getMessage());

e.printStackTrace();

}

return toReturn;

}

/**

* This method will extract delay between 2 record

* in csv file in input.

* @param csvFilePath Path of csv cleared file.

* @return interval(in seconds) between 2 records.

*/

public int getRecordsIntervalFromCsv(String csvFilePath){

CSVParser parser;

Page 51: Hadoop analyzerJR

5.1. JAVA CODE 51

try{

parser = new CSVParser(new FileReader(csvFilePath +

MY_FILE_EXTENSION), CSVFormat.DEFAULT.withHeader());

List<CSVRecord> records = parser.getRecords();

if (records.size() == 0 || records.size() == 1)

return 1;

String firstTime = records.get(0).get("time").split("

")[1].split(":")[2]; //get seconds

String secondTime = records.get(1).get("time").split("

")[1].split(":")[2]; //get seconds

parser.close();

int firstTimeVal = Integer.parseInt(firstTime);

int secondTimeVal = Integer.parseInt(secondTime);

int toReturn = secondTimeVal - firstTimeVal;

if (toReturn < 0)

toReturn = (secondTimeVal + 60) - firstTimeVal;

log.info("Finding interval between records: " + toReturn);

return toReturn;

}catch(Exception e){

log.severe("Exception parsing csv File: " + e.getMessage());

e.printStackTrace();

}

log.info("Finding interval between records: " + 0);

return 0;

}

/**

* This method will clear csv dstat file from

* extra comments.

* @param filePath path of file to clear

* @param clearedFilePath path of new file cleared

* @throws FileNotFoundException if file doesn’t exist

* @throws UnsupportedEncodingException

*/

private void clearCsvFile(String filePath, String clearedFilePath){

try{

File file = new File(filePath);

Scanner input;

try {

input = new Scanner(file);

PrintWriter writer = new PrintWriter(clearedFilePath,

"UTF-8");

boolean writingData = false;

while(input.hasNext()) {

String nextLine = input.nextLine();

if (writingData){

writer.println(nextLine);

}

else{ //we need to delete first dstat row???

if

Page 52: Hadoop analyzerJR

52 CONTENTS

(nextLine.equals("\"time\",\"usr\",\"sys\",\"idl\",\"wai\",\"hiq\",\"siq\",

\\

\"used\",\"buff\",\"cach\",\"free\",\"in\",\"out\",\"used\",\"free\",\"read\",\"writ\",\"recv\",\"send\",\"int\"

\\ ,\"csw\",\"#recv\",\"#send\"") ||

nextLine.equals("\"time\",\"usr\",\"sys\",\"idl\",\"wai\",\"hiq\",\"siq\",\"used\"

\\

,\"buff\",\"cach\",\"free\",\"in\",\"out\",\"used\",\"free\",\"read\",\"writ\",\"recv\",\"send\",\"int\",\"csw\",\\

\" #recv\",\"#send\",")){

writer.println(csvHeader);

writingData = true;

}

}

}

writer.close();

input.close();

} catch (FileNotFoundException e) {

log.severe(e.getMessage());

e.printStackTrace();

return;

} catch (UnsupportedEncodingException e) {

log.severe(e.getMessage());

e.printStackTrace();

return;

}

log.info("Created cleared file: " + clearedFilePath);

}catch(Exception e){

log.severe("Exception parsing file: " + filePath);

}

}

/**

* This method makes an array of double with each string

* contained in data.

* @param data list of data as String.

* @return list of data as double array to use it as Generator method

input.

*/

public double[] generateDoubleArrayFrom(ArrayList<String> data){

double[] toReturn = new double[1];

int position = 0;

for(String r:data){

//creating cpu dataset(array of double) for ChartGeneratorCpu

toReturn[position] = Double.parseDouble(r);

position++;

if (position > toReturn.length - 1){

if(!(position > data.size()-1)){

double[] tmp = new double[position + 1];

System.arraycopy(toReturn, 0, tmp, 0, toReturn.length);

toReturn = tmp;

}

Page 53: Hadoop analyzerJR

5.1. JAVA CODE 53

}

}

return toReturn;

}

/**

* This method makes an array of double with each string

* contained in data.

* @param data list of data as String where each element could

contains more data separated by ’,’.

* @param OPERATION is the operation to join each string.

* @return list of data as double array to use it as Generator method

input.

*/

public double[] generateDoubleArrayFrom(ArrayList<String> data, int

OPERATION){

ArrayList<String> toReturn = new ArrayList<String>();

for(String r:data){

String[] row = r.split(",");

double toAdd = 0;

switch (OPERATION){

case 1: //SUM

for (String s:row){

toAdd += Double.parseDouble(s);

}

toReturn.add(toAdd + "");

break;

case 2: //SUB

for (String s:row){

toAdd -= Double.parseDouble(s);

}

toReturn.add(toAdd + "");

break;

case 3: //DIV

for (String s:row){

toAdd /= Double.parseDouble(s);

}

toReturn.add(toAdd + "");

break;

case 4: //MULT

for (String s:row){

toAdd *= Double.parseDouble(s);

}

toReturn.add(toAdd + "");

break;

}

}

return generateDoubleArrayFrom(toReturn);

}

}

Page 54: Hadoop analyzerJR

54 CONTENTS

5.1.2 ChartGenerator

La classe ’chartGenerator.java’ espone dei metodi per la generazione di grafici.Tali metodi prendono diversi parametri che consentono di personalizzare ilgrafico a seconda delle esigenze dell’utente.

package chartsGenerators;

import static com.googlecode.charts4j.Color.SKYBLUE;

import java.util.ArrayList;

import java.util.logging.Logger;

import chartsManager.Chart;

import chartsManager.Chart_sCollector;

import com.googlecode.charts4j.AxisLabels;

import com.googlecode.charts4j.AxisLabelsFactory;

import com.googlecode.charts4j.AxisStyle;

import com.googlecode.charts4j.AxisTextAlignment;

import com.googlecode.charts4j.Color;

import com.googlecode.charts4j.DataUtil;

import com.googlecode.charts4j.Fills;

import com.googlecode.charts4j.GCharts;

import com.googlecode.charts4j.Line;

import com.googlecode.charts4j.LineChart;

import com.googlecode.charts4j.LineStyle;

import com.googlecode.charts4j.Plots;

import csvManipluators.Parser;

/**

*

* @author Romano Simone - www.sromano.altervista.org

* This class generates chart.

*/

public class ChartGenerator implements Generator{

private static final int IF_ZERO = 50;

private static Logger log = Logger.getLogger("global");

private String url;

public static int SUM = 1, SUB = 2, DIV = 3, MULT = 4, MINUTE = 5,

SECOND = 6, HOUR = 7;

Page 55: Hadoop analyzerJR

5.1. JAVA CODE 55

public String getUrl() {

return url;

}

/**

* This method generate the usage’s chart.

* @param data1 Contains value.

* @param interval Interval between each x value(in SECOND)

* @param scaleIn could be minute, second or hour and indicates

interval to show on x

* @param isPercentage if it’s true the y value will be scaled in %

* @param title title of chart

* @param dataTitle name of line

* @param yLabel label of y axis

* @param isDashedLine

* @param isGrayScale to choice greyscale mode

* @param isDashedLine to choice dashed line mode

*/

private void generateChart(double[] data,int interval, int scaleIn,

boolean isPercentage, String title, String dataTitle, String

yLabel, boolean isGreyScale, boolean isDashedLine){

//plotting data

Line line;

AxisLabels yAxis;

if (isPercentage){

if (isGreyScale){

line = Plots.newLine(DataUtil.scaleWithinRange(0,100,data),

Color.newColor("000000"), dataTitle);

yAxis = AxisLabelsFactory.newNumericRangeAxisLabels(0,100);

}

else{

line = Plots.newLine(DataUtil.scaleWithinRange(0,100,data),

Color.newColor("CA3D05"), dataTitle);

yAxis = AxisLabelsFactory.newNumericRangeAxisLabels(0,100);

}

}

else{

if (isGreyScale){

line =

Plots.newLine(DataUtil.scaleWithinRange(0,getMax(data)+(getMax(data)/10),data),

\newline Color.newColor("000000"), dataTitle);

yAxis =

AxisLabelsFactory.newNumericRangeAxisLabels(0,getMax(data));

}

else{

line =

Plots.newLine(DataUtil.scaleWithinRange(0,getMax(data)+(getMax(data)/10),data),

\newline Color.newColor("CA3D05"), dataTitle);

yAxis =

AxisLabelsFactory.newNumericRangeAxisLabels(0,getMax(data));

Page 56: Hadoop analyzerJR

56 CONTENTS

}

}

line.setLineStyle(LineStyle.newLineStyle(3, 1, 0));

if(isDashedLine){

line.setLineStyle(LineStyle.MEDIUM_DOTTED_LINE);

}

// Defining chart.

LineChart chart = GCharts.newLineChart(line);

chart.setSize(600, 450);

chart.setTitle(title, Color.newColor("000000"), 14);

chart.setGrid(25, 25, 3, 2);

// Defining axis info and styles

AxisLabels xAxis, xAxis2;

if(scaleIn == MINUTE){

xAxis = AxisLabelsFactory.newNumericRangeAxisLabels(0,

data.length/(60/interval)); //to get minute of computation

xAxis2 = AxisLabelsFactory.newAxisLabels("Minutes", 50.0);

}

else if(scaleIn == SECOND){

xAxis = AxisLabelsFactory.newNumericRangeAxisLabels(0,

data.length/(1.0/interval)); //to get second of computation

xAxis2 = AxisLabelsFactory.newAxisLabels("Seconds", 50.0);

}

else if(scaleIn == HOUR){

xAxis = AxisLabelsFactory.newNumericRangeAxisLabels(0,

data.length/(3600/interval)); //to get hour of computation

xAxis2 = AxisLabelsFactory.newAxisLabels("Hours", 50.0);

}

else{

xAxis = AxisLabelsFactory.newNumericRangeAxisLabels(0,

data.length/(1.0/interval)); //to get second of computation

xAxis2 = AxisLabelsFactory.newAxisLabels("Seconds", 50.0);

log.severe("Scale in parameter: " + scaleIn + " not valid;

possible use: " + MINUTE + " for minute, "

+ SECOND + " for seconds and " + HOUR + " for hour. Used

seconds.");

}

xAxis2.setAxisStyle(AxisStyle.newAxisStyle(Color.newColor("000000"),

14, AxisTextAlignment.CENTER));

AxisLabels yAxis2 = AxisLabelsFactory.newAxisLabels(yLabel,

50.0);

yAxis2.setAxisStyle(AxisStyle.newAxisStyle(Color.newColor("000000"),

14, AxisTextAlignment.CENTER));

// Adding axis info to chart.

chart.addXAxisLabels(xAxis);

chart.addXAxisLabels(xAxis2);

chart.addYAxisLabels(yAxis);

chart.addYAxisLabels(yAxis2);

Page 57: Hadoop analyzerJR

5.1. JAVA CODE 57

// Defining background and chart fills.

chart.setBackgroundFill(Fills.newSolidFill(Color.newColor("e8e8e8")));

chart.setAreaFill(Fills.newSolidFill(Color.newColor("ffffff")));

this.url = chart.toURLString();

log.info("Url for Chart generated...");

}

/**

* This method generate the chart.

* @param data1 first dataset

* @param interval Interval between each x value(in SECOND)

* @param scaleIn could be minute, second or hour and indicates

interval to show on x

* @param isPercentage if it’s true the y value will be scaled in %

* @param data2 second dataset

* @param title title of chart

* @param data1Title name of first line

* @param data2Title name of second line

* @param yLabel label of y axis

* @param isGrayScale to choice greyscale mode

* @param isDashedLine to choice dashed line mode

*/

private void generateChart(double[] data1, int interval, int scaleIn,

\\ boolean isPercentage, double[] data2, String title, String

data1Title, String data2Title, String yLabel, boolean \\

isGrayScale, boolean isDashedLine){

if (data1.length != data2.length){

log.warning("data1 and data2 has not same size! Check for time

consistence!");

}

//plotting data

Line line, line2;

AxisLabels yAxis;

if (isPercentage){

if (isGrayScale){

line = Plots.newLine(DataUtil.scaleWithinRange(0,100,data1),

Color.newColor("000000"), data1Title);

line2 = Plots.newLine(DataUtil.scaleWithinRange(0,100,data2),

Color.newColor("bbbbbb"), data2Title);

yAxis = AxisLabelsFactory.newNumericRangeAxisLabels(0,100);

}

else{

line = Plots.newLine(DataUtil.scaleWithinRange(0,100,data1),

Color.newColor("CA3D05"), data1Title);

line2 = Plots.newLine(DataUtil.scaleWithinRange(0,100,data2),

SKYBLUE, data2Title);

yAxis = AxisLabelsFactory.newNumericRangeAxisLabels(0,100);

}

}

Page 58: Hadoop analyzerJR

58 CONTENTS

else{

if (isGrayScale){

line =

Plots.newLine(DataUtil.scaleWithinRange(0,getMax(data1,data2)+getMax(data1,data2)/10,data1),

Color.newColor("000000"), data1Title);

line2 =

Plots.newLine(DataUtil.scaleWithinRange(0,getMax(data1,data2)+getMax(data1,data2)/10,data2),

Color.newColor("bbbbbb"), data2Title);

yAxis =

AxisLabelsFactory.newNumericRangeAxisLabels(0,getMax(data1,data2));

}

else{

line =

Plots.newLine(DataUtil.scaleWithinRange(0,getMax(data1,data2)+getMax(data1,data2)/10,data1),

Color.newColor("CA3D05"), data1Title);

line2 =

Plots.newLine(DataUtil.scaleWithinRange(0,getMax(data1,data2)+getMax(data1,data2)/10,data2),

SKYBLUE, data2Title);

yAxis =

AxisLabelsFactory.newNumericRangeAxisLabels(0,getMax(data1,data2));

}

}

line.setLineStyle(LineStyle.newLineStyle(3, 1, 0));

line2.setLineStyle(LineStyle.newLineStyle(3, 1, 0));

if(isDashedLine){

line.setLineStyle(LineStyle.MEDIUM_DOTTED_LINE);

line2.setLineStyle(LineStyle.MEDIUM_DOTTED_LINE);

}

// Defining chart.

LineChart chart = GCharts.newLineChart(line,line2);

chart.setSize(600, 450);

chart.setTitle(title, Color.newColor("000000"), 14);

chart.setGrid(25, 25, 3, 2);

// Defining axis info and styles

AxisLabels xAxis, xAxis2;

if (data1.length > data2.length){

if(scaleIn == MINUTE){

xAxis = AxisLabelsFactory.newNumericRangeAxisLabels(0,

data1.length/(60/interval)); //to get minute of

computation

xAxis2 = AxisLabelsFactory.newAxisLabels("Minutes", 50.0);

}

else if(scaleIn == SECOND){

xAxis = AxisLabelsFactory.newNumericRangeAxisLabels(0,

data1.length/(1.0/interval)); //to get second of

computation

xAxis2 = AxisLabelsFactory.newAxisLabels("Seconds", 50.0);

}

else if(scaleIn == HOUR){

Page 59: Hadoop analyzerJR

5.1. JAVA CODE 59

xAxis = AxisLabelsFactory.newNumericRangeAxisLabels(0,

data1.length/(3600/interval)); //to get hour of

computation

xAxis2 = AxisLabelsFactory.newAxisLabels("Hours", 50.0);

}

else

xAxis = AxisLabelsFactory.newNumericRangeAxisLabels(0,

data1.length/(1/interval)); //to get second of

computation

xAxis2 = AxisLabelsFactory.newAxisLabels("Seconds", 50.0);

log.severe("Scale in parameter: " + scaleIn + " not valid;

possible use: " + MINUTE + " for minute, "

+ SECOND + " for seconds and " + HOUR + " for hour.

Used Seconds.");

}

else{

if(scaleIn == MINUTE){

xAxis = AxisLabelsFactory.newNumericRangeAxisLabels(0,

data2.length/(60/interval)); //to get minute of

computation

xAxis2 = AxisLabelsFactory.newAxisLabels("Minutes", 50.0);

}

else if(scaleIn == SECOND){

xAxis = AxisLabelsFactory.newNumericRangeAxisLabels(0,

data2.length/(1.0/interval)); //to get second of

computation

xAxis2 = AxisLabelsFactory.newAxisLabels("Seconds", 50.0);

}

else if(scaleIn == HOUR){

xAxis = AxisLabelsFactory.newNumericRangeAxisLabels(0,

data2.length/(3600/interval)); //to get hour of

computation

xAxis2 = AxisLabelsFactory.newAxisLabels("Hours", 50.0);

}

else{

xAxis = AxisLabelsFactory.newNumericRangeAxisLabels(0,

data2.length/(1.0/interval)); //to get second of

computation

xAxis2 = AxisLabelsFactory.newAxisLabels("Seconds",

50.0);

log.severe("Scale in parameter: " + scaleIn + " not valid;

possible use: " + MINUTE + " for minute, "

+ SECOND + " for seconds and " + HOUR + " for hour.

Used Seconds.");

}

}

xAxis2.setAxisStyle(AxisStyle.newAxisStyle(Color.newColor("000000"),

14, AxisTextAlignment.CENTER));

AxisLabels yAxis2 = AxisLabelsFactory.newAxisLabels(yLabel,

50.0);

Page 60: Hadoop analyzerJR

60 CONTENTS

yAxis2.setAxisStyle(AxisStyle.newAxisStyle(Color.newColor("000000"),

14, AxisTextAlignment.CENTER));

// Adding axis info to chart.

chart.addXAxisLabels(xAxis);

chart.addXAxisLabels(xAxis2);

chart.addYAxisLabels(yAxis);

chart.addYAxisLabels(yAxis2);

// Defining background and chart fills.

chart.setBackgroundFill(Fills.newSolidFill(Color.newColor("e8e8e8")));

chart.setAreaFill(Fills.newSolidFill(Color.newColor("ffffff")));

this.url = chart.toURLString();

log.info("Url for Chart generated...");

}

/**

* Generates all chart(data1 and all data2) in one chart.

* To generate complex charts the library ’charts4j’

* has problem becouse max request that googleApi could

* support is 2048 URL length. Then for multilines chart

* This class uses JFreeChart(http://www.jfree.org/).

* @param data1

* @param interval

* @param scaleIn

* @param isPercentage

* @param data2

* @param title

* @param data1Title

* @param yLabel

* @param isGrayScale

* @param isDashedLine

* @param fileName

*/

private void generateChart(double[] data1, int interval, int scaleIn,

boolean isPercentage, ArrayList<double[]> data2, String title,

String data1Title, String yLabel, boolean isGrayScale, boolean

isDashedLine,String output, String fileName){

JFreeChartGenerator myJFreeChart = new JFreeChartGenerator();

this.url = myJFreeChart.getChart(data1, interval, scaleIn,

isPercentage, data2, title, data1Title, yLabel, isGrayScale,

isDashedLine, output, fileName);

}

/**

* This method return max lenght between data1 and

* all list in data2.

* @param data1

* @param data2

* @return

Page 61: Hadoop analyzerJR

5.1. JAVA CODE 61

*/

private int getMax(double[] data1, ArrayList<double[]> data2) {

int lengthMax = data1.length;

for(double[] data: data2){

if(data.length > lengthMax)

lengthMax = data1.length;

}

return lengthMax;

}

/**

* This method create chart from dstat Csv input.

* @param dstatFilePath

* @param columnDesired

* @param oneForLine if it’s true the columns desired will be plot in

different lines;

* else they will be sum.

* @param title

* @param lineName

* @param isPercentage if it’s true the y value will be scaled in %

* @param yLabel label of y axis

* @param scaleIn could be minute, second or hour and indicates

interval to show on x

* @param isGrayScale to choice greyscale mode

* @param isDashedLine to choice dashed line mode

* @return URL of generated chart

*/

public String getChart(String dstatFilePath, ArrayList<String>

columnDesired, String title, String lineName, boolean

isPercentage, String yLabel, int scaleIn, boolean isGreyScale,

boolean isDashedLine){

Parser p = new Parser();

ArrayList<String> result = new ArrayList<String>();

result = p.getDataFromCsv(dstatFilePath, columnDesired);

double[] dataGenerated = p.generateDoubleArrayFrom(result,

ChartGenerator.SUM);

generateChart(dataGenerated,

p.getRecordsIntervalFromCsv(dstatFilePath), scaleIn,

isPercentage, title, lineName, yLabel, isGreyScale,

isGreyScale);

Chart_sCollector.addChart(new Chart(title, lineName,

dataGenerated, yLabel, getUrl()));

return getUrl();

}

/**

* Create chart for dstatFilePath and add one line for

* each columnDesired.

* @param dstatFilePath

* @param columnDesired

Page 62: Hadoop analyzerJR

62 CONTENTS

* @param oneForLine

* @param title

* @param lineName

* @param lineName2

* @param isPercentage

* @param yLabel

* @param scaleIn

* @param isGreyScale

* @param isDashedLine

* @return

*/

public String getChart(String dstatFilePath, ArrayList<String>

columnDesired, boolean oneForLine, String title, String lineName,

String lineName2, boolean isPercentage, double toDivide, String

yLabel, int scaleIn, boolean isGreyScale, boolean isDashedLine){

Parser p = new Parser();

ArrayList<String> result = new ArrayList<String>();

ArrayList<String> result2 = new ArrayList<String>();

//*****************************//

//to use method already present I define 2 arraylist for each line

//one for first columnDesired and another for the other.

ArrayList<String> columnDesiredFirst = new ArrayList<String>();

columnDesiredFirst.add(columnDesired.get(0));

ArrayList<String> columnDesiredSecond = new ArrayList<String>();

columnDesiredSecond.add(columnDesired.get(1));

//****************************//

result = p.getDataFromCsv(dstatFilePath, columnDesiredFirst);

result2 = p.getDataFromCsv(dstatFilePath, columnDesiredSecond);

double[] usageFirstCol = p.generateDoubleArrayFrom(result,

ChartGenerator.SUM);

usageFirstCol = divideAllFor(usageFirstCol, toDivide);

double[] usageSecondCol = p.generateDoubleArrayFrom(result2,

ChartGenerator.SUM);

usageSecondCol = divideAllFor(usageSecondCol, toDivide);

generateChart(usageFirstCol,

p.getRecordsIntervalFromCsv(dstatFilePath), scaleIn,

isPercentage, usageSecondCol, title, lineName, lineName2,

yLabel, isGreyScale, isDashedLine);

return getUrl();

}

/**

* This method generate chart from 2 csv input file.

* @param dstatFilePath1

* @param dstatFilePath2

* @param columnDesired

* @param title

* @param line1Name

* @param line2Name

* @param isPercentage if it’s true the y value will be scaled in %

Page 63: Hadoop analyzerJR

5.1. JAVA CODE 63

* @param yLabel label of y axis

* @param scaleIn could be minute, second or hour and indicates

interval to show on x

* @param isGrayScale to choice greyscale mode

* @param isDashedLine to choice dashed line mode

* @return URL of generated chart

*/

public String getChart(String dstatFilePath1, String dstatFilePath2,

ArrayList<String> columnDesired, String title, String line1Name,

String line2Name, boolean isPercentage, double toDivide, String

yLabel, int scaleIn, boolean isGreyScale, boolean isDashedLine){

Parser p = new Parser();

ArrayList<String> result = new ArrayList<String>();

ArrayList<String> result2 = new ArrayList<String>();

result = p.getDataFromCsv(dstatFilePath1, columnDesired);

result2 = p.getDataFromCsv(dstatFilePath2, columnDesired);

double[] cpuUsageValueMaster = p.generateDoubleArrayFrom(result,

ChartGenerator.SUM);

cpuUsageValueMaster = divideAllFor(cpuUsageValueMaster, toDivide);

double[] cpuUsageValueSlave = p.generateDoubleArrayFrom(result2,

ChartGenerator.SUM);

cpuUsageValueSlave = divideAllFor(cpuUsageValueSlave, toDivide);

generateChart(cpuUsageValueMaster,

p.getRecordsIntervalFromCsv(dstatFilePath1), scaleIn,

isPercentage, cpuUsageValueSlave, title, line1Name, line2Name,

yLabel, isGreyScale, isDashedLine);

Chart_sCollector.addChart(new Chart(title, dstatFilePath1,

cpuUsageValueMaster, yLabel, getUrl()));

Chart_sCollector.addChart(new Chart(title, dstatFilePath2,

cpuUsageValueSlave, yLabel, getUrl()));

return getUrl();

}

/**

* This method compare first dstatFile with the average of

dstatFileList.

* all lines.

* @param dstatFilePath1

* @param dstatFileList

* @param columnDesired

* @param title

* @param line1Name

* @param line2Name

* @param isPercentage if it’s true the y value will be scaled in %

* @param yLabel label of y axis

* @param scaleIn could be minute, second or hour and indicates

interval to show on x

* @param isGrayScale to choice grey scale mode

* @param isDashedLine to choice dashed line mode

* @return URL of generated chart

Page 64: Hadoop analyzerJR

64 CONTENTS

*/

public String getChart(String dstatFilePath1, ArrayList<String>

dstatFileList, ArrayList<String> columnDesired, String title,

String line1Name, String line2Name, boolean isPercentage, double

toDivide, String yLabel, int scaleIn, boolean isGreyScale,

boolean isDashedLine){

Parser p = new Parser();

ArrayList<String> result = new ArrayList<String>();

ArrayList<String> result2 = new ArrayList<String>();

result = p.getDataFromCsv(dstatFilePath1, columnDesired);

double[] cpuUsageValueMaster = p.generateDoubleArrayFrom(result,

ChartGenerator.SUM);

cpuUsageValueMaster = divideAllFor(cpuUsageValueMaster, toDivide);

ArrayList<double[]> slave_sUsage = new ArrayList<double[]>();

for (String dstatFile: dstatFileList){

result2 = p.getDataFromCsv(dstatFile, columnDesired);

double[] tmpSlave = p.generateDoubleArrayFrom(result2,

ChartGenerator.SUM);

tmpSlave = divideAllFor(tmpSlave, toDivide);

slave_sUsage.add(tmpSlave);

}

double[] slaveDouble_Average = getAverage(p, slave_sUsage);

generateChart(cpuUsageValueMaster,

p.getRecordsIntervalFromCsv(dstatFilePath1), scaleIn,

isPercentage, slaveDouble_Average , title, line1Name,

line2Name, yLabel, isGreyScale, isDashedLine);

return getUrl();

}

/**

* This method will generate all charts in one.

* @param dstatFilePath1

* @param dstatFileList

* @param columnDesired

* @param title

* @param line1Name

* @param line2Name

* @param isPercentage

* @param yLabel

* @param scaleIn

* @param isGreyScale

* @param isDashedLine

* @param outputPath

* @param outputFileName

* @return

*/

public String getChart(String dstatFilePath1, ArrayList<String>

dstatFileList, ArrayList<String> columnDesired, String title,

String line1Name, String line2Name, boolean isPercentage, double

toDivide, String yLabel, int scaleIn, boolean isGreyScale,

Page 65: Hadoop analyzerJR

5.1. JAVA CODE 65

boolean isDashedLine, String outputPath, String fileName){

Parser p = new Parser();

ArrayList<String> result = new ArrayList<String>();

ArrayList<String> result2 = new ArrayList<String>();

result = p.getDataFromCsv(dstatFilePath1, columnDesired);

double[] cpuUsageValueMaster = p.generateDoubleArrayFrom(result,

ChartGenerator.SUM);

cpuUsageValueMaster = divideAllFor(cpuUsageValueMaster, toDivide);

ArrayList<double[]> slave_sUsage = new ArrayList<double[]>();

for (String dstatFile: dstatFileList){

result2 = p.getDataFromCsv(dstatFile, columnDesired);

double[] tmpSlave = p.generateDoubleArrayFrom(result2,

ChartGenerator.SUM);

tmpSlave = divideAllFor(tmpSlave, toDivide);

slave_sUsage.add(tmpSlave);

}

generateChart(cpuUsageValueMaster,

p.getRecordsIntervalFromCsv(dstatFilePath1), scaleIn,

isPercentage, slave_sUsage, title, line1Name, yLabel,

isGreyScale, isDashedLine, outputPath, fileName);

return getUrl();

}

/**

* Divides all element in input array for

* double toDivide value.

* @param doubleList

* @param toDivide

* @return

*/

private double[] divideAllFor(double[] doubleList, double toDivide) {

for(int i=0; i<doubleList.length; i++)

doubleList[i] = doubleList[i]/toDivide;

return doubleList;

}

private double[] getAverage(Parser p, ArrayList<double[]>

slave_sUsage) {

//get size of min slave file(we need first of the max)

int maxRecordSize = 0;

for(double[] record: slave_sUsage){

if (record.length > maxRecordSize) maxRecordSize =

record.length;

}

int minRecordSize = maxRecordSize;

for(double[] record: slave_sUsage){

if (record.length < minRecordSize) minRecordSize =

record.length;

}

ArrayList<String> averageSlave_s = new ArrayList<String>();

Page 66: Hadoop analyzerJR

66 CONTENTS

for (int i=0; i<minRecordSize; i++){

double average_i = 0;

for(int k=0; k<slave_sUsage.size(); k++){

average_i += slave_sUsage.get(k)[i];

}

average_i = average_i/slave_sUsage.size();

averageSlave_s.add(average_i + "");

}

double[] cpuUsageValueSlave =

p.generateDoubleArrayFrom(averageSlave_s);

return cpuUsageValueSlave;

}

/**

* Return max value of input array.

* @param data array of double.

* @return

*/

private double getMax(double[] data){

if (data.length == 0)

return 0;

double max = data[0];

for(int i=0; i<data.length; i++){

if(data[i]>max)

max = data[i];

}

if(max == 0)

return IF_ZERO;

return max;

}

/**

* Return max value of inputs array.

* @param data1 array of double.

* @param data2 array of double.

* @return

*/

private double getMax(double[] data1, double[] data2) {

double max1 = getMax(data1);

double max2 = getMax(data2);

if(max1 > max2){

if(max1 == 0)

return IF_ZERO;

return max1;

}

if(max2 == 0)

return IF_ZERO;

return max2;

}

}

Page 67: Hadoop analyzerJR

5.1. JAVA CODE 67

5.1.3 JFreeChartGenerator

La classe ’JFreeChartGenerator.java’ consente di generare grafici personalizz-abili a seconda delle esigenze dell’utente. Tale classe e stata utilizzata per lamodalita di grafici ’AllIn’ ovvero contenenti tutti gli slave ed il master nellostesso grafico.

package chartsGenerators;

import java.awt.BasicStroke;

import java.awt.Color;

import java.io.File;

import java.io.IOException;

import java.util.ArrayList;

import java.util.logging.Logger;

import org.jfree.chart.ChartFactory;

import org.jfree.chart.ChartUtilities;

import org.jfree.chart.JFreeChart;

import org.jfree.chart.axis.NumberAxis;

import org.jfree.chart.plot.PlotOrientation;

import org.jfree.chart.plot.XYPlot;

import org.jfree.chart.renderer.category.LineAndShapeRenderer;

import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;

import org.jfree.data.Range;

import org.jfree.data.xy.XYDataset;

import org.jfree.data.xy.XYSeries;

import org.jfree.data.xy.XYSeriesCollection;

import com.orsoncharts.util.Scale2D;

/**

*

* @author Romano Simone - www.sromano.altervista.org

* To generate complex charts the library ’charts4j’

* has problem becouse max request that googleApi could

* support is 2048 URL length. Then for multilines chart

* This class uses JFreeChart(http://www.jfree.org/).

*/

public class JFreeChartGenerator{

private static String OUTPUT_FOLDER_NAME = "png_charts";

private static Logger log = Logger.getLogger("global");

public static int MINUTE = 5, SECOND = 6, HOUR = 7;

/**

* Creates a chart dataset.

* @return chart dataset.

Page 68: Hadoop analyzerJR

68 CONTENTS

*/

private XYDataset createDataset(double[] data1, ArrayList<double[]>

data2, int interval, int scaleIn, String data1Title) {

XYSeriesCollection dataset = new XYSeriesCollection();

XYSeries firstChart = new XYSeries(data1Title);

double distanceBetweenPoints = 0.0;

if (scaleIn == MINUTE)

distanceBetweenPoints = 100.0/60.0/(double)interval;

if (scaleIn == SECOND)

distanceBetweenPoints = 100.0/1.0/(double)interval;

if (scaleIn == HOUR)

distanceBetweenPoints = 100.0/3600.0/(double)interval;

//creating dataset for first chart

double actualPoint = 0.0;

for (double y:data1){

firstChart.add(actualPoint, y);

actualPoint += distanceBetweenPoints;

}

dataset.addSeries(firstChart);

//creating dataste for others dataset

actualPoint = 0.0;

int i=1;

for(double[] data:data2){

XYSeries tmp = new XYSeries("Slave_" + i);

i++;

for(double y:data){

tmp.add(actualPoint, y);

actualPoint += distanceBetweenPoints;

}

dataset.addSeries(tmp);

actualPoint = 0.0;

}

return dataset;

}

/**

* Create JFreeChart from input dataset

* @param dataset

* @return

*/

private JFreeChart createChart(XYDataset dataset, String title, int

scaleIn, String yLabel, boolean isPercentage, boolean

isDashedLine) {

// create the chart...

String xAxis = checkXAxis(scaleIn);

final JFreeChart chart = ChartFactory.createXYLineChart(

title, // chart title

Page 69: Hadoop analyzerJR

5.1. JAVA CODE 69

xAxis, // x axis label

yLabel, // y axis label

dataset, // data

PlotOrientation.VERTICAL,

true, // include legend

true, // tooltips

false // urls

);

// NOW DO SOME OPTIONAL CUSTOMISATION OF THE CHART...

chart.setBackgroundPaint(Color.white);

XYPlot plot = chart.getXYPlot();

plot.setBackgroundPaint(Color.lightGray);

plot.setDomainGridlinePaint(Color.white);

plot.setRangeGridlinePaint(Color.white);

if (isDashedLine){

XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer)

plot.getRenderer();

for (int i=0; i<dataset.getSeriesCount(); i++)

renderer.setSeriesStroke(

i, new BasicStroke(

1.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,

1.0f, new float[] {5.0f, 3.0f}, 0.0f

)

);

}

NumberAxis range = (NumberAxis) plot.getRangeAxis();

range.setLowerBound(0);

if (isPercentage)

plot.getRangeAxis().setRange(new Range(0, 100), false, true);

return chart;

}

private String checkXAxis(int scaleIn) {

String xAxis = "";

if (scaleIn == MINUTE)

xAxis = "Minutes";

if (scaleIn == SECOND)

xAxis = "Seconds";

if (scaleIn == HOUR)

xAxis = "Hours";

return xAxis;

}

private String createImg(JFreeChart chart, String outputPath, String

fileName) {

//createOutputDir

File dir = new File(outputPath + File.separator +

JFreeChartGenerator.OUTPUT_FOLDER_NAME);

Page 70: Hadoop analyzerJR

70 CONTENTS

dir.mkdir();

String outputFilePath =outputPath + File.separator +

OUTPUT_FOLDER_NAME + File.separator + fileName + ".png";

File fileImg = new File(outputFilePath);

try {

ChartUtilities.saveChartAsPNG(fileImg, chart, 600, 400);

} catch (IOException e) {

log.severe("Error creating JFreeChart img: " + e.getMessage());

e.printStackTrace();

}

log.info("JFreeChart img created...");

return outputFilePath;

}

/**

* This method make chart and returns its path.

* @return

*/

public String getChart(double[] data1, int interval, int scaleIn,

boolean isPercentage, ArrayList<double[]> data2, String title,

String data1Title, String yLabel, boolean isGrayScale, boolean

isDashedLine, String outputPath, String fileName){

XYDataset dataset = createDataset(data1, data2, interval, scaleIn,

data1Title);

JFreeChart chart = createChart(dataset, title, scaleIn, yLabel,

isPercentage, isDashedLine);

String outputFile = createImg(chart, outputPath, fileName);

return outputFile;

}

}

5.2 R code

Di seguito sono elencati gli script R.

5.2.1 chart generator.R

Questo script consente di generare file pdf con grafici che mostrano l’andamentodelle macchine del cluster.

# require(scales)

# require(ggplot2)

# require(plyr)

# library(reshape2)

# library(xlsx)

loadLibrary <- function(lib){

Page 71: Hadoop analyzerJR

5.2. R CODE 71

if(require(package = lib, character.only = TRUE, lib.loc=".")){

print(paste(lib,"is loaded correctly", sep= " "))

} else {

print(paste("trying to install ", lib, sep = " "))

install.packages(lib, lib=".", dependencies = TRUE)

if(require(package = lib, character.only = TRUE, lib.loc=".")){

print(paste(lib,"installed and loaded", sep = " "))

} else {

stop(paste("could not install", lib, sep = " "))

}

}

}

r <- getOption("repos") # hard code the US repo for CRAN

r["CRAN"] <- "http://cran.us.r-project.org"

options(repos = r)

#Sys.setenv(JAVA_HOME=’C:\\Program Files\\Java\\jre1.8.0_25’)

#loadLibrary("rJava")

loadLibrary("colorspace")

loadLibrary("scales")

loadLibrary("ggplot2")

loadLibrary("plyr")

loadLibrary("reshape2")

# install.packages("colorspace", lib=".", dependencies = TRUE)

# install.packages("ggplot2", lib=".", dependencies = TRUE)

#library(ggplot2, lib.loc=".")

cbind.fill <- function(...) {

transpoted <- lapply(list(...),t)

transpoted_dataframe <- lapply(transpoted, as.data.frame)

return (data.frame(t(rbind.fill(transpoted_dataframe))))

}

mettiVirgolaCsv <-function(path){

for(file in list.files(path = path, pattern = "*.csv$")){

file = paste(path, file, sep="")

prova = readLines(file)

if(length(grep(pattern = "\"#send\"," , x = prova[7])) == 0){

#print("diverso")

prova[7] = paste(prova[7], ",", sep="")

write(x = prova, file = file)

}

}

}

plotSingleNodeOther <- function(tipologiaTempo,dstat, value,.e, len,

xlabel ,ylabel, colorLine, title, geom_color, printTitle = TRUE,

colorType = color, ylimits = NULL, lineDash = FALSE,fontSize =

NULL, fontFamily = NULL){

Page 72: Hadoop analyzerJR

72 CONTENTS

print(title)

p = ggplot(dstat, aes(dstat), environment = environment())

for(val in value){

p = p + geom_line(aes(x = len, y = eval(parse(text=val)), colour =

geom_color[1]))

}

if(length(value) == 1){

if(lineDash == TRUE) {

p = p + geom_line(aes(x = len, y = eval(parse(text=value[1])),

colour = geom_color[1]), linetype = "dotted")

}

else

p = p + geom_line(aes(x = len, y = eval(parse(text=value[1])),

colour = geom_color[1]))

}

else{

if(lineDash == TRUE){

p = p + geom_line(aes(x = len, y = eval(parse(text=value[1])),

colour = geom_color[1]))

p = p + geom_line(aes(x = len, y = eval(parse(text=value[2])),

colour = geom_color[2]), linetype = "dotted")

}

else{

p = p + geom_line(aes(x = len, y = eval(parse(text=value[1])),

colour = geom_color[1]))

p = p + geom_line(aes(x = len, y = eval(parse(text=value[2])),

colour = geom_color[2]))

}

}

p = p + xlab(xlabel)

p = p + ylab(ylabel)

p = p + labs(color="Legend")

p = p + scale_x_continuous(expand = c(0, 0))

if(!is.null(ylimits)){

p = p + scale_y_continuous(limits=ylimits ,expand = c(0, 0))

}

else{

p = p + scale_y_continuous(expand = c(0, 0))

}

if(length(value) == 1){

if(colorType == 0){

p = p + scale_color_manual(values="black")

}

else if(colorType == 1){

p = p + scale_color_manual(values="red")

}

}

else{

if(colorType == 0){

Page 73: Hadoop analyzerJR

5.2. R CODE 73

p = p + scale_color_manual(values=c("black", "grey"))

}

else if(colorType == 1){

}

}

p = p + theme(legend.position = "top",

panel.grid.major.y = element_line(colour = "black"),

panel.background = element_rect(fill = ’white’, colour

= ’black’),

panel.grid.major.x = element_blank(),

panel.grid.minor.x = element_blank(),

axis.text = element_text(colour = "black" ,

size = fontSize))

if(printTitle){

p = p + ggtitle(title)

}

print(p)

}

takeDelay <- function(fileInput){

file = readLines(con = fileInput)

a = sub(".*csv ", "", file[4])

a = sub("\".*","", a)

a = as.numeric(a)

return <- a

}

average <- function(campo, ylabel, tipologiaTempo = "s", colorType,

printTitle = TRUE, fontSize = fontSize, ylimits = NULL){

.e <- environment()

for(file in list.files(inputFile, pattern = "*.csv$")){

title = file

file = paste(inputFile, file, sep = "")

if(length(grep(pattern = "master" , x = file)) == 1){

dstat <- read.csv(file, skip=6)

dstat <- subset(dstat, select = -X)

dstat <- dstat[-1,]

if(length(campo) != 1){

campoEval = 0

for(val in campo){

campoEval = campoEval + eval(parse(text=val))

}

master = data.frame(campoEval)

}

else{

master <- eval(parse(text=campo))

Page 74: Hadoop analyzerJR

74 CONTENTS

}

}

else{

dstat <- read.csv(file, skip=6)

dstat <- subset(dstat, select = -X)

dstat <- dstat[-1,]

if(length(campo) != 1){

campoEval = 0

for(val in campo){

campoEval = campoEval + eval(parse(text=val))

}

if(exists("cpu")){

cpu <- cbind.fill(cpu, campoEval)

}

else{

cpu <- campoEval

}

}

else{

campoEval = eval(parse(text=campo))

if(exists("cpu")){

cpu <- cbind.fill(cpu, campoEval)

}

else{

cpu <- campoEval

}

}

}

}

cpu = cbind(cpu, NA)

cpu[,dim(cpu)[2]] = rowMeans(x = cpu, na.rm = TRUE)

cpu <- cbind.fill(cpu, master)

delayDSTAT = takeDelay(file)

if(tipologiaTempo == "s"){

len <- seq(0,dim(cpu)[1]-1) * delayDSTAT

xlabel = "Time (s)"

}

else if(tipologiaTempo == "m"){

len <- (seq(0,dim(cpu)[1]-1) * delayDSTAT) / 60

xlabel = "Time (m)"

}

else if(tipologiaTempo == "h"){

len <- ((seq(0,dim(cpu)[1]-1) * delayDSTAT) / 60) / 60

xlabel = "Time (h)"

}

plotSingleNodeOther(tipologiaTempo,cpu, c("dstat[, dim(dstat)[2]-1]",

Page 75: Hadoop analyzerJR

5.2. R CODE 75

"dstat[, dim(dstat)[2]]"), .e , len, xlabel ,ylabel, colorLine,

title = "Average", c("slave", "master"), printTitle, colorType,

ylimits = ylimits,fontSize = fontSize)

}

AllNodes <- function(campo, ylabel, tipologiaTempo = "s", colorType,

ylimits = NULL ,printTitle = TRUE, fontSize){

.e <- environment()

for(file in list.files(inputFile, pattern = "*.csv$")){

title = file

file = paste(inputFile, file, sep = "")

delayDSTAT = takeDelay(file)

dstat <- read.csv(file, skip=6)

dstat <- subset(dstat, select = -X)

dstat <- dstat[-1,]

if(length(grep(pattern = "master" , x = file)) == 1){

if(length(campo) != 1){

campoEval = 0

for(val in campo){

campoEval = campoEval + eval(parse(text=val))

}

master = data.frame(campoEval)

}

else{

master <- eval(parse(text=campo))

}

}

else{

if(length(campo) != 1){

campoEval = 0

for(val in campo){

campoEval = campoEval + eval(parse(text=val))

}

if(exists("cpu")){

cpu <- cbind.fill(cpu, campoEval)

}

else{

cpu <- campoEval

}

}

else{

campoEval = eval(parse(text=campo))

if(exists("cpu")){

cpu <- cbind.fill(cpu, campoEval)

}

else{

cpu <- campoEval

}

}

Page 76: Hadoop analyzerJR

76 CONTENTS

}

}

cpu <- cbind.fill(cpu, master)

names(cpu) <- tolower(names(cpu))

#cambiamo i nomi alle colonne con SlaveN e Master

for(numeroColonna in 1:ncol(cpu)-1) {

variabile <- paste ("Slave", numeroColonna, sep = "", collapse =

NULL)

colnames(cpu)[numeroColonna] <- variabile

}

colnames(cpu)[dim(cpu)[2]] <- "Master"

cpu = cbind(cpu, seq(1, dim(cpu)[1]))

colnames(cpu)[dim(cpu)[2]] <- paste("times")

aql <- melt(cpu, id.vars = "times")

nrow = round(dim(cpu)[2] / 12)

if(nrow == 0){

nrow = 1

}

if(tipologiaTempo == "s"){

aql$times <- aql$times * delayDSTAT

xlabel = "Time (s)"

}

else if(tipologiaTempo == "m"){

aql$times <- (aql$times * delayDSTAT) / 60

xlabel = "Time (m)"

}

else if(tipologiaTempo == "h"){

aql$times <- ((aql$times * delayDSTAT) / 60) / 60

xlabel = "Time (h)"

}

p = ggplot(aql, aes(times,value, col=variable))

p = p + geom_line()

p = p + xlab(xlabel)

p = p + ylab(ylabel)

p = p + labs(color="Legend")

p = p + scale_x_continuous(expand = c(0, 0))

p = p + guides(col = guide_legend(nrow = nrow))

p = p + theme(legend.position = "top",

panel.grid.major.y = element_line(colour = "black"),

panel.background = element_rect(fill = ’white’, colour =

’black’),

panel.grid.major.x = element_blank(),

panel.grid.minor.x = element_blank(),

axis.text = element_text(colour = "black" ,

size = fontSize))

if(!is.null(ylimits)){

p = p + scale_y_continuous(limits=ylimits ,expand = c(0, 0))

}

Page 77: Hadoop analyzerJR

5.2. R CODE 77

else{

p = p + scale_y_continuous(expand = c(0, 0))

}

title = "All Nodes"

if(printTitle){

p = p + ggtitle(title)

}

print(p)

}

singleNode <- function(tipologiaTempo, value, value2 = NULL,ylabel,

geom_color ,printTitle, colorType, lineDash, ylimits, fontSize){

for(file in list.files(inputFile, pattern = "*.csv$")){

title = file

file = paste(inputFile, file, sep = "")

delayDSTAT = takeDelay(file)

dstat <- read.csv(file, skip=6)

dstat <- subset(dstat, select = -X)

dstat <- dstat[-1,]

.e <- environment()

if(tipologiaTempo == "s"){

len <- (seq(0,length(dstat$used)-1) * delayDSTAT)

xlabel = "Time (s)"

}

else if(tipologiaTempo == "m"){

len <- (seq(0,length(dstat$used)-1) * delayDSTAT) / 60

xlabel = "Time (m)"

}

else if(tipologiaTempo == "h"){

len <- ((seq(0,length(dstat$used)-1) * delayDSTAT) / 60) / 60

xlabel = "Time (h)"

}

if(is.null(value2)){

if(length(value) != 1){

campoEval = 0

for(val in value){

campoEval = campoEval + eval(parse(text=val))

}

campoEval = data.frame(campoEval)

#YLIMITS MANCANTE

plotSingleNodeOther(tipologiaTempo = tipologiaTempo, dstat =

campoEval, value = "dstat$campoEval", .e = .e, len =

len,xlabel = xlabel ,ylabel = ylabel,colorLine =

colorLine,title = title ,geom_color = geom_color, printTitle

= printTitle, colorType = colorType, ylimits = ylimits,

lineDash = lineDash ,fontSize = fontSize)

}

Page 78: Hadoop analyzerJR

78 CONTENTS

else{

#YLIMITS MANCANTE

plotSingleNodeOther(tipologiaTempo,dstat, value,.e, len, xlabel

,ylabel, colorLine, title, geom_color, printTitle,

colorType, ylimits = ylimits, lineDash = lineDash, fontSize

= fontSize)

}

}

else{

#YLIMITS MANCANTE

plotSingleNodeOther(tipologiaTempo = tipologiaTempo, dstat,value =

c(value,value2), .e = .e, len = len,xlabel = xlabel ,ylabel =

ylabel,colorLine = colorLine,title = title ,geom_color =

geom_color, printTitle = printTitle, colorType = colorType,

ylimits = ylimits,lineDash = lineDash ,fontSize = fontSize)

}

}

}

result <- tryCatch({

input = readLines(’./R_script/input.hla’)

tempo = input[1] #sostituito

color = as.numeric(input[2]) #sostituito

dash = as.logical(input[3]) #sostituito

titoli = as.logical(input[4]) #sostituito

oneFilePdf = as.logical(input[5])

graphType = as.numeric(input[6]) #fatta divisione tra SINGOLI, MEDIE,

TUTTI

CPUType = input[7] #splittato in stringhe

RAMType = input[8] #splittato in stringhe

Upperbound_RAM = input[9] #fatto

IOType = as.numeric(input[10]) #la divisione e’ solo nei singoli, FATTA

PagingType = as.numeric(input[11]) #la divisione e’ solo nei singoli,

FATTA

NetType = as.numeric(input[12]) #la divisione e’ solo nei singoli, FATTA

NPacketType = as.numeric(input[13]) #la divisione e’ solo nei singoli,

FATTA

font = as.numeric(input[14]) #sostituito

inputFile <<- input[15]

output = input[16]

if(CPUType[1] == "NULL"){

CPUType = NULL

}else {

CPUType = strsplit(CPUType, split = " ")

CPUType = CPUType[[1]]

}

if(RAMType[1] == "NULL"){

RAMType = NULL

Page 79: Hadoop analyzerJR

5.2. R CODE 79

}else{

RAMType = strsplit(RAMType, split = " ")

RAMType = RAMType[[1]]

}

if(Upperbound_RAM == "NULL"){

Upperbound_RAM = NULL

} else{

Upperbound_RAM = as.numeric(Upperbound_RAM)

Upperbound_RAM = c(0, Upperbound_RAM)

}

ylimits = Upperbound_RAM

#tipologiaTempo valori = "s" "m" "h"

#combCPU "" o c("dstat$usr", dstat$sys) combinazione dei campi cpu

#combRAM "" o c("dstat$used", dstat$free) combinazione dei campi RAM

#tipologiaColori 0 = grigi, 1 = colorati, 2 = linee diverse

#printTitle TRUE, FALSE

mettiVirgolaCsv(inputFile)

if(graphType == 1){

singleOutput = paste(output, "SinglePlot.pdf", sep = "")

multiOutput = paste(output, "SinglePlot%04d.pdf", sep = "")

pdf(file = ifelse(oneFilePdf, singleOutput, multiOutput), width = 10,

onefile = oneFilePdf)

#CPU

if(is.null(CPUType)){

singleNode(tipologiaTempo = tempo, value = "dstat$usr", ylabel = "CPUs

Usr(%)", geom_color= "cpu", printTitle = titoli, colorType =

color, ylimits = NULL, lineDash = dash, fontSize = font)

singleNode(tipologiaTempo = tempo, value = "dstat$sys", ylabel = "CPUs

Sys(%)", geom_color= "cpu", printTitle = titoli, colorType =

color, ylimits = NULL, lineDash = dash, fontSize = font)

singleNode(tipologiaTempo = tempo, value = "dstat$idl", ylabel = "CPUs

Idl(%)", geom_color= "cpu", printTitle = titoli, colorType =

color, ylimits = NULL, lineDash = dash, fontSize = font)

singleNode(tipologiaTempo = tempo, value = "dstat$wai", ylabel = "CPUs

Wai(%)", geom_color= "cpu", printTitle = titoli, colorType =

color, ylimits = NULL, lineDash = dash, fontSize = font)

singleNode(tipologiaTempo = tempo, value = "dstat$hiq", ylabel = "CPUs

Hiq(%)", geom_color= "cpu", printTitle = titoli, colorType =

color, ylimits = NULL, lineDash = dash, fontSize = font)

singleNode(tipologiaTempo = tempo, value = "dstat$siq", ylabel = "CPUs

Siq(%)", geom_color= "cpu", printTitle = titoli, colorType =

color, ylimits = NULL, lineDash = dash, fontSize = font)

}

else{

singleNode(tipologiaTempo = tempo, value = CPUType, ylabel = "CPUs

(%)", geom_color= "cpu", printTitle = titoli, colorType = color,

ylimits = NULL, lineDash = dash, fontSize = font)

}

#MEMORIA

Page 80: Hadoop analyzerJR

80 CONTENTS

if(is.null(RAMType)){

singleNode(tipologiaTempo = tempo, value = "dstat$used/1048576",

ylabel = "Memory Used (MB)", geom_color= "memory", printTitle =

titoli, colorType = color, ylimits = ylimits, lineDash = dash,

fontSize = font)

singleNode(tipologiaTempo = tempo, value = "dstat$buff/1048576",

ylabel = "Memory Buff (MB)", geom_color= "memory", printTitle =

titoli, colorType = color, ylimits = ylimits, lineDash = dash,

fontSize = font)

singleNode(tipologiaTempo = tempo, value = "dstat$cach/1048576",

ylabel = "Memory Cach (MB)", geom_color= "memory", printTitle =

titoli, colorType = color, ylimits = ylimits, lineDash = dash,

fontSize = font)

singleNode(tipologiaTempo = tempo, value = "dstat$free/1048576",

ylabel = "Memory Free (MB)", geom_color= "memory", printTitle =

titoli, colorType = color, ylimits = ylimits, lineDash = dash,

fontSize = font)

} else{

singleNode(tipologiaTempo = tempo, value = RAMType, ylabel = "Memory

(MB)", geom_color= "memory", printTitle = titoli, colorType =

color, ylimits = ylimits, lineDash = dash, fontSize = font)

}

#PAGING

if(PagingType == 1){

singleNode(tipologiaTempo = tempo, value = "dstat$in.", ylabel =

"Paging in", geom_color= "in", printTitle = titoli, colorType =

color, ylimits = NULL, lineDash = dash, fontSize = font)

singleNode(tipologiaTempo = tempo, value = "dstat$out", ylabel =

"Paging out", geom_color= "out", printTitle = titoli, colorType

= color, ylimits = NULL, lineDash = dash, fontSize = font)

} else if(PagingType == 2){

singleNode(tipologiaTempo = tempo, value = "dstat$in.", value2 =

"dstat$out", ylabel = "Paging", geom_color= c("in", "out"),

printTitle = titoli, colorType = color, ylimits = NULL, lineDash

= dash, fontSize = font)

}

#SWAP

singleNode(tipologiaTempo = tempo, value = "dstat$used.1/1048576",

ylabel = "Swap (MB)", geom_color= "swap", printTitle = titoli,

colorType = color, ylimits = NULL, lineDash = dash, fontSize =

font)

#DISCO

if(IOType == 1){

singleNode(tipologiaTempo = tempo, value = "dstat$read/1048576",

ylabel = "Disk Usage Read (MB/s)", geom_color= "read",

printTitle = titoli, colorType = color, ylimits = NULL, lineDash

= dash, fontSize = font)

singleNode(tipologiaTempo = tempo, value = "dstat$writ/1048576",

ylabel = "Disk Usage Write (MB/s)", geom_color= "write",

Page 81: Hadoop analyzerJR

5.2. R CODE 81

printTitle = titoli, colorType = color, ylimits = NULL, lineDash

= dash, fontSize = font)

} else if(IOType == 2){

singleNode(tipologiaTempo = tempo, value = "dstat$writ/1048576",

value2 = "dstat$read/1048576", ylabel = "Disk Usage (MB/s)",

geom_color= c("read", "write"), printTitle = titoli, colorType =

color, ylimits = NULL, lineDash = dash, fontSize = font)

}

#RETE - MB

if(NetType == 1){

singleNode(tipologiaTempo = tempo, value = "dstat$recv/1048576",

ylabel = "Net Usage Receive (MB/s)", geom_color= "received",

printTitle = titoli, colorType = color, ylimits = NULL, lineDash

= dash, fontSize = font)

singleNode(tipologiaTempo = tempo, value = "dstat$send/1048576",

ylabel = "Net Usage Send (MB/s)", geom_color= "sent", printTitle

= titoli, colorType = color, ylimits = NULL, lineDash = dash,

fontSize = font)

} else if(NetType == 2){

singleNode(tipologiaTempo = tempo, value = "dstat$recv", value2 =

"dstat$send",ylabel = "Network Usage (MB)", geom_color=

c("recv", "sent"), printTitle = titoli, colorType = color,

ylimits = NULL, lineDash = dash, fontSize = font)

}

#RETE - PACCHETTI

if(NPacketType == 1){

singleNode(tipologiaTempo = tempo, value = "dstat$X.recv", ylabel =

"Net Packets Receive (#)", geom_color= "Pks. received",

printTitle = titoli, colorType = color, ylimits = NULL, lineDash

= dash, fontSize = font)

singleNode(tipologiaTempo = tempo, value = "dstat$X.send", ylabel =

"Net Packets Send (#)", geom_color= "Pks. sent", printTitle =

titoli, colorType = color, ylimits = NULL, lineDash = dash,

fontSize = font)

} else if(NPacketType == 2){

singleNode(tipologiaTempo = tempo, value = "dstat$X.send", value2 =

"dstat$X.recv", ylabel = "Net Packets (#)", geom_color= c("Pks.

received", "Pks. sent"), printTitle = titoli, colorType = color,

ylimits = NULL, lineDash = dash, fontSize = font)

}

#INTERRUPT

#singleNode(tipologiaTempo = tempo, value = "dstat$int", ylabel =

"Interrupts (#)", geom_color= "Interrupts", printTitle = titoli,

colorType = color, lineDash = dash, fontSize = font)

#CONTEXT SWITCHES

#singleNode(tipologiaTempo = tempo, value = "dstat$csw", ylabel =

"Context Switches (#)", geom_color= "Context Switches",

printTitle = titoli, colorType = color, lineDash = dash, fontSize

Page 82: Hadoop analyzerJR

82 CONTENTS

= font)

dev.off()

} else if(graphType == 2){

singleOutput = paste(output, "AveragePlot.pdf", sep = "")

multiOutput = paste(output, "AveragePlot%04d.pdf", sep = "")

pdf(file = ifelse(oneFilePdf, singleOutput, multiOutput), width = 10,

onefile = oneFilePdf)

if(is.null(CPUType)){

average("dstat$usr", ylabel = "CPUs Usr (%)", tipologiaTempo =

tempo, colorType = color, printTitle = titoli, fontSize = font,

ylimits = NULL)

average("dstat$sys", ylabel = "CPUs Sys (%)", tipologiaTempo =

tempo, colorType = color, printTitle = titoli, fontSize = font,

ylimits = NULL)

average("dstat$idl", ylabel = "CPUs Idl (%)", tipologiaTempo =

tempo, colorType = color, printTitle = titoli, fontSize = font,

ylimits = NULL)

average("dstat$wai", ylabel = "CPUs Wai (%)", tipologiaTempo =

tempo, colorType = color, printTitle = titoli, fontSize = font,

ylimits = NULL)

average("dstat$hiq", ylabel = "CPUs Hiq (%)", tipologiaTempo =

tempo, colorType = color, printTitle = titoli, fontSize = font,

ylimits = NULL)

average("dstat$siq", ylabel = "CPUs Siq (%)", tipologiaTempo =

tempo, colorType = color, printTitle = titoli, fontSize = font,

ylimits = NULL)

} else{

average(campo = CPUType, ylabel = "CPUs (%)", tipologiaTempo =

tempo, colorType = color, printTitle = titoli, fontSize = font)

}

if(is.null(RAMType)){

average("dstat$used/1048576", ylabel = "Memory Used (MB/s)",

tipologiaTempo = tempo, colorType = color, printTitle = titoli,

fontSize = font, ylimits = ylimits)

average("dstat$buff/1048576", ylabel = "Memory Buffer (MB/s)",

tipologiaTempo = tempo, colorType = color, printTitle = titoli,

fontSize = font, ylimits = ylimits)

average("dstat$cach/1048576", ylabel = "Memory Cache (MB/s)",

tipologiaTempo = tempo, colorType = color, printTitle = titoli,

fontSize = font, ylimits = ylimits)

average("dstat$free/1048576", ylabel = "Memory Free (MB/s)",

tipologiaTempo = tempo, colorType = color, printTitle = titoli,

fontSize = font, ylimits = ylimits)

} else{

average(campo = RAMType, ylabel = "Memory (MB/s)", tipologiaTempo =

tempo, colorType = color, printTitle = titoli, fontSize = font,

Page 83: Hadoop analyzerJR

5.2. R CODE 83

ylimits = ylimits)

}

average("dstat$in./1048576", ylabel = "Paging In", tipologiaTempo =

tempo, colorType = color, printTitle = titoli, fontSize = font,

ylimits = NULL)

average("dstat$out/1048576", ylabel = "Paging Out", tipologiaTempo =

tempo, colorType = color, printTitle = titoli, fontSize = font,

ylimits = NULL)

average("dstat$used.1/1048576", ylabel = "Swap (MB)", tipologiaTempo =

tempo, colorType = color, printTitle = titoli, fontSize = font,

ylimits = NULL)

average("dstat$read/1048576", ylabel = "Disk usage Read (MB/s)",

tipologiaTempo = tempo, colorType = color, printTitle = titoli,

fontSize = font, ylimits = NULL)

average("dstat$writ/1048576", ylabel = "Disk usage Write (MB/s)",

tipologiaTempo = tempo, colorType = color, printTitle = titoli,

fontSize = font, ylimits = NULL)

average("dstat$recv/1048576", ylabel = "Net Usage Received (MB/s)",

tipologiaTempo = tempo, colorType = color, printTitle = titoli,

fontSize = font, ylimits = NULL)

average("dstat$send/1048576", ylabel = "Net Usage Sent (MB/s)",

tipologiaTempo = tempo, colorType = color, printTitle = titoli,

fontSize = font, ylimits = NULL)

average("dstat$X.recv", ylabel = "Packets Received (#)",

tipologiaTempo = tempo, colorType = color, printTitle = titoli,

fontSize = font, ylimits = NULL)

average("dstat$X.send", ylabel = "Packets Sent (#)", tipologiaTempo =

tempo, colorType = color, printTitle = titoli, fontSize = font,

ylimits = NULL)

dev.off()

average("dstat$int", ylabel = "Interrupts (#)", tipologiaTempo =

tempo, colorType = color, printTitle = titoli, fontSize = font)

average("dstat$csw", ylabel = "Context Switches (#)", tipologiaTempo =

tempo, colorType = color, printTitle = titoli, fontSize = font)

} else if(graphType == 3){

singleOutput = paste(output, "AllNodesPlot.pdf", sep = "")

multiOutput = paste(output, "AllNodesPlot%04d.pdf", sep = "")

pdf(file = ifelse(oneFilePdf, singleOutput, multiOutput), width = 10,

onefile = oneFilePdf)

if(is.null(CPUType)){

AllNodes("dstat$usr", ylabel = "CPUs Usr (%)", tipologiaTempo =

tempo, colorType = color, ylimits = NULL, printTitle = titoli,

fontSize = font)

AllNodes("dstat$sys", ylabel = "CPUs Sys (%)", tipologiaTempo =

Page 84: Hadoop analyzerJR

84 CONTENTS

tempo, colorType = color, ylimits = NULL, printTitle = titoli,

fontSize = font)

AllNodes("dstat$idl", ylabel = "CPUs Idl (%)", tipologiaTempo =

tempo, colorType = color, ylimits = NULL, printTitle = titoli,

fontSize = font)

AllNodes("dstat$wai", ylabel = "CPUs Wai (%)", tipologiaTempo =

tempo, colorType = color, ylimits = NULL, printTitle = titoli,

fontSize = font)

AllNodes("dstat$hiq", ylabel = "CPUs Hiq (%)", tipologiaTempo =

tempo, colorType = color, ylimits = NULL, printTitle = titoli,

fontSize = font)

AllNodes("dstat$siq", ylabel = "CPUs Siq (%)", tipologiaTempo =

tempo, colorType = color, ylimits = NULL, printTitle = titoli,

fontSize = font)

}else{

AllNodes(CPUType, ylabel = "CPUs (%)", tipologiaTempo = tempo,

colorType = color, ylimits = NULL, printTitle = titoli, fontSize

= font)

}

if(is.null(RAMType)){

AllNodes("dstat$used/1048576", ylabel = "Memory Used (MB/s)",

tipologiaTempo = tempo, colorType = color, printTitle = titoli,

fontSize = font, ylimits = ylimits)

AllNodes("dstat$buff/1048576", ylabel = "Memory Buffer (MB/s)",

tipologiaTempo = tempo, colorType = color, printTitle = titoli,

fontSize = font, ylimits = ylimits)

AllNodes("dstat$cach/1048576", ylabel = "Memory Cache (MB/s)",

tipologiaTempo = tempo, colorType = color, printTitle = titoli,

fontSize = font, ylimits = ylimits)

AllNodes("dstat$free/1048576", ylabel = "Memory Free (MB/s)",

tipologiaTempo = tempo, colorType = color, printTitle = titoli,

fontSize = font, ylimits = ylimits)

} else{

AllNodes(RAMType, ylabel = "Memory (MB/s)", tipologiaTempo = tempo,

colorType = color, printTitle = titoli, fontSize = font, ylimits

= ylimits)

}

AllNodes("dstat$in./1048576", ylabel = "Paging In", tipologiaTempo =

tempo, colorType = color, ylimits = NULL, printTitle = titoli,

fontSize = font)

AllNodes("dstat$out/1048576", ylabel = "Paging Out", tipologiaTempo =

tempo, colorType = color, ylimits = NULL, printTitle = titoli,

fontSize = font)

AllNodes("dstat$used.1/1048576", ylabel = "Swap (MB)", tipologiaTempo

= tempo, colorType = color, ylimits = NULL, printTitle = titoli,

fontSize = font)

AllNodes("dstat$read/1048576", ylabel = "Disk usage Read (MB/s)",

tipologiaTempo = tempo, colorType = color, ylimits = NULL,

Page 85: Hadoop analyzerJR

5.2. R CODE 85

printTitle = titoli, fontSize = font)

AllNodes("dstat$writ/1048576", ylabel = "Disk usage Write (MB/s)",

tipologiaTempo = tempo, colorType = color, ylimits = NULL,

printTitle = titoli, fontSize = font)

AllNodes("dstat$recv/1048576", ylabel = "Net Usage Received (MB/s)",

tipologiaTempo = tempo, colorType = color, ylimits = NULL,

printTitle = titoli, fontSize = font)

AllNodes("dstat$send/1048576", ylabel = "Net Usage Sent (MB/s)",

tipologiaTempo = tempo, colorType = color, ylimits = NULL,

printTitle = titoli, fontSize = font)

AllNodes("dstat$X.recv", ylabel = "Packets Received (#)",

tipologiaTempo = tempo, colorType = color, ylimits = NULL,

printTitle = titoli, fontSize = font)

AllNodes("dstat$X.send", ylabel = "Packets Sent (#)", tipologiaTempo =

tempo, colorType = color, ylimits = NULL, printTitle = titoli,

fontSize = font)

AllNodes("dstat$int", ylabel = "Interrupts (#)", tipologiaTempo =

tempo, colorType = color, printTitle = titoli, fontSize = font)

AllNodes("dstat$csw", ylabel = "Context Switches (#)", tipologiaTempo

= tempo, colorType = color, printTitle = titoli, fontSize = font)

dev.off()

}

}, error = function(err){

print(paste("MY_ERROR: ", err))

})

5.2.2 excel.R

Questo script consente di generare file pdf con grafici che mostrano l’andamentodelle macchine del cluster.

input = readLines(’./R_script/inputExcel.hla’)

inputFile <<- input[1]

output <<- input[2]

loadLibrary <- function(lib){

if(require(package = lib, character.only = TRUE, lib.loc=".")){

print(paste(lib,"is loaded correctly", sep= " "))

} else {

print(paste("trying to install ", lib, sep = " "))

install.packages(lib, lib=".", dependencies = TRUE)

if(require(package = lib, character.only = TRUE, lib.loc=".")){

print(paste(lib,"installed and loaded", sep = " "))

} else {

stop(paste("could not install", lib, sep = " "))

Page 86: Hadoop analyzerJR

86 CONTENTS

}

}

}

r <- getOption("repos") # hard code the US repo for CRAN

r["CRAN"] <- "http://cran.us.r-project.org"

options(repos = r)

loadLibrary("openxlsx")

loadLibrary("methods")

takeDelay <- function(fileInput){

file = readLines(con = fileInput)

a = sub(".*csv ", "", file[4])

a = sub("\".*","", a)

a = as.numeric(a)

return <- a

}

createXLS <- function(){

.e <- environment()

fileOutput = output

if(file.exists(fileOutput)) {

file.remove(fileOutput)

}

for(file in list.files(inputFile, pattern = "*.csv$")){

file = paste(inputFile, file, sep = "")

delayDSTAT = takeDelay(file)

dstat <- read.csv(file, skip=6)

dstat <- subset(dstat, select = -X)

dstat <- dstat[-1,]

if(length(grep(pattern = "master" , x = file)) == 1){

cpuMasterUsr <- dstat$usr

cpuMasterSys <- dstat$sys

cpuMasterIdl <- dstat$idl

cpuMasterWai <- dstat$wai

cpuMasterHiq <- dstat$hiq

cpuMasterSiq <- dstat$siq

memoryMasterUsed <- dstat$used/1048576

memoryMasterBuff <- dstat$buff/1048576

memoryMasterCach <- dstat$cach/1048576

memoryMasterFree <- dstat$free/1048576

swapMaster <- dstat$used.1/1048576

discoReadMaster <- dstat$read/1048576

discoWriteMaster <- dstat$writ/1048576

pacchettiRicevutiMaster <- dstat$X.recv

pacchettiInviatiMaster <- dstat$X.send

Page 87: Hadoop analyzerJR

5.2. R CODE 87

throughputReteRicevutiMaster <- dstat$recv/1048576

throughputReteInviatiMaster <- dstat$send/1048576

dstatMediaCPUMasterUsr <- mean(cpuMasterUsr)

dstatMediaCPUMasterSys <- mean(cpuMasterSys)

dstatMediaCPUMasterIdl <- mean(cpuMasterIdl)

dstatMediaCPUMasterWai <- mean(cpuMasterWai)

dstatMediaCPUMasterHiq <- mean(cpuMasterHiq)

dstatMediaCPUMasterSiq <- mean(cpuMasterSiq)

dstatMediaMemoriaMasterUsed <- mean(memoryMasterUsed)

dstatMediaMemoriaMasterBuff <- mean(memoryMasterBuff)

dstatMediaMemoriaMasterCach <- mean(memoryMasterCach)

dstatMediaMemoriaMasterFree <- mean(memoryMasterFree)

dstatMediaSwapMaster <- mean(swapMaster)

dstatMediaDiscoReadMaster <- mean(discoReadMaster)

dstatMediaDiscoWriteMaster <- mean(discoWriteMaster)

dstatMediaPacchettiRicevutiMaster <- mean(pacchettiRicevutiMaster)

dstatMediaPacchettiInviatiMaster <- mean(pacchettiInviatiMaster)

dstatMediaThroughputReteRicevutiMaster <-

mean(throughputReteRicevutiMaster)

dstatMediaThroughputReteInviatiMaster <-

mean(throughputReteInviatiMaster)

}

else{

#CPU

if(exists("cpuUsr")){

cpuUsr <- cbind(cpuUsr, dstat$usr)

}

else {

cpuUsr <- dstat$usr

}

if(exists("cpuSys")){

cpuSys <- cbind(cpuSys, dstat$sys)

}

else {

cpuSys <- dstat$sys

}

if(exists("cpuIdl")){

cpuIdl <- cbind(cpuIdl, dstat$idl)

}

else {

cpuIdl <- dstat$idl

}

if(exists("cpuWai")){

cpuWai <- cbind(cpuWai, dstat$wai)

}

else {

cpuWai <- dstat$wai

Page 88: Hadoop analyzerJR

88 CONTENTS

}

if(exists("cpuHiq")){

cpuHiq <- cbind(cpuHiq, dstat$hiq)

}

else {

cpuHiq <- dstat$hiq

}

if(exists("cpuSiq")){

cpuSiq <- cbind(cpuSiq, dstat$siq)

}

else {

cpuSiq <- dstat$siq

}

if(exists("dstatMediaCPUUsr"))

dstatMediaCPUUsr <- cbind(dstatMediaCPUUsr, mean(cpuUsr))

else {

dstatMediaCPUUsr <- cbind(mean(cpuUsr))

}

if(exists("dstatMediaCPUSys"))

dstatMediaCPUSys <- cbind(dstatMediaCPUSys, mean(cpuSys))

else {

dstatMediaCPUSys <- cbind(mean(cpuSys))

}

if(exists("dstatMediaCPUIdl"))

dstatMediaCPUIdl <- cbind(dstatMediaCPUIdl, mean(cpuIdl))

else {

dstatMediaCPUIdl <- cbind(mean(cpuIdl))

}

if(exists("dstatMediaCPUWai"))

dstatMediaCPUWai <- cbind(dstatMediaCPUWai, mean(cpuWai))

else {

dstatMediaCPUWai <- cbind(mean(cpuWai))

}

if(exists("dstatMediaCPUHiq"))

dstatMediaCPUHiq <- cbind(dstatMediaCPUHiq, mean(cpuHiq))

else {

dstatMediaCPUHiq <- cbind(mean(cpuHiq))

}

if(exists("dstatMediaCPUSiq"))

dstatMediaCPUSiq <- cbind(dstatMediaCPUSiq, mean(cpuSiq))

else {

dstatMediaCPUSiq <- cbind(mean(cpuSiq))

}

#MEMORIA

if(exists("memoryUsed")) {

memoryUsed <- cbind(memoryUsed, dstat$used/1048576)

}

else {

memoryUsed <- dstat$used/1048576

Page 89: Hadoop analyzerJR

5.2. R CODE 89

}

if(exists("memoryBuff")) {

memoryBuff <- cbind(memoryBuff, dstat$buff/1048576)

}

else {

memoryBuff <- dstat$buff/1048576

}

if(exists("memoryCach")) {

memoryCach <- cbind(memoryCach, dstat$cach/1048576)

}

else {

memoryCach <- dstat$cach/1048576

}

if(exists("memoryFree")) {

memoryFree <- cbind(memoryFree, dstat$free/1048576)

}

else {

memoryFree <- dstat$free/1048576

}

if(exists("dstatMediaMemoriaUsed"))

dstatMediaMemoriaUsed <- cbind(dstatMediaMemoriaUsed,

mean(memoryUsed))

else {

dstatMediaMemoriaUsed <- cbind(mean(memoryUsed))

}

if(exists("dstatMediaMemoriaBuff"))

dstatMediaMemoriaBuff <- cbind(dstatMediaMemoriaBuff,

mean(memoryBuff))

else {

dstatMediaMemoriaBuff <- cbind(mean(memoryBuff))

}

if(exists("dstatMediaMemoriaCach"))

dstatMediaMemoriaCach <- cbind(dstatMediaMemoriaCach,

mean(memoryCach))

else {

dstatMediaMemoriaCach <- cbind(mean(memoryCach))

}

if(exists("dstatMediaMemoriaFree"))

dstatMediaMemoriaFree <- cbind(dstatMediaMemoriaFree,

mean(memoryFree))

else {

dstatMediaMemoriaFree <- cbind(mean(memoryFree))

}

#SWAP

if(exists("swap")) {

swap <- cbind(swap, dstat$used.1/1048576)

}

Page 90: Hadoop analyzerJR

90 CONTENTS

else {

swap <- dstat$used.1/1048576

}

if(exists("dstatMediaSwap"))

dstatMediaSwap <- cbind(dstatMediaSwap, mean(swap))

else {

dstatMediaSwap <- cbind(mean(swap))

}

#DISCO READ

if(exists("discoRead")) {

discoRead <- cbind(discoRead, dstat$read/1048576)

}

else {

discoRead <- dstat$read/1048576

}

if(exists("dstatMediaDiscoRead"))

dstatMediaDiscoRead <- cbind(dstatMediaDiscoRead,

mean(discoRead))

else {

dstatMediaDiscoRead <- cbind(mean(discoRead))

}

#DISCO WRITE

if(exists("discoWrite")) {

discoWrite <- cbind(discoWrite, dstat$writ/1048576)

}

else {

discoWrite <- dstat$writ/1048576

}

if(exists("dstatMediaDiscoWrite"))

dstatMediaDiscoWrite <- cbind(dstatMediaDiscoWrite,

mean(discoWrite))

else {

dstatMediaDiscoWrite <- cbind(mean(discoWrite))

}

#PACCHETTI RICEVUTI

if(exists("pacchettiRicevuti")) {

pacchettiRicevuti <- cbind(pacchettiRicevuti, dstat$X.recv)

}

else {

pacchettiRicevuti <- dstat$X.recv

}

if(exists("dstatMediaPacchettiRicevuti"))

dstatMediaPacchettiRicevuti <-

cbind(dstatMediaPacchettiRicevuti, mean(pacchettiRicevuti))

else {

dstatMediaPacchettiRicevuti <- cbind(mean(pacchettiRicevuti))

}

#PACCHETTI INVIATI

if(exists("pacchettiInviati")) {

pacchettiInviati <- cbind(pacchettiInviati, dstat$X.send)

Page 91: Hadoop analyzerJR

5.2. R CODE 91

}

else {

pacchettiInviati <- dstat$X.send

}

if(exists("dstatMediaPacchettiInviati"))

dstatMediaPacchettiInviati <- cbind(dstatMediaPacchettiInviati,

mean(pacchettiInviati))

else {

dstatMediaPacchettiInviati <- cbind(mean(pacchettiInviati))

}

#THROUGHPUT RETE RICEVUTI

if(exists("throughputReteRicevuti")) {

throughputReteRicevuti <- cbind(throughputReteRicevuti,

dstat$recv/1048576)

}

else {

throughputReteRicevuti <- dstat$recv/1048576

}

if(exists("dstatMediaThroughputReteRicevuti"))

dstatMediaThroughputReteRicevuti <-

cbind(dstatMediaThroughputReteRicevuti,

mean(throughputReteRicevuti))

else {

dstatMediaThroughputReteRicevuti <-

cbind(mean(throughputReteRicevuti))

}

#THROUGHPUT RETE INVIATI

if(exists("throughputReteInviati")) {

throughputReteInviati <- cbind(throughputReteInviati,

dstat$send/1048576)

}

else {

throughputReteInviati <- dstat$send/1048576

}

if(exists("dstatMediaThroughputReteInviati"))

dstatMediaThroughputReteInviati <-

cbind(dstatMediaThroughputReteInviati,

mean(throughputReteInviati))

else {

dstatMediaThroughputReteInviati <-

cbind(mean(throughputReteInviati))

}

}

}

listMasterDstat =

list(cpuMasterUsr,cpuMasterSys,cpuMasterIdl,cpuMasterWai,cpuMasterHiq,cpuMasterSiq,memoryMasterUsed,

memoryMasterBuff, memoryMasterCach, memoryMasterFree,swapMaster,

discoReadMaster, discoWriteMaster,

pacchettiRicevutiMaster, pacchettiInviatiMaster,

Page 92: Hadoop analyzerJR

92 CONTENTS

throughputReteRicevutiMaster,

throughputReteInviatiMaster)

listDstat = list(cpuUsr,cpuSys,

cpuIdl,cpuWai,cpuHiq,cpuSys,memoryUsed, memoryBuff,

memoryCach,memoryFree, swap, discoRead, discoWrite,

pacchettiRicevuti, pacchettiInviati,

throughputReteRicevuti, throughputReteInviati)

for(j in 1:17) {

listDstat[[j]] <- cbind(listMasterDstat[[j]], listDstat[[j]])

for(numeroColonna in 2:ncol(listDstat[[j]])) {

variabile <- paste ("Slave", numeroColonna-1, sep = "", collapse =

NULL)

colnames(listDstat[[j]])[numeroColonna] <- variabile

}

listDstat[[j]] <- cbind(seq(delayDSTAT,

nrow(listDstat[[j]])*delayDSTAT, delayDSTAT), listDstat[[j]])

colnames(listDstat[[j]])[1] <- "Tempo"

colnames(listDstat[[j]])[2] <- "Master"

}

dstatMedieCPUUsr <- cbind(dstatMediaCPUMasterUsr, dstatMediaCPUUsr)

dstatMedieCPUSys <- cbind(dstatMediaCPUMasterSys, dstatMediaCPUSys)

dstatMedieCPUIdl <- cbind(dstatMediaCPUMasterIdl, dstatMediaCPUIdl)

dstatMedieCPUWai <- cbind(dstatMediaCPUMasterWai, dstatMediaCPUWai)

dstatMedieCPUHiq <- cbind(dstatMediaCPUMasterHiq, dstatMediaCPUHiq)

dstatMedieCPUSiq <- cbind(dstatMediaCPUMasterSiq, dstatMediaCPUSiq)

dstatMedieMemoriaUsed <- cbind(dstatMediaMemoriaMasterUsed,

dstatMediaMemoriaUsed)

dstatMedieMemoriaBuff <- cbind(dstatMediaMemoriaMasterBuff,

dstatMediaMemoriaBuff)

dstatMedieMemoriaCach <- cbind(dstatMediaMemoriaMasterCach,

dstatMediaMemoriaCach)

dstatMedieMemoriaFree <- cbind(dstatMediaMemoriaMasterFree,

dstatMediaMemoriaFree)

dstatMedieSwap <- cbind(dstatMediaSwapMaster, dstatMediaSwap)

Page 93: Hadoop analyzerJR

5.2. R CODE 93

dstatMedieDiscoRead <- cbind(dstatMediaDiscoReadMaster,

dstatMediaDiscoRead)

dstatMedieDiscoWrite <- cbind(dstatMediaDiscoWriteMaster,

dstatMediaDiscoWrite)

dstatMediePacchettiRicevuti <-

cbind(dstatMediaPacchettiRicevutiMaster,

dstatMediaPacchettiRicevuti)

dstatMediePacchettiInviati <- cbind(dstatMediaPacchettiInviatiMaster,

dstatMediaPacchettiInviati)

dstatMedieThroughputReteRicevuti <-

cbind(dstatMediaThroughputReteRicevutiMaster,

dstatMediaThroughputReteRicevuti)

dstatMedieThroughputReteInviati <-

cbind(dstatMediaThroughputReteInviatiMaster,

dstatMediaThroughputReteInviati)

dstatMedieTotali <-

rbind(dstatMedieCPUUsr,dstatMedieCPUSys,dstatMedieCPUIdl,dstatMedieCPUWai,dstatMedieCPUHiq,dstatMedieCPUSiq,

dstatMedieMemoriaUsed,dstatMedieMemoriaBuff,dstatMedieMemoriaCach,dstatMedieMemoriaFree,dstatMedieSwap,dstatMedieDiscoRead,

dstatMedieDiscoWrite,dstatMediePacchettiRicevuti,dstatMediePacchettiInviati,

dstatMedieThroughputReteRicevuti,dstatMedieThroughputReteInviati)

colnames(dstatMedieTotali)[1] <- "Master"

dstatMediaNomi = rbind("CPU USR","CPU SYS","CPU IDL","CPU WAI","CPU

HIQ","CPU SIQ","MEMORIA USED","MEMORIA BUFF","MEMORIA

CACH","MEMORIA FREE","SWAP","DISCO LETTURA","DISCO SCRITTURA",

"PACCHETTI RETE RICEVUTI","PACCHETTI RETE

INVIATI",

"THROUGHPUT RETE RICEVUTI","THROUGHPUT RETE

INVIATI")

dstatMedieTotali = cbind(dstatMediaNomi, dstatMedieTotali)

colnames(dstatMedieTotali)[1] <- "Informazione"

for(numeroColonna in 3:ncol(dstatMedieTotali)) {

variabile <- paste ("Slave", numeroColonna-2, sep = "", collapse =

NULL)

colnames(dstatMedieTotali)[numeroColonna] <- variabile

}

output = paste(output, "excelDstat", sep="")

l = list("CPU USR" = listDstat[[1]], "CPU SYS" = listDstat[[2]], "CPU

IDL" = listDstat[[3]], "CPU WAI" = listDstat[[4]], "CPU HIQ" =

listDstat[[5]], "CPU SIQ" = listDstat[[6]], "MEMORIA USED" =

listDstat[[7]], "MEMORIA BUFF" = listDstat[[8]], "MEMORIA CACH" =

listDstat[[9]], "MEMORIA FREE" = listDstat[[10]], "SWAP" =

listDstat[[11]], "DISCO LETTURA" = listDstat[[12]], "DISCO

SCRITTURA" = listDstat[[13]], "PACCHETTI RICEVUTI" =

listDstat[[14]], "PACCHETTI INVIATI" = listDstat[[15]],

"THROUGHPUT RETE RICEVUTI" = listDstat[[16]], "THROUGHPUT RETE

INVIATI" = listDstat[[17]], "Aggregato" = dstatMedieTotali)

Page 94: Hadoop analyzerJR

94 CONTENTS

write.xlsx(x = l, file = output, colNames = TRUE)

}

result <- tryCatch({

createXLS()

}, error = function(err){

print(paste("MY_ERROR: ", err))

})

5.2.3 graphHadoopGenerator.R

Questo script consente di generare il pdf con il grafico relativo alla timeline deitask di Hadoop

#require(ggplot2)

#library(XML)

#library(intervals)

argv <- commandArgs(trailingOnly = TRUE)

print("Inizialiting Environment...")

loadLibrary <- function(lib){

if(require(package = lib, character.only = TRUE, lib.loc=".")){

print(paste(lib,"is loaded correctly", sep= " "))

} else {

print(paste("trying to install ", lib, sep = " "))

install.packages(lib, lib=".", dependencies = TRUE)

if(require(package = lib, character.only = TRUE, lib.loc=".")){

print(paste(lib,"installed and loaded", sep = " "))

} else {

stop(paste("could not install", lib, sep = " "))

}

}

}

r <- getOption("repos") # hard code the US repo for CRAN

r["CRAN"] <- "http://cran.us.r-project.org"

options(repos = r)

#Sys.setenv(JAVA_HOME=’C:\\Program Files\\Java\\jre1.8.0_25’)

loadLibrary("ggplot2")

loadLibrary("XML")

loadLibrary("intervals")

printf <- function(...)print(sprintf(...))

print("Progress..")

tablehead = c("startTime", "finishTime", "elapsedTime", "progress",

"id", "rack", "state", "status", "nodeHttpAddress", "diagnostics",

"type", "assignedContainerId")

for(file in list.files(argv[1])) {

file = paste(argv[1], file, sep = "")

Page 95: Hadoop analyzerJR

5.2. R CODE 95

content = readLines(file)

pagetree <- xmlInternalTreeParse(content, error=function(...){},

useInternalNodes = TRUE)

tablehead = c("StartTime", "FinishTime", "ElapsedTime", "Progress",

"Attempt", "Rack", "State", "Status", "Node", "Note", "Type",

"AssignedContainerId")

tablebody = xpathSApply(pagetree, "//*/taskAttempt/*", xmlValue)

if(length(tablebody) == 0){

next;

}

tabella = matrix(tablebody, ncol = length(tablehead), byrow = TRUE)

newframe = data.frame(tabella)

colnames(newframe) <- tablehead

newframe <- subset(newframe, select =

c(Attempt,State,Status,Node,StartTime,FinishTime,ElapsedTime,Note))

if(exists("miaVariabile")){

miaVariabile <- rbind(miaVariabile, newframe)

}else{

miaVariabile <- newframe

}

}

miaVariabile$StartTime =

levels(miaVariabile$StartTime)[miaVariabile$StartTime]

#miaVariabile$StartTime = strptime(miaVariabile$StartTime, "%a, %d %b %Y

%H:%M:%S")

miaVariabile$FinishTime =

levels(miaVariabile$FinishTime)[miaVariabile$FinishTime]

#miaVariabile$FinishTime = strptime(miaVariabile$FinishTime, "%a, %d %b

%Y %H:%M:%S")

miaVariabile$StartTime= as.numeric(miaVariabile$StartTime)

miaVariabile$FinishTime = as.numeric(miaVariabile$FinishTime)

miaVariabile$FinishTime = miaVariabile$FinishTime -

miaVariabile$StartTime

miaVariabile$StartTime = miaVariabile$StartTime -

min(miaVariabile$StartTime)

miaVariabile$FinishTime = miaVariabile$FinishTime +

miaVariabile$StartTime

#importare la libreria Intervals

print("Progress....")

nuovoFrame = subset(x = miaVariabile, select = c(Node, StartTime,

FinishTime))

nuovoFrame = nuovoFrame[with(nuovoFrame, order(Node)), ]

invisible(by(data = nuovoFrame, INDICES = nuovoFrame$Node, FUN =

function(x){

Page 96: Hadoop analyzerJR

96 CONTENTS

mat = matrix(data = c(x$StartTime, x$FinishTime), ncol = 2)

A = Intervals(mat)

ol <<-interval_overlap(A,A)

# ord <- order(mat[,1], decreasing = TRUE)

# mat = mat[ord,]

#

# print(mat)

#TODO

# interval_overlap(Aint, Aint)

mat1 = mat

mat1 = cbind(mat1, NA)

diff = list()

for(i in 1:dim(mat1)[1]){

diff[[i]] = setdiff(seq(1,dim(mat1)[1]),ol[[i]])

}

num = 0

for(i in 1:length(diff)){

flag = FALSE

visitati = c()

if(is.na(mat1[i,3])){

num = num + 1

mat1[i,3] = num

if(length(diff[[i]]) == 0){

#print("la lunghezza e’ zero")

}

else{

for(j in 1:length(diff[[i]])){

#printf("j = %d", j)

#print(flag)

if(flag == FALSE){

if(is.na(mat1[diff[[i]][j],3])){

mat1[diff[[i]][j],3] = num

#print("mat1")

#printf("mat1[%d][%d] = %d", diff[[i]][j], 3,

mat1[diff[[i]][j],3])

#print(mat1[diff[[i]][j],3])

visitati = c(visitati, diff[[i]][j])

flag = TRUE

}

}

else{

for(l in 1:length(visitati)){

#printf("visitati[%d] = %d", l, visitati[l])

#printf("diff[[%d]][%d] = %d", i, l, diff[[i]][j])

differenza = setdiff(diff[[i]][visitati[l]], diff[[i]][j])

Page 97: Hadoop analyzerJR

5.2. R CODE 97

#print("differenza")

#print(differenza)

if(length(differenza) == 0){

#print("ok la differenza e’ 0 e posso aggiungere sulla

stessa linea")

if(is.na(mat1[diff[[i]][j],3])){

mat1[diff[[i]][j],3] = num

visitati = c(visitati, diff[[i]][j])

}

}

}

}

}

}

}

}

print("Progress......")

#mat1 = cbind(levels(x$Node), mat1)

#print(x$Node)

#print(mat1)

if(!exists("matComp")){

matComp <<- mat1

} else{

matComp <<- rbind(matComp,mat1)

}

}

))

frameP = data.frame(matComp)

frameP = cbind(frameP, nuovoFrame$Node)

frameP = cbind(frameP, miaVariabile$State)

colnames(frameP) = c("StartTime", "FinishTime", "LineNumber", "Node",

"State")

frameP$Node = sub(".*/","",frameP$Node)

frameP$Node = sub(":.*","", frameP$Node)

frameP$Node = paste(frameP$Node, "/")

frameP$Node = paste(frameP$Node, frameP$LineNumber)

# ggplot(frameP, aes(colour=State)) +

# geom_segment(aes(x=StartTime, xend=FinishTime, y=Node, yend=Node),

size=6, position = "identity", lineend = "round") +

# xlab("Duration")

plotLogHadoop <- function(tipologiaTempo,dstat, .e, len, title,

printTitle = TRUE, fontSize = NULL){

#print(frameP)

p = ggplot(frameP, aes(colour=State), environment = environment())

p = p + geom_segment(aes(x=StartTime, xend=FinishTime, y=Node,

Page 98: Hadoop analyzerJR

98 CONTENTS

yend=Node), size=6, position = "identity", lineend = "round")

p = p + xlab("Duration")

p = p + scale_x_continuous(expand = c(0, 0))

#p = p + scale_y_discrete(limits = rev(frameP$Node), expand = c(0.1,0))

p = p + theme(legend.position = "right",

panel.grid.major.y = element_line(colour = "black"),

panel.background = element_rect(fill = ’white’, colour =

’black’),

panel.grid.major.x = element_blank(),

panel.grid.minor.x = element_blank(),

axis.text = element_text(colour = "black" ,

size = fontSize))

if(printTitle){

p = p + ggtitle(title)

}

print(p)

}

output = argv[2]

output = paste(output, "hadoopGraph.pdf", sep = "")

pdf(file = output, width = 10, height = 10)

plotLogHadoop(tipologiaTempo = "s",dstat = frameP, .e = environment(),

title = "Log Hadoop", printTitle = TRUE, fontSize = 10)

invisible(dev.off())

print("Hadoop Graph Generated...Done!")

5.2.4 speedup.R

Questo script consente di generare file pdf con grafici che mostrano l’andamentodello speedup e dell’efficienza del cluster

argv <- commandArgs(trailingOnly = TRUE)

alarm()

loadLibrary <- function(lib){

if(require(package = lib, character.only = TRUE, lib.loc=".")){

print(paste(lib,"is loaded correctly", sep= " "))

} else {

print(paste("trying to install ", lib, sep = " "))

install.packages(lib, lib=".", dependencies = TRUE)

if(require(package = lib, character.only = TRUE, lib.loc=".")){

print(paste(lib,"installed and loaded", sep = " "))

} else {

stop(paste("could not install", lib, sep = " "))

}

}

}

Page 99: Hadoop analyzerJR

5.2. R CODE 99

r <- getOption("repos") # hard code the US repo for CRAN

r["CRAN"] <- "http://cran.us.r-project.org"

options(repos = r)

#Sys.setenv(JAVA_HOME=’C:\\Program Files\\Java\\jre1.8.0_25’)

#loadLibrary("rJava")

loadLibrary("colorspace")

loadLibrary("scales")

loadLibrary("ggplot2")

loadLibrary("plyr")

loadLibrary("reshape2")

speedUp <- function(TempoSequenziale, VettoreTempiHadoop,

vettoreNodiUsati, output){

su = TempoSequenziale / VettoreTempiHadoop

efficienza = su / vettoreNodiUsati

#plot(vettoreNodiUsati, su, type=c("l"))

df = data.frame(VettoreTempiHadoop, vettoreNodiUsati, su, efficienza)

p = ggplot(df, aes(df), environment = environment())

p = p + geom_line(aes(x = vettoreNodiUsati, y = su), colour = "red")

p = p + xlab("# nodes")

p = p + ylab("Speedup")

p = p + scale_x_continuous(expand = c(0, 0))

p = p + scale_y_continuous(expand = c(0, 0))

p = p + theme(panel.grid.major.y = element_line(colour = "black"),

panel.background = element_rect(fill = ’white’, colour =

’black’),

panel.grid.major.x = element_blank(),

panel.grid.minor.x = element_blank(),

axis.text = element_text(colour = "black"))

p = p + ggtitle("Speedup Chart")

outputSU = paste(output, "speedup_efficiency.pdf", sep = "")

pdf(file = outputSU, width = 10, height = 10)

print(p)

p = ggplot(df, aes(df), environment = environment())

p = p + geom_line(aes(x = vettoreNodiUsati, y = efficienza), colour =

"red")

p = p + xlab("# nodes")

p = p + ylab("Speedup")

p = p + scale_x_continuous(expand = c(0, 0))

p = p + scale_y_continuous(expand = c(0, 0))

p = p + theme(panel.grid.major.y = element_line(colour = "black"),

panel.background = element_rect(fill = ’white’, colour =

’black’),

panel.grid.major.x = element_blank(),

panel.grid.minor.x = element_blank(),

Page 100: Hadoop analyzerJR

100 CONTENTS

axis.text = element_text(colour = "black"))

p = p + ggtitle("Efficiency Chart")

print(p)

dev.off()

}

result <- tryCatch({

output = argv[1]

dati = as.matrix(read.csv(file = ’./R_script/speedup.hla’, header =

FALSE, sep = ","))

speedUp(TempoSequenziale = dati[3,1], VettoreTempiHadoop = dati[2,],

vettoreNodiUsati = dati[1,], output)

}, error = function(err){

print(paste("MY_ERROR: ", err))

})

5.3 C code

Di seguito sono elencati gli script C.

5.3.1 client.c

Questo script lanciato sul master permette di invocare metodi remoti ai varislave per avviare e stoppare Dstat in maniera parallela

#include "basic.h"

void client_echo(FILE *fp, int sockfd);

int hostname_to_ip(char * , char *);

/***************************************************************************

* gestisci_zombie

* chiama waitpid per eliminare gli zombie.

* Deve essere registrata con signal per il segnale SIGCHLD

***************************************************************************/

void gestisci_zombie(int signo) {

pid_t pid;

int stat;

while ( (pid = waitpid(-1,&stat,WNOHANG)) > 0) {

printf("Child %d terminated\n",pid);

}

}

/***************************************************************************

Page 101: Hadoop analyzerJR

5.3. C CODE 101

* reti_read

* legge tutti i dati disponibili nel buffer in una sola volta e poi li

* esamina un byte per volta. La read, invece, legge un byte per volta.

***************************************************************************/

ssize_t reti_read(int fd, char *ptr) {

static int read_cnt = 0; /* numero di byte letti */

static char read_buf[MAXLINE]; /* buffer per mantenere i dati

letti */

static char *read_ptr; /* puntatore al prossimo byte da

leggere */

if (read_cnt <= 0) {

/* se non ci sono byte disponibili nel buffer chiama la

read. */

while ( (read_cnt = read(fd, read_buf, sizeof(read_buf)))

< 0)

/* se la read fallisce perch non ci sono sufficienti

dati riprova, altrimenti esce. */

if (errno != EINTR)

return(-1);

if (read_cnt == 0)

return(0);

read_ptr = read_buf;

}

/* legge il prossimo byte dal buffer e decrementa il numero dei

byte

disponibili */

read_cnt--;

*ptr = *read_ptr++;

return(1);

}

ssize_t reti_readline(int fd, void *vptr, size_t maxlen) {

int n, rc;

char c, *ptr;

ptr = vptr;

for (n = 1; n < maxlen; n++) {

if ( (rc = reti_read(fd, &c)) == 1) {

*ptr++ = c;

if (c == ’\n’)

break; /* legge il newline, come la fgets() */

}

else

if (rc == 0) {

if (n == 1)

return(0); /* EOF, non ha letto nulla */

Page 102: Hadoop analyzerJR

102 CONTENTS

else

break; /* EOF, ha letto qualcosa */

}

else

return(-1); /* errore, errno settato dalla

read() */

}

*ptr = 0; /* inserisce uno 0 per indicare la fine

dell’input, coma la fgets() */

return(n);

/* restituisce il numero di byte letti */

}

/***************************************************************************

* reti_writen

* scrive n byte sul descrittore fd. Riprova fino a quando i dati non

* vengono effettivamenti scritti.

***************************************************************************/

ssize_t reti_writen(int fd, const void *vptr, size_t n) {

size_t nleft; /* byte anora da scrivere */

ssize_t nwritten; /* byte scritti dall’ultima write */

const char *ptr;

ptr = vptr;

nleft = n;

while (nleft > 0) {

if ( (nwritten = write(fd, ptr, nleft)) <= 0) {

if (errno == EINTR)

/* richiama la write se la funzione fallita perch

nel buffer ptr non ci sono sufficienti byte. */

nwritten = 0;

else

return(-1);

}

nleft -= nwritten;

ptr += nwritten;

}

return(n);

/* restituisce il numero di byte scritti. */

}

int main(int argc, char **argv) {

int sockfd, n;

struct sockaddr_in servaddr;

if (argc != 4) {

printf("usage: %s <indirizzoIP> <porta> <comando> \n",argv[0]);

Page 103: Hadoop analyzerJR

5.3. C CODE 103

exit(1);

}

if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {

printf("Socket error\n");

exit(1);

}

bzero(&servaddr, sizeof(servaddr));

servaddr.sin_family = AF_INET;

servaddr.sin_port = htons(atoi(argv[2])); /* echo server */

if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) {

char *hostname = argv[1];

char ip[100];

hostname_to_ip(hostname , ip);

printf("%s resolved to %s\n" , hostname , ip);

if(inet_pton(AF_INET,ip,&servaddr.sin_addr) <= 0) {

printf("inet_pton error for %s", argv[1]);

exit(1);

}

}

if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr))

< 0) {

printf("connect error");

exit(1);

}

char cmd[80];

strcpy (cmd, argv[3]);

strcat (cmd, "\n");

//printf("comanda abilitati: startDstat, stopDstat, getPid (il pid

viene stampato sul server)\n");

//client_echo(stdin, sockfd); /* svolge tutto il lavoro del client */

char sendline[MAXLINE], recvline[MAXLINE];

reti_writen(sockfd, cmd, strlen(cmd));

if (reti_readline(sockfd, recvline, MAXLINE) == 0) {

printf("%s: server terminated prematurely",__FILE__);

exit(1);

}

fputs(recvline, stdout);

exit(0);

}

Page 104: Hadoop analyzerJR

104 CONTENTS

void client_echo(FILE *fp, int sockfd) {

char sendline[MAXLINE], recvline[MAXLINE];

while (fgets(sendline, MAXLINE, fp) != NULL) {

reti_writen(sockfd, sendline, strlen(sendline));

if (reti_readline(sockfd, recvline, MAXLINE) == 0) {

printf("%s: server terminated prematurely",__FILE__);

exit(1);

}

fputs(recvline, stdout);

}

}

int hostname_to_ip(char *hostname , char *ip)

{

int sockfd;

struct addrinfo hints, *servinfo, *p;

struct sockaddr_in *h;

int rv;

memset(&hints, 0, sizeof hints);

hints.ai_family = AF_UNSPEC; // use AF_INET6 to force IPv6

hints.ai_socktype = SOCK_STREAM;

if ( (rv = getaddrinfo( hostname , "http" , &hints , &servinfo)) !=

0)

{

fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));

return 1;

}

// loop through all the results and connect to the first we can

for(p = servinfo; p != NULL; p = p->ai_next)

{

h = (struct sockaddr_in *) p->ai_addr;

strcpy(ip , inet_ntoa( h->sin_addr ) );

}

freeaddrinfo(servinfo); // all done with this structure

return 0;

}

5.3.2 server.c

Questo script lanciato sugli slave si mette in ascolto in attesa di ordini da partedel master per avviare e stoppare Dstat

Page 105: Hadoop analyzerJR

5.3. C CODE 105

#include "basic.h"

pid_t server_echo(int sockfd, pid_t pid);

/***************************************************************************

* gestisci_zombie

* chiama waitpid per eliminare gli zombie.

* Deve essere registrata con signal per il segnale SIGCHLD

***************************************************************************/

void gestisci_zombie(int signo) {

pid_t pid;

int stat;

while ( (pid = waitpid(-1,&stat,WNOHANG)) > 0) {

printf("Child %d terminated\n",pid);

}

}

/***************************************************************************

* reti_read

* legge tutti i dati disponibili nel buffer in una sola volta e poi li

* esamina un byte per volta. La read, invece, legge un byte per volta.

***************************************************************************/

ssize_t reti_read(int fd, char *ptr) {

static int read_cnt = 0; /* numero di byte letti */

static char read_buf[MAXLINE]; /* buffer per mantenere i dati

letti */

static char *read_ptr; /* puntatore al prossimo byte da

leggere */

if (read_cnt <= 0) {

/* se non ci sono byte disponibili nel buffer chiama la

read. */

while ( (read_cnt = read(fd, read_buf, sizeof(read_buf)))

< 0)

/* se la read fallisce perch\‘e non ci sono

sufficienti

dati riprova, altrimenti esce. */

if (errno != EINTR)

return(-1);

if (read_cnt == 0)

return(0);

read_ptr = read_buf;

}

/* legge il prossimo byte dal buffer e decrementa il numero dei

byte

disponibili */

Page 106: Hadoop analyzerJR

106 CONTENTS

read_cnt--;

*ptr = *read_ptr++;

return(1);

}

ssize_t reti_readline(int fd, void *vptr, size_t maxlen) {

int n, rc;

char c, *ptr;

ptr = vptr;

for (n = 1; n < maxlen; n++) {

if ( (rc = reti_read(fd, &c)) == 1) {

*ptr++ = c;

if (c == ’\n’)

break; /* legge il newline, come la fgets() */

}

else

if (rc == 0) {

if (n == 1)

return(0); /* EOF, non ha letto nulla */

else

break; /* EOF, ha letto qualcosa */

}

else

return(-1); /* errore, errno settato dalla

read() */

}

*ptr = 0; /* inserisce uno 0 per indicare la fine

dell’input, coma la fgets() */

return(n);

/* restituisce il numero di byte letti */

}

/***************************************************************************

* reti_writen

* scrive n byte sul descrittore fd. Riprova fino a quando i dati non

* vengono effettivamenti scritti.

***************************************************************************/

ssize_t reti_writen(int fd, const void *vptr, size_t n) {

size_t nleft; /* byte anora da scrivere */

ssize_t nwritten; /* byte scritti dall’ultima write */

const char *ptr;

pid_t childpid;

ptr = vptr;

nleft = n;

while (nleft > 0) {

Page 107: Hadoop analyzerJR

5.3. C CODE 107

if ( (nwritten = write(fd, ptr, nleft)) <= 0) {

if (errno == EINTR)

/* richiama la write se la funzione \‘e fallita

perch\‘e

nel buffer ptr non ci sono sufficienti byte. */

nwritten = 0;

else

return(-1);

}

nleft -= nwritten;

ptr += nwritten;

}

return(n);

/* restituisce il numero di byte scritti. */

}

int main(int argc, char **argv) {

pid_t childpid;

int listenfd, connfd;

struct sockaddr_in servaddr, cliaddr;

socklen_t cliaddr_len;

char hostname[1024];

hostname[1023] = ’\0’;

gethostname(hostname, 1023);

printf("Hostname: %s\n", hostname);

if (argc != 2) {

printf("Uso: %s <porta>\n",argv[0]);

exit(1);

}

if( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {

printf("Socket error");

exit(1);

}

bzero(&servaddr, sizeof(servaddr));

servaddr.sin_family = AF_INET;

servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

servaddr.sin_port = htons(atoi(argv[1]));

if( (bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr)))

< 0) {

printf("bind error\n");

exit(1);

}

if( listen(listenfd, 5) < 0 ) {

printf("listen error\n");

exit(1);

Page 108: Hadoop analyzerJR

108 CONTENTS

}

childpid = 0;

for ( ; ; ) {

/*attesa di connessione accetta connessione */

cliaddr_len = sizeof(cliaddr);

if( (connfd = accept(listenfd, (struct sockaddr *) &cliaddr,

&cliaddr_len)) < 0) {

printf("Accept error");

exit(1);

}

childpid = server_echo(connfd, childpid); /* svolge tutto il

lavoro del server */

close(connfd);

}

}

pid_t server_echo(int sockfd, pid_t pid) {

ssize_t n;

char line[MAXLINE];

pid_t childpid;

for ( ; ; ) {

if ( (n = reti_readline(sockfd, line, MAXLINE)) == 0)

return pid; /* connection closed by other

end */

if(strcmp(line, "startDstat\n") == 0){

if( (pid = fork()) == 0 ) {

pid = getpid();

//execl("/usr/bin/dstat",

"/usr/bin/dstat","-tcmgsdny", "--net-packets",

"--float", "--noheaders" ,"--output

/home/user/Scrivania/clientServer/dstatOutput.csv",

"10", (char*) 0);

execl("/usr/bin/dstat", "/usr/bin/dstat","-tcmgsdny",

"--net-packets", "--float", "--noheaders" ,"--output",

"/home/user/Scrivania/clientServer/dstatOutput.csv",

"10", (char*) 0);

}

else

printf("PADRE\n");

}

if(strcmp(line, "getPid\n") == 0){

/*stampa il pid, utile solo per debug*/

printf("Il pid e’ %d\n", pid);

fflush(stdin);

}

if(strcmp(line, "stopDstat\n") == 0){

Page 109: Hadoop analyzerJR

5.3. C CODE 109

/*uccide il figlio*/

int err = kill(pid, SIGKILL);

pid = 0;

}

if(strcmp(line, "getDstat\n") == 0){

printf("QUI VA LA FUNZIONE CHE PRENDE I VALORI DA

DSTAT\n");

fflush(stdin);

}

reti_writen(sockfd, line, n);

}

}

5.3.3 AllSlaves.c

Questo script lanciato sul master permette di lanciare in modo automatico uncomando su tutti gli slave

#include "basic.h"

int main(int argc, char **argv) {

if (argc != 5) {

printf("Inserire i seguenti parametri: <start> <stop> <porta>

<comando> \n");

exit(1);

}

int start = atoi(argv[1]);

int stop = atoi(argv[2]);

char buf[100];

pid_t pid;

printf("%d %d\n", start, stop);

for(int i = start; i <= stop; i++){

sprintf(buf, "slave%d", i); // puts string into buffer

printf("%s\n", buf);

if( (pid = fork()) == 0 ) {

execl("./echocli","./echocli",buf, argv[3], argv[4],(char*) 0);

exit(0);

}

}

}

Page 110: Hadoop analyzerJR

Bibliography

[1] JFreeChart http://www.jfree.org/jfreechart/

[2] charts4j https://code.google.com/p/charts4j/

[3] Apache Commons CSV https://commons.apache.org/proper/

commons-csv/

[4] icePdf http://www.icesoft.org/java/home.jsf

[5] Bootstrap http://getbootstrap.com/

[6] Dstat http://dag.wiee.rs/home-made/dstat/

[7] Java profiler http://docs.oracle.com/javase/7/docs/technotes/

samples/hprof.html

[8] R language http://www.r-project.org/

[9] Hadoop http://hadoop.apache.org/

[10] Python http://www.python.it/

110

Page 111: Hadoop analyzerJR

Afterword

Il progetto proposto e stato realizzato da Amedeo Leo, Alessio Petrozziello e Si-mone Romano per il progetto di Sistemi Operativi Avanzati tenuto dal professorGiuseppe Cattaneo.

111