• Non ci sono risultati.

2.7 Apache Cassandra

2.8.3 Query Model

L’azienda MongoDB ha sviluppato una serie di driver per renderlo interrogabile con i principali linguaggi e framework di programmazione come Java, Scala, Python, PHP, Javascript e NodeJS.

Il linguaggio di interrogazione è completamente diverso dal classico SQL utilizzato nei database relazionali, in questo caso il linguaggio nativo di interrogazione è molto simile a Javascript, data la grande affinità tra il data-model e il formato JSON.

Oltre ai driver per i vari linguaggi di programmazione è possibile interagire con MongoDB direttamente dalla shell di sistema eseguendo il comando “mongo”; se ci si vuole connettere su una specifica porta o indirizzo IP, si può impostare l’host e la porta come parametri opzionali. La shell utilizza il linguaggio Javascript per poter interagire con il database.

MongoDB supporta in maniera abbastanza efficace le “CRUD operations”, cioè le oper- azioni di creazione, aggiornamento, cancellazione e ricerca dei documenti.

Per quanto riguarda la realizzazione delle collezioni si può utilizzare il comando db.createCollection(...) specificando le opzioni richieste, oppure se si va ad inserire un qualche documento in una

collezione non esistente, questa viene creata in automatico con i parametri di default. Invece l’inserimento dei documenti, a partire dalla versione 3.2, si può effettuare con tre comandi differenti, come mostrato in figura 2.23:

• db.collection.insert() • db.collection.insertOne() • db.collection.insertMany()

Fig. 2.23 Insert operation

Il primo metodo permette di inserire uno o più documenti all’interno della collezione selezionata: per inserirne solo uno bisogna passare un singolo documento come parametro altrimenti, se ne vogliono inserire molti, una lista di documenti. In aggiunta a questo metodo, nell’ultima versione, ne sono stati inseriti altri due che permettono di inserire uno o più documenti all’interno della collezione.

Analogamente, sono implementati anche i metodi gestiscono le operazioni di update sui documenti; questi sono:

• db.collection.update() • db.collection.updateOne() • db.collection.updateMany() • db.collection.replaceOne()

Fig. 2.24 Update operation Tutte queste operazioni, richiedono 3 documenti in input:

• nel primo (update criteria) vengono indicati i filtri per ricercare quali dei documenti sono da aggiornare. Inoltre, si possono utilizzare una serie di operatori logici e non che permettono di concatenare più restrizioni e/o aggiungere condizioni specifiche sui singoli campi.

{ <field1>: <value1>, ... }

{ <field1>: { <operator1>: <value1> }, ... }

• nel secondo (update action), invece, sono indicati quali campi dei documenti devono essere modificati

• nel terzo (update option), infine, si possono specificare alcuni parametri opzionali per l’esecuzione dell’operazione di update. In particolare si può specificare se effettuare questa operazione come upsert oppure no: di default non viene eseguita come upsert. In pratica, se tale opzione è impostata a true, viene ricercato il / i documento/i che soddisfano le condizioni richieste, se ne viene trovato almeno uno vengono modificati i campi richiesti altrimenti viene inserito un nuovo documento in cui sono definiti solo i parametri impostati nell’update action.

A seconda dell’operazione scelta e dei parametri impostati, si può aggiornare uno o più documenti che soddisfano le condizioni impostate; le operazioni updateOne, replaceOne e update modificano, di default, solamente un singolo documento, mentre updateMany e update, con l’opzione “multi”, modificano tutti quelli che soddisfano le condizioni richieste.

Le operazioni che gestiscono la cancellazione di uno più documenti in una collezione sono:

• db.collection.remove() • db.collection.deleteOne() • db.collection.deleteMany()

Fig. 2.25 Remove operation

La prima, come per le operazioni precedenti, permette di eliminare uno o tutti i documenti che soddisfano le richieste. DeleteOne() ne cancella solamente uno mentre deleteMany() elimina tutti quelli che soddisfano i parametri. Tutti e tre i metodi necessitano, quindi, di un documento in input in cui sono specificati i criteri per identificare quali o quale documento è da cancellare; questo criterio è analogo a quello di update nelle precedenti operazioni.

Tutte queste tre operazioni, che possono essere incluse nell’insieme delle “write oper- ations”, possono essere gestite anche attraverso le bulkOperation. In pratica, MongoDB permette di eseguire, per le operazioni di scrittura, delle operazioni in blocco, queste però devono incidere tutte sulla medesima collezione. Il blocco delle operazioni può essere ordinato o non ordinato e può contenere operazioni miste del tipo insertOne, updateOne, updateMany, replaceOne, deleteOne e deleteMany. Ogni operazione viene aggiunta allo stack come un nuovo documento in cui la chiave è il tipo di operazione e il valore contiene i parametri dell’operazione. Ad esempio:

db . c h a r a c t e r s . b u l k W r i t e ( [ { i n s e r t O n e : { "document" : { "_id" : 4 , " char " : " D i t h r a s ", " c l a s s " : " b a r b a r i a n ", " l v l " : 4 } }

} ,

{ i n s e r t O n e : {

"document" : {

"_id" : 5 , " char " : " Taeln ", " c l a s s " :

" f i g h t e r ", " l v l " : 3 } } } , { updateOne : { " f i l t e r " : { " char " : " Eldon " } , " update " : { $ s e t : { " s t a t u s " : " C r i t i c a l I n j u r y " } } } } , { deleteOne : { " f i l t e r " : { " char " : " B r i s b a n e "} } } , { replaceOne : { " f i l t e r " : { " char " : " Meldane " } , " r e p l a c e m e n t " : { " char " : "Tanys", " c l a s s " : " o r a c l e ", " l v l " : 4 } } } ] ) ;

Particolarmente importanti sono le operazioni di ricerca e i metodi per trovare dei documenti all’interno delle collezioni sono:

• db.collection.findOne() • db.collection.find()

Il primo permette di trovare un singolo documento mentre il secondo un insieme di documenti che soddisfano determinati criteri di ricerca(query criteria) passati come parametro di input; se non viene specificato nulla vengono ritornati tutti i documenti della collezione.

Inoltre questa operazione ha un secondo parametro opzionale (projection) che permette di filtrare i campi dei documenti che si vogliono avere nel risultato della ricerca. Il parametro che identifica le condizioni della ricerca è analogo a quello che definisce i criteri di update e delete nelle operazioni precedenti. Qui si può specificare un documento contenente, nella forma chiave valore, le condizioni di ricerca da rispettare. Gli operatori che si possono inserire per definire tali condizioni sono molteplici ed includono tutti gli operatori logici, matematici e altri più specifici per effettuare ricerche all’interno di array, ricerche geospaziali, testuali e di range; questi a loro volta possono essere poi concatenati e annidati a piacimento per poter rispondere al meglio ai requisiti della ricerca.

Peraltro, MongoDB ha implementato al suo interno un Aggregation Framework attraverso il quale è possibile effettuare una grande quantità di operazioni di aggregazione. Il framework è modellato secondo il concetto del “data processing pipelines”, in sostanza , i documenti sono inseriti in una serie di operazioni che li trasformano e filtrano in maniera sequenziale fino ad ottenere il risultato aggregato; questo framework vuole essere un’alternativa al map-reduce.

Fig. 2.26 Aggregation Framework

La pipeline di base di queste tipologie di query è composta da un primo step in cui vengono filtrati i documenti secondo una serie di criteri di ricerca e un secondo step in cui vengono trasformati opportunamente per ottenere il risultato richiesto. Tuttavia, si possono creare anche pipeline più complesse in cui inserire step intermedi con operazioni di grouping,

sorting, projection su uno o più campi dei documenti e altre relative alla gestione, ricerca sugli array contenuti nei documenti. L’elenco completo degli stages che si possono inserire nella pipeline sono quelli mostrati nella tabella 2.27.

Gli stages vengono eseguiti in maniera sequenziale, dal primo all’ultimo, e ciascuno di essi può apparire anche più d’una volta all’interno della pipeline. Alcuni necessitano di una o più pipeline expression in cui sono definite le trasformazioni da effettuare sui documenti. Queste espressioni operano solo sui documenti correnti, ovvero quelli ottenuti negli step precedenti ed operano le trasformazioni in memoria.

Infine, dato che l’operazione aggregate() esegue gli step di aggregazione appena descritti andando in full scan sull’intera collezione, per velocizzare le operazioni, i costrutti matchesort possono trarre un vantaggio dagli indici solo quando questi sono posti all’inizio della pipeline.

Fig. 2.28 Map Reduce Framework

In MongoDB è implementato un comando che permette di effettuare delle operazioni di map-reduce sulle collezioni dei database. In tale operazione, MongoDB applica una fase di map su ogni documento in input, la funzione di map emette una coppia key-value e per quelle chiavi che contengono più di un valore è implementabile un’operazione di reduce in cui aggregare tali valori. Una volta eseguito anche lo step di reduce, vengono salvati i risultati nella collezione corrente oppure in una nuova; le funzioni di map-reduce, per quanto riguarda quelle implementate nella shell, sono scritte in linguaggio Javascript.

Big Data al servizio delle energie

rinnovabili

In questo capitolo verrà descritto il progetto associato a questa tesi. Questo è stato realizzato presso l’azienda Data Reply, durante lo svolgimento dello stage.

Nella prima sezione del capitolo c’è una panoramica sulle finalità, nella seconda l’architettura del sistema e una descrizione dell’ambiente in cui è stato implementato e testato il progetto. Nel capitolo successivo, invece, una spiegazione dettagliata del data model e dei flussi im- plementati. In questa, per ogni flusso, verranno esposte le scelte implementative, i risultati delle performance ottenuti e i test effettuati per poter identificare la soluzione migliore o la combinazione di parametri ottimali per le operazioni di scrittura.

Infine, nell’ultimo capitolo ci sarà il confronto tra le performance dei flussi gestiti con Cassandra e quelli gestiti con MongoDB; per ognuno di essi verranno considerate solo le soluzioni migliori.

3.1

Obiettivo

Il progetto sviluppato tratta la gestione del processo di ETL (Extract - Transform - Load) per più tipologie di flussi di dati. Il processo è stato implementato sia in modalità batch, sia in modalità real-time utilizzando due diversi database noSQL (Cassandra e MongoDB), per poterne confrontare le performance.

Il progetto è un’applicazione creata per un’azienda cliente nell’ambito delle Energy Renewable, e in particolare tratta della gestione del flusso delle informazioni provenienti dai

vari sensori dei device degli impianti dislocati in tutto il mondo. L’obiettivo è stato quello di migliorare l’implementazione di un’architettura già presente, andando a re-implementare i processi di ETL, streaming e batch, e modificare, ove possibile, anche alcune strutture nel data model; questo perchè quelli precedenti avevano una serie problemi di performance legati alla velocità di trasformazione e caricamento dei dati, soprattutto nella modalità real-time.

Documenti correlati