Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
vuoi
o PayPal
tutte le volte che vuoi
SQL.
Supponiamo di avere uno “use case” in cui una grande mole di dati vecchi viene
acceduta poco frequentemente, mentre una quantità modesta di dati nuovi viene
acceduta molto spesso.
Nei sistemi Big Data si gestiscono diversi tipi di dati ed è quindi comune usare diversi
tipi di Storage, per questo possiamo usare PostgreSQL per la gestione di dati
(dinamici) recenti e spostare i dati vecchi in
sistemi di storage per dati (statici) di grandi dimensioni, come Apache Parquet.
Il processing può essere suddiviso in due parti: batch processing e streaming
processing. modello batch
Il è quello più tradizionale, dove
i miei dati di input vengono spezzettati in
“fette” e ragiono indipendentemente su
ciascuna fetta, portando quindi ad una
semplificazione del modello di processing.
Lo svantaggio è che non è real-time, ho una
visione limitata in base all’intervallo di tempo
del batch.
Posso assegnare anche ciascun pezzo ad una macchina singola, riassemblando
successivamente il risultato finale.
Adatto nel momento in cui ho una grande mole di dati.
Lavoro con processamenti periodici, quindi colleziono dati fino a quando non
raggiungo la dimensione del batch, dopodiché scateno l’evento di processamento.
streaming
Il secondo modello è quello , dove interpreto il flusso di input come un
dataset illimitato, processando i vari record che arrivano di volta in volta, con
granularità fine.
Il vantaggio è che ho bassa latenza e posso lavorare in real-time, ma ragionando sul
singolo record ho problema nell’implementare, ad esempio, analisi delle analytics.
Si sottolinea inoltre che i dati sono disordinati e che devono essere processati sulla
base del timestamp della sorgente, che possono essere in realtà molteplici e la loro
gestione rallenta il sistema di processing stesso.
È auspicabile un processamento exactly-once, ma difficoltoso per ciò che è detto
prima, senza contatore la possibilità di perdita dei messaggi.
Per risolvere questi problemi, il processamento streaming deve mantenere lo stato
delle varie fasi e degli eventi, dovendosi appoggiare a tecnologie per mantenere
salvato il proprio stato.
Esiste una distinzione tra event-time e processing-time:
event-time
- indica il momento in cui l’evento effettivamente accade, impostato
alla sorgente
processing-time
- indica il momento in cui l’evento viene ricevuto dai sistemi di
elaborazione
Non tutti supportano un processamento event-time, ma tutti supportano il secondo
tipo. micro-batch
Esiste anche una terza categoria, il , un trade-off tra le due categorie
precedenti, in cui si usano piccoli batch elaborati a piccoli intervalli, bilanciando
throughput e latenza.
Per i sistemi streaming, abbiamo strumenti di data processing come Apachi Storm o
Flink, per i sistemi batch MapReduce e Spark, infine per i micro-batch possiamo avere
Spark Streaming. MapReduce è un modello di ispirato alle funzioni
MAP e REDUCE della programmazione funzionale.
Si definisce una funzione MAP, che esegue del
processamento su dati key/value generando un
insieme di risultati sempre key/value,
ed una funzione REDUCE per fare il merging dei
risultati intermedi.
È presente anche una fase di shuffle con cui
ridistribuire i dati appartenenti alla stessa chiave.
I programmi così definiti sono altamente parallelizzabili.
input reader
- , il quale divide l’input in chunk che vengono assegnati ad una
singola funzione map
funzione map
- è una funzione che mappa i dati di ingresso in coppie chiave-
valore più piccole per processamento intermedio
funzione partition
- con cui trovare il reducer appropriato data la chiave (solo
se sono più di uno)
funzione compare
- , con cui ordinare i dati in modo opportuno per la funzione
reduce
funzione reduce
- , la quale prende i valori intermedi uno per uno e li processa
per la creazione di una soluzione parziale restituita al framework
output writer
- , con il quale scrivo i risultati su file di output
Hadoop è un’implementazione open source di Google File System e di MapReduce,
nato inizialmente con solo MapReduce e HDFS, per poi aggiungersi il resource
manager YARN e altri framework di processing.
In particolare, i clienti effettuano delle “submission” di jobs di processing, essendo in
ambito batch, e il componente “resource manager” mapperà queste richieste sui vari
nodi che ho a disposizione.
Tra i limiti troviamo il supporto al solo processamento batch, con tempi di
processamento elevati, difficile implementare algoritmi complessi e iterativi ed è
pensato per processamenti stateless (difficile per stateful).
Date le scarse performance di Hadoop, dal momento che ci si focalizzava Apache
maggiormente sulla fault tolerance, sono nate soluzioni alternative come
Spark .
Un grosso problema di MapReduce era la scrittura su disco in diverse fasi
dell’algoritmo, con aumento della latenza, e ogni passaggio corrispondenza ad un Job
MapReduce, per cui i dati dovevano essere caricati da 0.
Per superare queste limitazioni, i dati vengono tenuti in memoria finché posso,
riducendo quindi l’I/O su disco ed effettuo meno passaggi sui dati.
Al di sopra del cuore di spark ho diverse API con cui interfacciarmi a diversi servizi, ad
esempio ottenere i dati ragionando in termini di linguaggio SQL, è presente una
libreria di machine learning, una di graph processing e infine spark-streaming per il
processamento in mini-batch.
In particolare, tra le API di alto livello troviamo quella dei DataFrame, dove i dati
possono essere organizzati in righe/colonne, permettendo la distribuzione su più
macchine.
Non opero più in termini di Map e Reduce, ma in forma tabellare, potendo individuare
le colonne di mio interesse e su cui posso poi effettuare operazioni di filtering per
essere ancora più selettivo.
MLib è la libreria di ML di Spark, con l’obbiettivo di facilitare l’implementazione di ML
scalabili e distribuiti.
Ho algoritmi di regressione, classificazione e clustering su larga scala, così come
estrazione delle features. All’interno dell’architettura di Apache
Spark troviamo il Cluster Manager, il
quale gestisce e coordinate
l’esecuzione dei task nel cluster di
calcolo (kubernetis), e le applicazioni in
cui risiede un driver process che
eseguono sul nodo cluster, mantenendo
le informazioni sull’applicazione,
rispondendo agli input dell’utente e
analizzando e distribuendo il lavoro sugli executors.
Esistono diversi tipi di cluster, ad esempio la modalità standalone, la quale è
relativamente semplice da usare e per infrastrutture più semplici è sufficiente,
altrimenti kubernetis.
Abbiamo anche API di basso livello basato su i Resilient Distributed Dataset (RDD), una
raccolta di elementi partizionati tra i vari nodi, immutabili e su cui posso operare in
parallelo.
Nei sistemi di streaming devo avere la capacità di mantenere uno stato tra i vari
eventi e fare attenzione all’ordinamento dei dati in ingresso sulla base del timestamp
della sorgente (molto complicato).
Apachi Flink è l’equivalente di Spark per i sistemi streaming, cioè un framework e
motore di elaborazioni per calcoli stateful su dati limitati (bounded) e soprattuto
illimitati (unbounded).
È progettato per funzionare negli ambienti di cluster più comuni, come kubernetis,
eseguendo calcoli in memoria ad altissima velocità.
Ho diverse tipologie di applicazioni, con dati in ingresso transazionali, logs o IoT, sia in
real-time sia da DB.
Sono presenti diverse tipologie di applicazioni, come event-driver, streaming pipelines
e streaming analytics.
Nelle applicazioni Event-driver, rispetto alle applicazioni transazionali tradizionali, ho
degli event-log che vengono posti in ingresso a Flink e processati sulla base dello stato
precedente, portando alla scrittura di un altro event log, oppure il triggering di una
action sulla base del decision making (es. sono sotto la soglia).
Sia in ingresso sia in uscita è spesso usata Kafka per la gestione dei log.
Per quanto riguarda l’analisi streaming, come detto prima, abbiamo latenza inferiore,
non abbiamo la necessità di gestire il partizionamento dei dati di input, a volte
“artificioso”, e si ha architettura più semplice.
Flink fornisce diverse funzioni per la gestione dello stato in base al pattern di accesso
all’applicazione:
molteplici primitive di stato
- , con diverse strutture dati (dati atomici, elenchi,
mappe…)
pluggable state backend
- , cioè ci sono diversi backend (DB) che memorizzano
lo stato in memoria
consistenza dello stato exactly-once
- stato molto grande
- , anche di diversi TB
applicazioni scalabili
- , ridistribuendo lo stato a più o meno lavoratori
Per la gestione del tempo, Flink offre diverse funzionalità:
- modalità event-time
supporto watermark
- , cioè si usa il meccanismo del watermark, cioè delle
condizioni di esclusione dei messaggi, al fine di realizzare applicazioni real-time
flessibili
late data handling
- , con cui gestire eventi in ritardo, cioè dopo il termine del
watermark, come aggiornare i risultati completati in precedenza, oppure
reindirizzarli su uscite secondarie.
Il watermark l’intervallo massimo per cui sono disposto ad aspettare per
processare un messaggio.
Modalità processing time
- , per applicazioni con requisiti rigorosi di bassa
latenza, che possono tollerare risultati approssimativi (modalità non
desiderabile)
Rispetto ad Apachi Spark, Flink ha tre livelli di API con diversi livelli di concisione ed
espressività.
Partendo da quella di alto livello, ho una API relazionale basata su SQL, progettate per
facilitare la definizione di data analytics e data pipeling, seguono API di livello
intermedio in cui ragiono con DataStream per streaming e batch data processing, con
operazioni come il windowing, e infine ho una API di basso livello, che ragiona in
termini di stato, eventi e tempo, con un controllo molto granulare, con una maggiore
flessibilità di decidere come gestire lo stato, a discapito di codici molto più lunghi.
Nell’ecosistema di flink troviamo libreria che implementano soluzioni di ML, come Flink
ML, oppure Flink Table Store per creare tabelle dinamiche per lo streaming e
l’elaborazione in batch.
Kafka Stream è una libreria Java per il processing streaming strettamente legata a
kafka.
Essa usa lo stesso modello di partizionamento di kafka per scalare il processing
orizzontalmente e supporta la semantica