web semantico - Digital Forensics @ UniSa
Transcript
web semantico - Digital Forensics @ UniSa
Università degli Studi di Salerno FACOLTÀ DI SCIENZE MATEMATICHE, FISICHE E NATURALI Corso di Laurea Magistrale in Informatica SISTEMI OPERATIVI II WEB SEMANTICO Docente: Prof. G. CATTANEO Presentata da: SARA CANTALUPO 0522500088 STEFANIA CALIENDO 0522500168 Sessione 2013/2014 2 Indice 1 Introduzione 1.1 Strumenti utilizzati 1.1.1 Hadoop . . 1.1.2 Ontologia . 1.1.3 OWL . . . 1.1.4 POS Tagger 1.1.5 Stemming . 1.1.6 Jena . . . . 1.1.7 Jsoup . . . 1.1.8 HTTrack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1 1 2 2 3 3 3 3 3 2 Analisi progettuale 2.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . . . 2.2 Scelta e preparazione dell’input . . . . . . . . . . . . . . 2.3 Parsing . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.4 Text processing . . . . . . . . . . . . . . . . . . . . . . . 2.5 Calcolo delle frequenze ed estrazione delle parole chiave 2.6 Categorizzazione dei documenti tramite l’ontologia . . . 2.6.1 Esempio di esecuzione dell’algoritmo 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 5 5 6 6 7 7 8 . . . . . . 11 11 14 14 15 15 19 . . . . 23 23 23 24 26 . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 Sviluppo del progetto 3.1 Formato dell’input . . . 3.2 Scelta del Sequence File 3.3 Ontologia . . . . . . . . 3.4 Implementazione . . . . 3.4.1 Sequenziale . . . 3.4.2 Distribuito . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 Tests e Benchmarking 4.1 Ambiente di lavoro . . . . . . . . . . . . 4.2 Test codice sequenziale su file di testo da 4.3 Test codice distribuito tramite Hadoop . 4.3.1 Test Block Size . . . . . . . . . . 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7,9 GB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 INDICE 4.4 4.3.2 Test di scalabilità . . . . . . . . . . . . . . . . . . . . 4.3.3 Profiling versione distribuita con 16 slave e block size 4.3.4 Test distribuito su SequenceFile da 11 GB . . . . . . Esempio output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128 MB . . . . . . . . . . . . . . . . . . . . . . 26 27 33 40 5 Conclusioni 43 Bibliografia 45 Elenco delle figure 2.1 2.2 2.3 2.4 2.5 2.6 Schema riassuntivo dei passi dell’algoritmo . . . . . . . . Schema della fase di preparazione dell’input . . . . . . . Schema riassuntivo della fase di Text Processing . . . . . Input/Output della fase di estrazione delle parole chiave Parte di struttura ad albero dell’ontologia . . . . . . . . Esempio esecuzione algoritmo 1 . . . . . . . . . . . . . . 3.1 3.2 Esempio POS Tagger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 Esempio di utilizzo di StopWord e Stemming . . . . . . . . . . . . . . . . 16 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 4.10 4.11 4.12 4.13 4.14 4.15 4.16 4.17 4.18 4.19 4.20 4.21 4.22 4.23 Stima tempo codice sequenziale . . . . . . . . . . . . . . . Tempo impiegato dall’ontologia per 50 MB . . . . . . . . . Test eseguiti . . . . . . . . . . . . . . . . . . . . . . . . . . Risultati test variando block size . . . . . . . . . . . . . . . Scalabilità . . . . . . . . . . . . . . . . . . . . . . . . . . . Speedup - Efficienza . . . . . . . . . . . . . . . . . . . . . . Speedup . . . . . . . . . . . . . . . . . . . . . . . . . . . . Efficienza . . . . . . . . . . . . . . . . . . . . . . . . . . . . Unità di misura . . . . . . . . . . . . . . . . . . . . . . . . Risultati di Hadoop su test con block size = 128 MB e slave Uso medio CPU - Tutti gli slave . . . . . . . . . . . . . . . Uso CPU - Differenza tra Slave 1 e Slave 15 . . . . . . . . . Uso medio memoria . . . . . . . . . . . . . . . . . . . . . . Uso memoria - Differenza tra Slave 1 e Slave 15 . . . . . . Lettura media disco . . . . . . . . . . . . . . . . . . . . . . Lettura disco - Slave . . . . . . . . . . . . . . . . . . . . . . Scrittura media disco . . . . . . . . . . . . . . . . . . . . . Scrittura disco - Uno slave . . . . . . . . . . . . . . . . . . Media pacchetti di rete inviati . . . . . . . . . . . . . . . . Media pacchetti di rete ricevuti . . . . . . . . . . . . . . . . Media throughput di rete inviati . . . . . . . . . . . . . . . Media throughput di rete ricevuti . . . . . . . . . . . . . . Stato MapSlave - BlockSize 128 MB, 16 slave . . . . . . . . 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . = 16 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 6 7 8 9 9 24 25 25 26 26 26 27 28 29 30 31 32 33 34 35 35 36 36 37 37 38 38 39 6 ELENCO DELLE FIGURE 4.24 Stato MapSlave - BlockSize 32 MB, 8 slave . . . . . . . . . . . . . . . . . 39 4.25 Stato MapSlave SequenceFile 11GB - BlockSize 128 MB, 32 slave . . . . 40 4.26 Esempio output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 Elenco dei codici 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 Generazione Sequence File per file di testo . . . . . . . . . . . . . Esempio file Comments.xml . . . . . . . . . . . . . . . . . . . . . Esempio file PostHistory.xml . . . . . . . . . . . . . . . . . . . . Esempio file Post.xml . . . . . . . . . . . . . . . . . . . . . . . . Generazione Sequence File per file XML . . . . . . . . . . . . . . Fase di Part-Of-Speech Tagger . . . . . . . . . . . . . . . . . . . Parsing per file XML . . . . . . . . . . . . . . . . . . . . . . . . . Fase di rimozione Stop Word e Stemming . . . . . . . . . . . . . Fase di calcolo della frequenza . . . . . . . . . . . . . . . . . . . . Fase di categorizzazione dei documenti tramite ontologia . . . . . Fase di Map per il Sequence FIle di file di testo . . . . . . . . . . Main codice distribuito per Sequence File di file di testo . . . . . Modifiche fase di Map per il Sequence File di file XML . . . . . . Modifiche Main codice distribuito per Sequence File di file XML . 7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 12 13 13 13 15 16 16 17 18 19 20 21 21 8 ELENCO DEI CODICI Capitolo 1 Introduzione La ricerca di informazioni sul Web è un problema complesso, la cui risoluzione ha portato alla nascita di diverse compagnie che hanno migliorato di anno in anno la qualità dei risultati forniti. Tuttavia, l’uso del testo puro come criterio di ricerca ha portato inevitabilmente prima alla scoperta di informazioni legate solo alle parole cercate, ma poi si è pensato di migliorare la ricerca concentrandosi sul loro significato: facendo così nascere il concetto di Web Semantico. Lo scopo di questo progetto è proprio quello di fornire un’implementazione in Java di Web Semantico utilizzando il paradigma Map-Reduce, fornito da Hadoop, e il concetto di Ontologie. Nel seguito di questa sezione saranno fornite alcune definizioni necessarie per la piena comprensione del lavoro svolto. Nel capitolo 2 verrà fornita un’analisi progettuale di come è stato affrontato il progetto. Nel capitolo 3 sarà descritta la nostra implementazione dell’algoritmo e verranno spiegate le scelte implementative fatte, la spiegazione dei test effettuati nel capitolo 4, per poi chiudere con le conclusioni nel capitolo 5. 1.1 1.1.1 Strumenti utilizzati Hadoop Hadoop è un open source framework sotto licenza Apache. Nasce come progetto per l’analisi distribuita di grandi insiemi di dati attraverso un semplice modello di programmazione. Hadoop è ormai riconosciuto come una delle più promettenti soluzioni general-purpose per i Big Data, capace di memorizzare grandi quantità di dati e di fornire una semplice ma potente piattaforma di analisi. Per permettere la computazione e l’analisi di dati distribuiti può essere installato su un cluster di macchine linux. Le componenti fondamentali di Hadoop sono: • Hadoop Common Librerie di base per la corretta esecuzione di Hadoop; • Hadoop YARN 1 2 CAPITOLO 1. INTRODUZIONE Componente per la pianificazione dei progetti e la gestione delle risorse del cluster; • MapReduce Sistema di elaborazione parallela dei dati. Secondo tale paradigma le applicazioni vengono divise in piccoli task e ogni task può essere su uno o più nodi rendendo l’applicazione distribuita. In particolare l’elaborazione avviene in due fasi: – Map: Prende in input una coppia chiave-valore e restituisce in output una lista di coppie intermedie chiave’-valore’. – Reduce: Prende in input una lista di coppie chiave-valore intermedie, che hanno la stessa chiave e restituisce in output una lista di coppie chiave’-valore’. • Hadoop Distributed File System (HDFS) Filesystem distribuito, scritto in JAVA, usato da Hadoop. Permette di gestire in modo distribuito grandi insiemi di dati. E’ un block-structured file system, secondo cui i singoli file sono suddivisi in blocchi di dimensione fissa e distribuiti tra i vari nodi del cluster mantenendo anche delle repliche per garantire maggiore sicurezza. Hadoop cerca di far eseguire a ciascun nodo i calcoli sui blocchi di file presenti nel proprio disco, in questo modo si suddivide il carico di lavoro aumentando le prestazioni di calcolo e diminuendo traffico di rete. 1.1.2 Ontologia L’ontologia è una delle principali branche della filosofia che si occupa delle categorie fondamentali dell’essere. Dal punto di vista informatico, l’ontologia ha trovato applicazione come metodo di rappresentazione della conoscenza. Le ontologie attualmente sono utilizzate per diversi scopi tra cui quello della classificazione di documenti. Esse permettono di esprimere l’appartenenza degli oggetti a delle categorie, fornendo al tempo stesso una gerarchia fra le categorie stesse. Un’ontologia è costituita da: • Classi (concetti generali del dominio di interesse); • Relazioni tra queste classi; • Proprietà (attributi, slot, ruoli) assegnate a ciascun concetto, che ne descrivono vari tipi di attributi o proprietà. Le ontologie sono aperte e riutilizzabili. Queste sono due proprietà fondamentali, perché fanno che si che le informazioni contenute nelle diverse ontologie, non siano fini a sé stesse, ma integrabili. Questo significa che due ontologie diverse possano essere integrate per condividere l’informazione. Inoltre il fatto che le ontologie siano riutilizzabili, permette che nessuna informazione vada sprecata. Le ontologie sono scritte in OWL. 1.1.3 OWL OWL (Ontology Web Language) è un linguaggio di markup per la specifica formale della semantica, il cui fine è descrivere delle basi di conoscenze, effettuare delle deduzioni su 1.1. STRUMENTI UTILIZZATI 3 di esse e integrarle con i contenuti delle pagine web. Le ontologie OWL, sviluppato dal W3C Web Ontology Group, forniscono classi, proprietà, individui e valori che è possibile memorizzare e condividere come documenti del Semantic Web. 1.1.4 POS Tagger Part-Of-Speech Tagger è un software che prende in input un file di testo e assegna ad ogni parola un tag POS in base al suo valore sintattico. 1.1.5 Stemming È una funzione, usata da alcuni motori di ricerca per l’espansione di interrogazioni e in altri problemi di elaborazione del linguaggio naturale, che consente di comprendere tra i risultati della ricerca tutte le pagine che contengono parole aventi la stessa radice delle keyword utilizzate nell’interrogazione. Ad esempio una ricerca con la parola danza darà come risultato anche pagine che contengono le parole ’danzatore’ o ’danzatrice’. 1.1.6 Jena Jena è un framework Java per lo sviluppo di applicazioni orientate al web semantico. Esso fornisce delle API per leggere e scrivere grafi RDF (Resource Description Framework), rappresentati come un modello astratto. Jena supporta anche OWL ed include inoltre vari motori di deduzione logica. Jena è open source ed è stato sviluppato dall’HP Labs Semantic Web Programme. 1.1.7 Jsoup Jsoup è una libreria Java che permette di estrarre e manipolare dati da codice HTML prelevato da un URL o una stringa, utilizzando un attraversamento DOM (Document Object Model), gerarchia ad albero, o dei selettori CSS. 1.1.8 HTTrack HTTrack è un’applicazione Open source sviluppata da Xavier Roche che permette di scaricare siti web da Internet in una directory locale, costruendo ricorsivamente tutte le directory e ottenendo pagine HTML, immagini e altri file dal server al computer. Ciò consentirebbe di visualizzare l’intero sito in locale, senza essere collegati alla rete Internet. 4 CAPITOLO 1. INTRODUZIONE Capitolo 2 Analisi progettuale 2.1 Introduzione Il seguente capitolo presenta le diverse fasi del progetto, la cui implementazione, sia sequenziale che in distribuito, sarà mostrata nei capitoli successivi. I passi dell’algoritmo sono presentati in figura 2.1 e possono essere così riassunti: • scelta e preparazione dell’input; • parsing; • text processing; • calcolo delle frequenze ed estrazione delle parole chiave; • categorizzazione dei documenti tramite l’ontologia. 2.2 Scelta e preparazione dell’input L’input consiste di un elevato numero di pagine web [3]. In un primo momento si è pensato di utilizzare le pagine nel formato originale e quindi di procedere alla rimozione dei tag html nella fase di text-processing. Si è, però, ritenuto più opportuno fare uso di un convertitore, in modo tale da estrarre semplice testo dalle pagine in formato html; questo processo ha consentito non solo di eliminare le informazioni non necessarie all’analisi dei documenti (tag html, css, immagini . . . ), ma anche di ridurre la taglia dell’input (Figura 2.2 ). In un secondo momento, però, avendo a disposizione un dataset di file in formato xml, si è ritenuto necessario introdurre una fase alternativa di parsing che sarà illustrata nel paragrafo successivo. 5 6 CAPITOLO 2. ANALISI PROGETTUALE File html File xml Conversione Parsing Text Processing Calcolo frequenze e parole chiave Ontologia Categorizzazione tramite ontologia Categoria finale Figura 2.1: Schema riassuntivo dei passi dell’algoritmo File in formato html Convertitore File in formato testo Figura 2.2: Schema della fase di preparazione dell’input 2.3 Parsing La seguente fase è utilizzata solo per il trattamento dei file in formato xml. Per la definizione dell’input si rimanda al paragrafo 3.1. Il parsing consente di estrapolare dal testo solo le informazioni necessarie all’analisi. 2.4 Text processing La fase di text processing può essere suddivisa in ulteriori sottopassaggi. La prima operazione da compiere è il Part Of Speech tagging [4], che consiste nell’etichettare ogni parola con il suo ruolo nella frase (soggetto, verbo, predicato, . . . ). Quindi, si passa alla fase di word stemming: tale processo riduce le parole alla loro radice, 2.5. CALCOLO DELLE FREQUENZE ED ESTRAZIONE DELLE PAROLE CHIAVE7 Semplice testo Part Of Speech Tagging Word Stemming Rimozione delle stop word P = {p1 , p2 , . . . , pn } Figura 2.3: Schema riassuntivo della fase di Text Processing in modo da identificare più facilmente concetti. Ad esempio, i termini “fishing”, “fisher”, “fished” vengono sostituiti dalla loro radice “fish”. Questa fase è propedeutica a quella di estrazione delle parole chiave, in quanto consente di contare i termini in base al loro valore semantico. Una volta fatto ciò, è necessario ripulire il testo da informazioni superflue: a tale scopo si effettua la rimozione delle stop word, ovvero di tutti quei termini di uso comune che non sono propri del contesto (congiunzioni, disgiunzioni, avverbi, ecc.), e dei segni di punteggiatura. L’operazione di Part Of Speech tagging è effettuata per prima in quanto facilita le fasi successive. L’output della fase appena descritta sarà quindi un insieme P = {p1 , p2 , . . . , pn } di parole. La figura 2.3 riassume in un diagramma i passaggi di questa fase. 2.5 Calcolo delle frequenze ed estrazione delle parole chiave Dopo aver pulito il testo dai termini poco significativi per il nostro obiettivo, si passa alla fase di estrazione delle parole o frasi chiave. Per semplicità, la scelta è ricaduta sulle parole. Quindi, dopo aver contato le occorrenze di ogni parola all’interno di un documento, si prendono in considerazione solo le prime 10 parole, in ordine decrescente di frequenza; tali termini sono forniti in input alla fase successiva. Se P è l’insieme delle n parole risultato dalla fase precedente, R sarà l’insieme delle 10 parole che rappresenta l’output di questa fase, come mostrato in figura 2.4. 2.6 Categorizzazione dei documenti tramite l’ontologia In questa sezione, come presentato da [1], ogni parola chiave è mappata [5] in una risorsa dell’ontologia. Per ottenere la categoria finale, che sia più specifica possibile per un dato documento di testo, l’insieme delle parole chiave viene partizionato in coppie ri , rj . Così, per ogni coppia di parole si esegue l’algoritmo 1. 8 CAPITOLO 2. ANALISI PROGETTUALE P = {p1 , p2 , . . . , pn } Calcolo frequenze R = {r1 , r2, . . . , r10 } Figura 2.4: Input/Output della fase di estrazione delle parole chiave Algorithm 1 Return the final category of text 1: if ri and rj are similar then 2: the result could be each of them 3: else if ri is ancestor of rj then 4: result is rj 5: else a resource rx is found which is ancestor of both ri and rj . 6: end if 2.6.1 Esempio di esecuzione dell’algoritmo 1 Per comprendere meglio il comportamento dell’algoritmo appena illustrato, sarà fornito un esempio. Si consideri un’ontologia, che presenta una struttura ad albero come quella in Figura 2.5. Siano poi: {Language, P rogramming, N etwork, M onitor, P en, Book, Hardware, Card, M ouse, Sof tware} le 10 parole fornite in input all’algoritmo. L’input viene processato a coppie: la prima coppia Language - Programming rientra nel caso 2 quindi il risultato sarà l’elemento più in basso nella gerarchia, cioè Language; la seconda coppia è formata da Language e Network, e rientrando nel caso 3 il risultato sarà Software, ovvero l’antenato comune alle due risorse; per Software - Monitor, ancora caso 3, il risultato sarà Computer ; la coppia Computer - Hardware (Pen e Book non corrispondono a nessuna risorsa nell’ontologia) rientra nel caso 2, quindi viene selezionato Hardware; lo stesso vale per la coppia successiva, Hardware - Card, che seleziona Card ; poi, è la volta di Card - Mouse, che rientra nel caso 1, quindi selezioniamo a caso Card ; infine, Card - Software che restituisce Computer, che sarà l’argomento finale. L’esecuzione dell’algoritmo è stata schematizzata nella figura 2.6. 2.6. CATEGORIZZAZIONE DEI DOCUMENTI TRAMITE L’ONTOLOGIA Computer • Hardware – card – CompactDisk – Input – Keyboard – Monitor – Mouse – ... • Software – ComputerGraphics – Network – Programming ∗ ∗ ∗ ∗ Enviroment Logical Language Tecnique – Cookie – WebBrowser – ... Figura 2.5: Parte di struttura ad albero dell’ontologia Language Language Programming Network Monitor Hardware Card Software Computer Hardware Card Card Computer Mouse Software Figura 2.6: Esempio esecuzione algoritmo 1 9 10 CAPITOLO 2. ANALISI PROGETTUALE Capitolo 3 Sviluppo del progetto 3.1 Formato dell’input Il codice è stato eseguito e testato utilizzando input diversi. In particolare, il primo input è stato utilizzato per testare il codice sequenziale, mentre i successivi sono serviti per i test in distribuito. • File di testo da 7,9 GB Sono file ottenuti scaricando pagine html dal sito di Wikipedia, con HTTrack (paragrafo 1.1.8). Le pagine html sono state poi trasformate in formato txt utilizzando il text-based browser web Lynx, attraverso il comando: lynx -dump input.html > output.txt • Sequence File da 1,89 GB Il Sequence File è stato generato a partire da file di testo di dimensione pari a 7,9 GB. Per ogni file txt in input si crea una coppia chiave-valore, dove la chiave è il nome del file e il valore è il suo contenuto. Il codice utilizzato è: 1 2 3 4 5 6 7 8 9 10 11 12 while ( filelist . hasNext ()) { try { LocatedFileStatus file = filelist . next (); DataInputStream d = new DataInputStream ( fs . open ( file . getPath ())); BufferedReader reader = new BufferedReader ( new InputStreamReader ( d )); reader . readLine (); reader . readLine (); while (( line = reader . readLine ()) != null ){ if ( line . contains ( " </ comments > " ) || line . contains ( " </ posts > " ) || line . contains ( " </ posthistory > " )) continue ; testo = testo + line ; 13 14 } 11 12 CAPITOLO 3. SVILUPPO DEL PROGETTO 15 16 17 18 d . close (); key = new Text ( file . getPath (). getName (). toString ()); value = new Text ( testo ); writer . append ( key , value ); Listing 3.1: Generazione Sequence File per file di testo • Sequence File da circa 11 GB In questo caso il Sequence File è stato generato da file di tipo XML di dimensioni pari a circa 30 GB. Il dataset è stato reperito su http://blog.stackoverflow. com/category/cc-wikidump/ ed è una raccolta di post pubblicati dagli utenti del suddetto forum di programmazione (www.stackoverflow.com). Il dataset, una volta scaricato (20 GB compresso, 100 GB estratto), si compone di 245 archivi, ognuno dei quali contenente i seguenti 8 file .xml: – Votes.xml – Users.xml – Tags.xml – PostLinks.xml – Badges.xml – Posts.xml (Listing 3.2) – PostHistory.xml (Listing 3.3) – Comments.xml (Listing 3.4) Di questi 8 solo gli ultimi 3 sono stati presi in considerazione, in quanto i primi cinque non sarebbero stati utili al fine dei test, poiché contenti numeri ed identificativi di utenti, pagine del forum ed altre caratteristiche meno importanti. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 <?xml version="1.0" encoding="utf-8"?> <comments> <row Id="1" PostId="12" Score="2" Text="Most new functionality is provided by libraries and programming. What kind of " more things" are you talking about?" CreationDate="2014-02-11T23:12:43.420" UserId="8" /> <row Id="2" PostId="12" Score="0" Text="What TheDoctor said, what you mean by more things? Also, what are you referring to by "firmware"? The software/OS’s onboard?" CreationDate="2014-02-11T23:30:53.260" UserId="35" /> <row Id="3" ... ... ... </comments> Listing 3.2: Esempio file Comments.xml 3.1. FORMATO DELL’INPUT 1 2 3 4 5 6 7 8 9 10 11 12 13 14 13 <?xml version="1.0" encoding="utf-8"?> <posthistory> <row Id="1" PostHistoryTypeId="1" PostId="1" RevisionGUID="624e1b4f-5501-4091-a7dd-771303b26242" CreationDate="2014-04-22T17:35:44.280" UserId="14" Text="Method for creating a subquery using JDatabase" /> <row Id="2" PostHistoryTypeId="3" PostId="1" RevisionGUID="624e1b4f-5501-4091-a7dd-771303b26242" CreationDate="2014-04-22T17:35:44.280" UserId="14" Text="<mysql><jdatabase>" /> <row Id="3" ... ... ... </posthistory> Listing 3.3: Esempio file PostHistory.xml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <?xml version="1.0" encoding="utf-8"?> <posts> <row Id="1" PostTypeId="1" AcceptedAnswerId="4" CreationDate="2014-01-21T20:26:05.383" Score="13" ViewCount="62" Body="<p>I was offered a beer the other day that was reportedly made with citra hops. What are citra hops? Why should I care that my beer is made with them?</p>
" OwnerUserId="7" LastEditorUserId="8" LastEditDate="2014-01-21T22:04:34.977" LastActivityDate="2014-01-21T22:04:34.977" Title="What is a citra hop, and how does it differ from other hops?" Tags="<hops>" AnswerCount="1" CommentCount="0" /> <row Id="2" ... ... ... </posts> Listing 3.4: Esempio file Post.xml Essendo l’input più grande, per generare il Sequence File non è stato possibile utilizzare il codice precedente per un problema di heap space. Il codice è stato modificato sulla base di alcune considerazioni fatte riguardo al formato dell’input. Ogni tag row rappresenta, in base al tipo di file, un commento o un post. In questo caso la coppia chiave-valore è ottenuta utilizzando un contatore per la generazione delle chiavi e assegnando il contenuto di una linea al valore. Il codice utilizzato è: 1 2 while ( filelist . hasNext ()) { try { 14 CAPITOLO 3. SVILUPPO DEL PROGETTO 3 4 5 6 7 8 9 10 11 12 13 14 15 16 LocatedFileStatus file = filelist . next (); DataInputStream d = new DataInputStream ( fs . open ( file . getPath ())); BufferedReader reader = new BufferedReader ( new InputStreamReader ( d )); reader . readLine (); reader . readLine (); while (( line = reader . readLine ()) != null ){ if ( line . contains ( " </ comments > " ) || line . contains ( " </ posts > " ) || line . contains ( " </ posthistory > " )) continue ; value = new Text ( line ); count . set ( count . get () +1); writer . append ( count , value ); } d . close (); Listing 3.5: Generazione Sequence File per file XML • File XML da 30 GB Tale file XML è stato generato a partire dagli stessi file xml utilizzati per generare il Sequence file di 11 GB, attraverso il comando da shell cat *.xml > fileInput che concatena tutti i file in un unico file grande. 3.2 Scelta del Sequence File Hadoop è ottimizzato per lavorare con pochi file di grandi dimensioni, piuttosto che con tanti file piccoli (per ”piccoli” si intende di taglia molto inferiore rispetto a quella del blocco dell’HDFS ). Infatti, il FileInputFormat genera gli split in modo tale che ogni split è l’intero file o parte di esso. Se l’input è molto piccolo, ogni map processerà un input molto piccolo e ce ne saranno tanti quanti sono i file, aggiungendo overhead. Uno dei problemi affrontati in corso di implementazione è stato proprio il fatto di dover lavorare con tanti piccoli file (i file di testo hanno dimensione pari a pochi KB). La soluzione migliore è risultata quella di utilizzare il Sequence File di Hadoop. Tale strumento può essere visto come un contenitore per file di piccole dimensioni, consentendone così un uso più efficiente. 3.3 Ontologia Come detto nei precedenti capitoli per generare l’output finale è stata utilizzata un’ontologia. L’ontologia è stata scaricata dal sito di Protégé [6], che è un editor di ontologie, utilizzabile anche online. In particolare l’ontologia scaricata si chiama Information Science Ontology(OIS) e descrive l’ambito delle scienze in generale. Un esempio di una classe è riportata in 2.5. 3.4. IMPLEMENTAZIONE 15 Input: ”A passenger plane has crashed shortly after take-off from Kyrgyzstan’s capital, Bishkek, killing a large number of those on board” Output: A_DT passenger_NN plane_NN has_VBZ crashed_VBN shortly_RB after_IN takeoff_NN from_IN Kyrgyzstan_NNP ś_POS capital_NN ,_, Bishkek_NNP ,_, killing_VBG a_DT large_JJ number_NN of_IN those_DT on_IN board_NN ._. Figura 3.1: Esempio POS Tagger 3.4 Implementazione L’implementazione del codice si divide in due fasi. In un primo momento, è stato implementato il codice nella versione sequenziale. In seguito, sono state effettuate le scelte necessarie (Sequence File, Map/Reduce) per ottenere un codice adatto per Hadoop. 3.4.1 Sequenziale L’input del codice sequenziale è un insieme di file di testo (7,9 GB), come menzionato sopra. Per ogni file sono stati eseguiti, nell’ordine, i passi presentati nel capitolo precedente e riassunti in Figura 2.1 : • Ad ogni parola viene aggiunto un tag che identifica il suo valore sintattico, utilizzando la classe MaxentTagger della libreria Part-Of-Speech Tagger (POS Tagger) (paragrafo 1.1.4). La figura 3.1 mostra un esempio del comportamento di tale classe. 1 2 3 public class HTMLutils { public static String extractText ( String file ) throws IOException , C las sN otF ou ndE xce pt ion { 4 // Inizializza il tagger MaxentTagger tagger = new MaxentTagger ( " left3words - wsj -0 -18. tagger " ); 5 6 7 8 // Aggiunge i POS al testo String tagged = tagger . tagString ( file ); 9 10 11 return tagged ; 12 } 13 14 } Listing 3.6: Fase di Part-Of-Speech Tagger 16 CAPITOLO 3. SVILUPPO DEL PROGETTO Input: A_DT passenger_NN plane_NN has_VBZ crashed_VBN shortly_RB after_IN takeoff_NN from_IN Kyrgyzstan_NNP ś_POS capital_NN ,_, Bishkek_NNP ,_, killing_VBG a_DT large_JJ number_NN of_IN those_DT on_IN board_NN ._. Output: passeger plane crash takeoff Kyrgyzstan capital Bishkek kill large number board Figura 3.2: Esempio di utilizzo di StopWord e Stemming Per i file XML (testati però solo in distribuito) viene aggiunta prima anche una parte di parsing, utilizzando la classe Jsoup ( 1.1.7): 1 2 3 4 String line ; while (( line = file . readLine ()) != null ){ sb . append ( line ); } 5 6 7 Document document = Jsoup . parse ( sb . toString () , " " , org . jsoup . parser . Parser . xmlParser ()); 8 9 10 11 12 13 14 for ( Element e : document . select ( " row " )){ String a = e . attributes (). get ( " text " ); if ( a . isEmpty ()) a = e . attributes (). get ( " body " ); } String tagged = tagger . tagString ( a ); Listing 3.7: Parsing per file XML • Ogni parola viene analizzata: se è una stop word viene rimossa (per la definizione di stop word si faccia riferimento a 2.4), altrimenti viene applicato lo stemming. Ci sono degli appositi tag che identificano una stop word. Questi tag sono memorizzati nell’array s_stopwords. Nello specifico, per ogni parola si controlla il corrispondente tag, inserito nello step precedente. Se il tag è contenuto nell’array s_stopwords, la relativa parola viene cancellata, altrimenti si fa lo stemming, cioè la parola viene trasformata nella forma della sua radice. Inoltre, se la parola è una forma verbale di essere o avere viene eliminata. La figura 3.2 mostra con un esempio questi due step. 1 2 3 4 5 6 7 public class StopWords { private static String [] s_stopwords = { " DT " , " CD " , " CC " , " EX " , " IN " , " MD " , " PDT " , " PRP " , " PRP$ " , " RB " , " RBR " , " RBS " , " RP " , " POS " , " SYM " , " TO " , " UH " , " WP " , " WP$ " , " WRB " , " WDT " , " # " , " $ " , " \" " , " ( " , " ) " , " ," , " . " , " : " , " ’’" , " LRB " , " RRB " , " LCB " , " RCB " , " LSB " , " RSB " , " -LRB - " , "B - " , " ‘‘" , " FW " , " -RRB - " , " " , " " }; 3.4. IMPLEMENTAZIONE 17 8 private HashSet < String > stopwords ; Morphology stemmer = new Morphology (); 9 10 11 // costruttore : crea un HashSet con le stopwords public StopWords (){ stopwords = new HashSet < String >( s_stopwords . length ); for ( String stopWord : s_stopwords ){ stopwords . add ( stopWord ); } } 12 13 14 15 16 17 18 19 // restituisce true se la parola in input e ’ una stopword public boolean isStopWord ( String word ){ return stopwords . contains ( word ); } 20 21 22 23 24 // rimuove le stopword e fa lo stemming del documento dato in input public String removeStopWord ( String document ) throws FileN otFou ndExce ption { 25 26 27 28 // memorizza in un array di stringhe le singole parole del documento StringTokenizer str = new StringTokenizer ( document ); String output = " " ; 29 30 31 32 // per ogni parola , se e ’ una stopword la elimina , altrimenti // fa lo stemming e la memorizza nella stringa output while ( str . hasMoreTokens ()) { String token = str . nextToken (); if (! isStopWord ( token . split ( " / " )[1])){ WordLemmaTag lemma = stemmer . lemmatize ( stemmer . stem ( token . split ( " / " )[0] , token . split ( " / " )[1])); if (! lemma . value (). equalsIgnoreCase ( " be " ) && ! lemma . value (). equalsIgnoreCase ( " have " )) output += lemma . lemma () + " " ; } } return output ; } 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 } Listing 3.8: Fase di rimozione Stop Word e Stemming • Si calcola la frequenza delle parole e si selezionano le prime 10 con frequenza maggiore. 1 2 3 4 5 for ( int j =0; j < word . length ; j ++) { word [ j ] = word [ j ]. toLowerCase (); WordData data = words . get ( word [ j ]); if ( data == null ) 18 CAPITOLO 3. SVILUPPO DEL PROGETTO words . put ( word [ j ] , new WordData ( word [ j ]) ); else data . count ++; 6 7 8 9 } 10 11 12 13 ArrayList < WordData > wordsByFrequency = new ArrayList < WordData >( words . values ()); Collections . sort ( wordsByFrequency , new CountCompare ()); Listing 3.9: Fase di calcolo della frequenza • Le 10 parole selezionate vengono mappate nell’ontologia. A tale scopo viene utilizzato il framework Jena (paragrafo 1.1.6). Si mostra il codice dell’implementazione dell’algoritmo del paragrafo 2.6, che restituisce l’argomento che identifica il file in esame, selezionato dall’ontologia. Se l’ontologia non riesce a classificare il file, viene dato in output come argomento ”OTHER”. Un esempio del comportamento di tale algoritmo è già stato mostrato nel capitolo precedente (Figura 2.6), mentre un campione di 5 elementi prelevato casualmente dall’output è mostrato nel capitolo successivo (4.4). 1 public OntClass red uce Fi nal Co mmo nCl as s ( OntModel onto ){ 2 OntClass currentCommonClass = null ; 3 4 // per ogni classe ( fino a che non rimane una sola classe )... while ( ontClasses . size () != 1) { // prende due classi adiacenti e calcola l ’ antenato comune ... currentCommonClass = OntTools . getLCA ( onto , ontClasses . get (0) , ontClasses . get (1)); // se l ’ antenato comune corrisponde ad una delle due classi , // allora vuole dire che l ’ altra e ’ discente della classe che corrisponde // all ’ antenato . Scegliamo la classe piu ’ in basso nella discendenza if ( currentCommonClass . equals ( ontClasses . get (0))) currentCommonClass = ontClasses . get (1); else if ( currentCommonClass . equals ( ontClasses . get (1))) currentCommonClass = ontClasses . get (0); 5 6 7 8 9 10 11 12 13 14 15 16 17 18 // rimuove le due classi analizzate e aggiunge quella selezionata ontClasses . remove (0); ontClasses . remove (0); ontClasses . add ( currentCommonClass ); 19 20 21 22 } return ontClasses . get (0); 23 24 25 } Listing 3.10: Fase di categorizzazione dei documenti tramite ontologia 3.4. IMPLEMENTAZIONE 3.4.2 19 Distribuito L’implementazione del codice distribuito viene effettuata adattando il codice sequenziale al paradigma Map/Reduce. La fase di Map esegue l’intero codice, riportato sopra, poiché il carico di lavoro non può essere diviso. Di conseguenza il Reduce è stato eliminato in quanto non necessario. Il codice distribuito è stato eseguito su due input diversi. Il primo è il Sequence File da circa 2 GB, generato a partire da file di testo, per il quale il Map dà in output una coppia chiave-valore, dove la chiave è il nome del file e il valore è l’argomento. Il secondo è il Sequence File da 11 GB, generato a partire da file XML, dove l’output restituito dal Map è sempre una coppia chiave-valore: la chiave è un identificatore e il valore è l’argomento del post o del commento. Di seguito è riportato il contenuto del Mapper, per il Sequence File generato a partire da file di testo: 1 2 public void map ( Text key , Text value , Context contex ) throws IOException , InterruptedException { 3 4 5 6 try { // use the realURL to generate the outlinks String text = value . toString (). trim (); 7 String new_input = null ; 8 9 // stringa contenente l ’ intero documento // il metodo elimina i tag html String document = null ; 10 11 12 13 try { document = HTMLutils . extractText ( text ); } catch ( Cla ss Not Fo und Exc ep tio n e ) { // TODO Auto - generated catch block e . printStackTrace (); 14 15 16 17 18 19 } 20 21 22 23 // rimuove le stopwords e fa lo stamming delle parole StopWords s = new StopWords (); new_input = s . removeStopWord ( document ); 24 25 26 27 // calcolo delle frequenze TreeMap < String , WordData > words = new TreeMap < String , WordData >(); String [] word = new_input . split ( " " ); 28 29 30 31 32 33 34 35 // per ogni parola controlla se e ’ gia ’ presente in words : // - se esiste , incrementa il numero di occorrenze // - altrimenti la aggiunge for ( int j =0; j < word . length ; j ++) { word [ j ] = word [ j ]. toLowerCase (); WordData data = words . get ( word [ j ]); 20 CAPITOLO 3. SVILUPPO DEL PROGETTO if ( data == null ) words . put ( word [ j ] , new WordData ( word [ j ])); else data . count ++; 36 37 38 39 } ArrayList < WordData > wordsByFrequency = new ArrayList < WordData >( words . values ()); Collections . sort ( wordsByFrequency , new CountCompare ()); 40 41 42 43 // legge l ’ ontologia e mappa le parole chiave nelle classi dell ’ ontologia OntResource argomento = ontology . readOntology ( wordsByFrequency ); 44 45 46 // Scrive in contex la chiave e il rispettivo valore . // Se il valore e ’ Thing , il documento viene classificato come OTHER . if ( argomento . getLocalName (). equalsIgnoreCase ( " thing " )) contex . write ( key , new Text ( " OTHER " )); else contex . write ( key , new Text ( argomento . getLocalName ())); } catch ( Exception e ) { System . err . println ( value . toString (). replaceAll ( " \\ t + " , " \ t " )); e . printStackTrace (); } 47 48 49 50 51 52 53 54 55 56 } Listing 3.11: Fase di Map per il Sequence FIle di file di testo Il codice del main per il Sequence File formato da file di testo è: 1 public static void main ( String [] args ) throws Exception { 2 3 4 5 6 if ( args . length != 2) { System . out . println ( " usage : [ input ] [ output ] " ); System . exit ( -1); } 7 8 Job job = Job . getInstance ( new Configuration ()); 9 10 11 job . setMapOutputKeyClass ( Text . class ); job . set Map Ou tpu tV alu eCl as s ( Text . class ); 12 13 14 job . setOutputKeyClass ( Text . class ); job . setOutputValueClass ( Text . class ); 15 16 17 job . setMapperClass ( WordMapper . class ); job . setNumReduceTasks (0); 18 19 20 job . setInputFormatClass ( Se qu e nc eF i le In pu t Fo rm at . class ); job . setOutputFormatClass ( TextOutputFormat . class ); 21 22 23 FileInputFormat . setInputPaths ( job , new Path ( args [0])); FileOutputFormat . setOutputPath ( job , new Path ( args [1])); 24 25 26 job . setJarByClass ( WordCount . class ); job . waitForCompletion ( true ); 3.4. IMPLEMENTAZIONE 27 21 } Listing 3.12: Main codice distribuito per Sequence File di file di testo Per quanto riguarda, invece, il Sequence File generato a partire dai file XML, le modifiche riguardano solo i tipi della chiave, infatti a differenza di prima, ora la chiave è un identificatore numerico. Quindi le modifiche sono le seguenti: 1 2 3 4 public void map ( IntWritable key , Text value , Context contex ) throws IOException , InterruptedException { ... ... Listing 3.13: Modifiche fase di Map per il Sequence File di file XML 1 2 3 4 5 6 ... job . s e t M apOutputKeyClass ( IntWritable . class ); job . s e t M ap Ou tpu tVa lu eCl as s ( Text . class ); job . set OutputKeyClass ( IntWritable . class ); job . se t OutputValueClass ( Text . class ); ... Listing 3.14: Modifiche Main codice distribuito per Sequence File di file XML Tutti i codici utilizzati sono disponibili al seguente indirizzo: https://www.dropbox. com/s/02qlppic18i68k3/CodiceCaliendoCantalupo.zip?dl=0 22 CAPITOLO 3. SVILUPPO DEL PROGETTO Capitolo 4 Tests e Benchmarking 4.1 Ambiente di lavoro Il codice implementato è stato testato sulle macchine del laboratorio Reti del Dipartimento di Informatica dell’Università degli studi di Salerno, ognuna delle quali ha le seguenti caratteristiche: • Sistema Operativo: Windows 7 • CPU: Intel Celeron G530 Dual Core operante a 2.4Ghz, in grado di supportare le istruzioni Intel SSE di secondo livello • RAM: 4GB • Hardisk: 250GB Queste macchine sono collegate tra di loro mediante uno switch Ethernet da 100Mbps. Su ognuna di esse vi è istallata la macchina virtuale VMWare, con sistema operativo Ubuntu Linux 12.04 LTS con 2CPU, 3GB di RAM e Hardisk da 120 GB. Sulla macchina virtuale, a sua volta, c’è installata Hadoop 2.2.0 con Java 1.7.0.60. 4.2 Test codice sequenziale su file di testo da 7,9 GB Il codice sequenziale è stato eseguito su una delle macchine del laboratorio Reti, passando in input file di testo di dimensione totale pari a 7,9 GB. Il tempo stimato per completare l’analisi di tutti i file è di circa 80 ore (più di 3 giorni). I risultati ottenuti sono mostrati in Figura 4.1. Inoltre, é stato analizzato anche il tempo di esecuzione impiegato dall’ontologia prendendo un campione di 50 MB di file, il cui risultato è presentato in Figura 4.2. Il grafico mostra, per ogni file, la percentuale di tempo occupata dall’ultima fase dell’algoritmo, ovvero quella di categorizzazione dei documenti tramite l’ontologia. Si evince che tale fase occupa in media il 40% del tempo totale. La percentuale varia in base al numero di parole che vengono utilizzate come input per l’algoritmo 1: infatti, delle 10 parole 23 24 CAPITOLO 4. TESTS E BENCHMARKING Figura 4.1: Stima tempo codice sequenziale con frequenza maggiore, l’algoritmo utilizza effettivamente solo quelle che mappano una risorsa nell’ontologia, scartando le altre. 4.3 Test codice distribuito tramite Hadoop Per quanto riguarda il codice distribuito, esso è stato eseguito più volte cambiando l’input e modificando block size e numero di slave. • Con in input il Sequence File di 1,8 GB, sono stati eseguiti i test mostrati in Figura 4.3. • Per il Sequence File di 11 GB è stato eseguito un unico test con block size pari a 128 MB e con 32 slave. • Inoltre, è stata fatta una stima per i test con un file XML di circa 30 GB, block size pari a 128 MB e con 32 slave. Il lavoro è durato 24 ore, durante il quale è stato portato a termine solo un giro di map. I map creati erano 213. Lo scopo di tale test era quello di verificare l’efficienza della scelta del Sequence File come tipo di File Input Format. I risultati successivi riguardano i test con in input il SequenceFile da circa 2GB. 4.3. TEST CODICE DISTRIBUITO TRAMITE HADOOP Figura 4.2: Tempo impiegato dall’ontologia per 50 MB Figura 4.3: Test eseguiti 25 26 CAPITOLO 4. TESTS E BENCHMARKING RF BlockSize # Slave Tempo Totale Tempo Medio Map 2 2 2 32 64 128 16 16 16 17hrs, 40mins 17hrs, 13mins 17hrs, 20mins 4hrs, 2mins 7hrs, 45mins 14hrs, 54mins Figura 4.4: Risultati test variando block size RF BlockSize # Slave Tempo Totale Tempo Medio Map 2 2 2 32 32 32 8 16 32 36hrs, 4mins 17hrs, 40mins 8hrs, 5mins 3hrs, 58mins 4hrs, 2mins 4hrs, 1mins Figura 4.5: Scalabilità 4.3.1 Test Block Size Viene riportata ora una tabella (Figura 4.4) che mostra i tempi di esecuzione del codice distribuito utilizzando sempre 16 slave e modificando la block size. Si può notare, come previsto, che i tempi di esecuzione in tutti e tre i casi sono simili. 4.3.2 Test di scalabilità In Figura 4.5 è mostrata la tabella che riporta i risultati dei test di scalabilità. La tabella in Figura 4.6 mostra lo speedup dell’algoritmo (Figura 4.7) e l’efficienza (Figura 4.8). Lo speedup è calcolato secondo la legge di Amdahl: Sn = Ts Tn (4.a) dove • Tn = Tempo di esecuzione con Hadoop • Ts = Tempo di esecuzione sequenziale RF BlockSize # Slave Speedup Efficienza 2 2 2 32 32 32 8 16 32 2,21 4,51 9,90 0,28 0,28 0,31 Figura 4.6: Speedup - Efficienza 4.3. TEST CODICE DISTRIBUITO TRAMITE HADOOP 27 Figura 4.7: Speedup L’efficienza è ottenuta da: En = Sn n (4.b) dove • Sn = Speedup • n = Numero di CPUs totali 4.3.3 Profiling versione distribuita con 16 slave e block size 128 MB Durante le varie esecuzioni dell’algoritmo, esso è stato monitorato usando il tool Dstat, con campionamento ogni 10 secondi. L’utilizzo di tale tool non impatta molto le prestazioni del cluster, infatti, esso richiede pochissima CPU e memoria RAM. Dstat permette di visualizzare tutte le risorse di sistema (CPU, memoria, disco, ecc) in tempo reale. In particolare è stato lanciato il comando: dstat -tcmgsdn –net-packets –float –noheaders –output out-dstat.csv 10 dove: 28 CAPITOLO 4. TESTS E BENCHMARKING Figura 4.8: Efficienza • tcmgsdn: abilita rispettivamente la visualizzazione dell’ora e della data per ogni riga dell’output, le statistiche riguardanti CPU, la memoria, la paginazione (page in e page out), lo swap, il disco (numero byte letti e scritti) e la rete (numeri pacchetti inviati e ricevuti, throughput dell’host in uplink e downlink). • net-packets: mostra il numero di pacchetti ricevuti e trasmessi sulla rete. • float: serve per forzare valori in output a float. • net-noheaders: disabilita la ripetizione dell’intestazione. • output: permette il redirect dell’output di dstat in un file csv. • 10: indica il tempo di campionamento con cui vengono visualizzati i dati. Le unità di misura utilizzate nel plug-in sono mostrate in figura 4.9. Nelle successive sezioni vengono analizzati e mostrati i risultati del codice eseguito su Hadoop utilizzando 16 slave e block size pari a 128 MB. Hadoop per tale test restituisce i risultati mostrati in Figura 4.10. Sono stati creati 16 map task, poiché: 1, 89 GB = 1935, 36 MB 1935, 36/128 = 15, 12 → 16 map task Questo test è stato eseguito in circa 17 ore e 20 minuti. Durante l’esecuzione sono stati completati correttamente, quindi, 16 map task, ma in totale ne sono stati lanciati 17, poiché un map task è stato ”ucciso” (killed ) dal framework. 4.3. TEST CODICE DISTRIBUITO TRAMITE HADOOP 29 Figura 4.9: Unità di misura La CPU totale spesa ammonta a circa 246 ore (888917370 ms). Dei 17 map task lanciati, 12 sono datalocal map task, cioè circa il 70,6% dei lanciati. 4.3.3.1 Uso CPU Il grafico in figura 4.11 mostra la percentuale media di CPU usata da tutti gli slave. Dal grafico si evince che la CPU non è sfruttata al massimo, infatti gli slave fanno un utilizzo del 50%. Poiché ogni slave ha 2 CPU, questo significa che ogni slave ne usa una sola. Inoltre, si può notare che gli slave eseguono tutti un unico Map impiegando circa 16h, eccetto uno slave che, dopo il primo Map, ne esegue un altro di dimensione inferiore impiegando circa 2h. La differenza tra quest’ultimo slave e gli altri, prendendo in considerazione un slave a caso, è mostrata in figura 4.12: 4.3.3.2 Uso Memoria Il grafico 4.13 mostra un forte utilizzo di RAM (con un picco massimo di circa 3000 MB) da parte del master. Per quanto riguarda gli slave si ripete la stessa situazione dell’utilizzo della CPU, infatti tutti gli slave eseguono un Map usando in media 1700 MB, mentre un unico slave ne segue due, dove il secondo, essendo più piccolo, richiede meno memoria (circa 700 MB) (Figura 4.14 ). Anche in questo caso si può notare che la RAM non è stata sfruttata al massimo, quindi si è cercato di sfruttarla interamente eseguendo 2 Map Task su ogni computer, ma il carico di lavoro risultava eccessivo tanto che gli slave non riuscivano a portare a termine il loro compito. 30 CAPITOLO 4. TESTS E BENCHMARKING File System Counters FILE: Number of bytes read=0 FILE: Number of bytes written=1274668 FILE: Number of read operations=0 FILE: Number of large read operations=0 FILE: Number of write operations=0 HDFS: Number of bytes read=2030229527 HDFS: Number of bytes written=4495259 HDFS: Number of read operations=96 HDFS: Number of large read operations=0 HDFS: Number of write operations=32 Job Counters Killed map tasks=1 Launched map tasks=17 Datalocal map tasks=12 Racklocal map tasks=5 Total time spent by all maps in occupied slots (ms)=1731463294 Total time spent by all reduces in occupied slots (ms)=0 MapReduce Framework Map input records=119115 Map output records=113903 Input split bytes=1728 Spilled Records=0 Failed Shuffles=0 Merged Map outputs=0 GC time elapsed (ms)=30669812 CPU time spent (ms)=888917370 Physical memory (bytes) snapshot=19490893824 Virtual memory (bytes) snapshot=31082086400 Total committed heap usage (bytes)=16700669952 File Input Format Counters Bytes Read=2030227799 File Output Format Counters Bytes Written=4495259 Figura 4.10: Risultati di Hadoop su test con block size = 128 MB e slave = 16 4.3. TEST CODICE DISTRIBUITO TRAMITE HADOOP 31 Figura 4.11: Uso medio CPU - Tutti gli slave 4.3.3.3 Lettura Disco I grafici in 4.15 e 4.16 mostrano la lettura del disco durante l’esecuzione dell’algoritmo. Si evince che ci sono poche letture dati da parte di tutti gli slave; anche per il master le letture sono poche eccetto per alcuni picchi. Comportamento atteso in quanto le letture locali sono limitate solo ad operazioni per il recupero temporaneo di alcune informazioni necessarie per il programma. I dati da esaminare si trovano in HDFS. 4.3.3.4 Scrittura Disco Per la scrittura del disco vale un discorso analogo a quello della lettura. I risultati sono riportati in 4.17 e in 4.18. 4.3.3.5 Pacchetti reti inviati/ricevuti Le Figure 4.19 e 4.20 mostrano rispettivamente i pacchetti rete inviati e quelli ricevuti, sia per il master che per tutti gli slave in media. 4.3.3.6 Throughput di rete Le Figure 4.21 e 4.22 mostrano rispettivamente ii throughput di rete per i pacchetti inviati e per quelli ricevuti, sia per il master che per tutti gli slave in media. 32 CAPITOLO 4. TESTS E BENCHMARKING Figura 4.12: Uso CPU - Differenza tra Slave 1 e Slave 15 4.3. TEST CODICE DISTRIBUITO TRAMITE HADOOP 33 Figura 4.13: Uso medio memoria 4.3.3.7 State Slave Il grafico in Figura 4.23 mostra i map task eseguiti su ogni nodo. Ogni slave ha un unico map task, eccetto l’ultimo che ne esegue due, di cui, come detto sopra, il secondo task elabora meno dati e per questo è più breve. Si può notare che c’è un unico map task killed, 0 falliti e i restanti sono tutti completati. Tutti i map task iniziano quasi contemporaneamente. Però tale grafico non permette di veder bene il funzionamento dei map task in quanto ogni slave ha un unico map task. Per mostrare meglio tale meccanismo viene riportato un altro grafico relativo ad un test che esegue più di un map task per ogni slave: test con block size pari a 32 MB utilizzando 8 slave. (Figura 4.24 ). 4.3.4 Test distribuito su SequenceFile da 11 GB Il test è stato eseguito sul SequenceFile di circa 11 GB, generato a partire dai file XML (come descritto in 3.1). Per tale test sono stati utilizzati 32 slave e block size di default (128 MB). La durata totale del test è stata di 55h, 43min, 59sec e ogni slave ha lavorato in media 17hr e 6min. I map lanciati sono stati 88, ma quelli effettivamente eseguiti 87 (1 è stato ”ucciso” (killed )). Infatti: 10, 87 GB = 11130, 88 MB 11130, 88/128 = 86, 96 → 87 map task 34 CAPITOLO 4. TESTS E BENCHMARKING Figura 4.14: Uso memoria - Differenza tra Slave 1 e Slave 15 4.3. TEST CODICE DISTRIBUITO TRAMITE HADOOP Figura 4.15: Lettura media disco Figura 4.16: Lettura disco - Slave 35 36 CAPITOLO 4. TESTS E BENCHMARKING Figura 4.17: Scrittura media disco Figura 4.18: Scrittura disco - Uno slave 4.3. TEST CODICE DISTRIBUITO TRAMITE HADOOP Figura 4.19: Media pacchetti di rete inviati Figura 4.20: Media pacchetti di rete ricevuti 37 38 CAPITOLO 4. TESTS E BENCHMARKING Figura 4.21: Media throughput di rete inviati Figura 4.22: Media throughput di rete ricevuti 4.3. TEST CODICE DISTRIBUITO TRAMITE HADOOP Figura 4.23: Stato MapSlave - BlockSize 128 MB, 16 slave Figura 4.24: Stato MapSlave - BlockSize 32 MB, 8 slave 39 40 CAPITOLO 4. TESTS E BENCHMARKING Figura 4.25: Stato MapSlave SequenceFile 11GB - BlockSize 128 MB, 32 slave Si riporta, per questo test, lo stato di esecuzione degli slave, in Figura 4.25. Anche in questo caso, i map task cominciano tutti contemporaneamente; tutti gli slave lavorano e ognuno esegue più di un map task. Come si può notare però, rispetto ai test precedenti, la durata dell’esecuzione di ogni map task varia in modo considerevole. La causa di tale comportamento potrebbe essere il tipo di input, ma è solo un’ipotesi, in quanto non si hanno a disposizioni strumenti che permettano di dare spiegazioni più precise alla questione. 4.4 Esempio output La seguente tabella mostra l’output per cinque file presi a caso, per i test effettuati sui file txt che, come mostrato in precedenza, sono stati generati a partire da pagine web. Il nome del file corrisponde al nome della pagina web, e può quindi essere un punto di riferimento per verificare l’esattezza dei risultati: 4.4. ESEMPIO OUTPUT 41 NomeFile Output Evolutionary origin of religions.txt Domain name.txt Category programming language designers.txt Religion in ancient greece.txt Commodore 64.txt SocialScience Internet Practice OTHER Computer Figura 4.26: Esempio output 42 CAPITOLO 4. TESTS E BENCHMARKING Capitolo 5 Conclusioni Lo sviluppo di tale progetto è stato molto interessante in quanto ha permesso di affrontare problematiche attuali: l’implementazione di Web Sematico e la programmazione distribuita con Hadoop. Lavorare, sfruttando i vantaggi offerti dalla programmazione distribuita, ha portato, come previsto, ad avere una notevole differenza tra il tempo di esecuzione del codice sequenziale e quello del codice distribuito. La maggiore difficoltà affrontata nello sviluppo del progetto è stata quella di reperire un input di grandi dimensioni per i test. Per analizzare le performance del web semantico si richiede l’utilizzo di pagine html, ma non essendoci disponibilità di un dataset di pagine web già pronto, si è dovuto provvedere a crearlo, scaricando le pagine, operazione che ha richiesto molto tempo (giorni). Quindi resta aperta la questione di testare il codice su un dataset di grande dimensione (molti GB). Per quanto riguarda il tipo di input per Hadoop, si è scelto di usare il SequenceFile per fruttare al meglio il paradigma MapReduce. Oltre ad Hadoop, un altro strumento interessante è stato l’uso dell’ontologia, la quale ha influito molto sul risultato finale, sia dell’output che del tempo richiesto. Infatti l’argomento finale viene fornito dall’ontologia, in base ad una lista di parole passate in input, ed occupa circa il 40% del tempo totale. Quindi la bontà dell’output dipende dalla struttura dell’ontologia, mentre la durata dell’esecuzione dipende dalla sua taglia. 43 44 CAPITOLO 5. CONCLUSIONI Bibliografia [1] Hajiabadi, Hajiabadi, H.Tabaraie (2011), Extracting Specific Categories of Text Documents Using Ontology, International Conference on Computer Applications and Industrial Electronics (ICCAIE 2011). [2] Song, Lim, Kang, Lee (2005), Automatic Classification of Web Pages based on the Concept of Domain Ontology, Proceedings of the 12th Asia-Pacific Software Engineering Conference (APSEC’05). [3] HTTrack, a free (GPL, libre/free software) and easy-to-use offline browser utility. http://www.httrack.com [4] Stanford University, Stanford Log-linear Part-Of-Speech Tagger, The Stanford Natural Language Processing Group, http://nlp.stanford.edu/software/tagger. shtml. [5] Apache Jena, a free and open source Java framework for building Semantic Web and Linked Data applications. https://jena.apache.org [6] Stanford University, Protégé, a free, open-source ontology editor and framework for building intelligent systems. http://protege.stanford.edu 45