You are on page 1of 62

Razvojni okviri za analizu tokova podataka

Grbavac, Oliver

Master's thesis / Diplomski rad

2021

Degree Grantor / Ustanova koja je dodijelila akademski / stručni stupanj: University of


Zagreb, Faculty of Organization and Informatics / Sveučilište u Zagrebu, Fakultet
organizacije i informatike

Permanent link / Trajna poveznica: https://urn.nsk.hr/urn:nbn:hr:211:280332

Rights / Prava: Attribution-ShareAlike 3.0 Unported

Download date / Datum preuzimanja: 2021-05-12

Repository / Repozitorij:

Faculty of Organization and Informatics - Digital


Repository
SVEUČILIŠTE U ZAGREBU
FAKULTET ORGANIZACIJE I INFORMATIKE
VARAŽDIN

Oliver Grbavac

Razvojni okviri za analizu tokova


podataka

DIPLOMSKI RAD

Varaždin, 2021.
SVEUČILIŠTE U ZAGREBU

FAKULTET ORGANIZACIJE I INFORMATIKE

VARAŽDIN

Oliver Grbavac

Studij: Organizacija poslovnih sustava

RAZVOJNI OKVIRI ZA ANALIZU TOKOVA PODATAKA

DIPLOMSKI RAD

Mentor/Mentorica:

Prof. dr. sc. Kornelije Rabuzin

Varaždin, siječanj 2021.


Oliver Grbavac

Izjava o izvornosti

Izjavljujem da je moj završni/diplomski rad izvorni rezultat mojeg rada te da se u izradi istoga
nisam koristio drugim izvorima osim onima koji su u njemu navedeni. Za izradu rada su
korištene etički prikladne i prihvatljive metode i tehnike rada.

Autor/Autorica potvrdio/potvrdila prihvaćanjem odredbi u sustavu FOI-radovi

_______________________________________________________________________
Sažetak

S rastućim trendovima na područjima analitike i velike količine podataka javile su se i


potrebe za tehnologijama koje omogućuju procesiranje velikih količina podataka. U ovom
radu obraditi će se razvojni okviri koji omogućuju analizu tokova podataka. Kroz teoretski i
praktični pristup analizirati će se primjena razvojnih okvira poput Apache Flink, Apache
Spark, itd. U teorijskom dijelu analiziraju se mogućnosti i performanse, a u praktičnom dijelu
se uspoređuju razvojni okviri na realnom skupu podataka.

Ključne riječi: Big Data, razvojni okviri, analiza, Apache Spark, Apache Flink
Sadržaj
1. Uvod ......................................................................................................................... 1
2. Veliki podaci (Big Data) ............................................................................................. 2
2.1. Analiza podataka u realnom vremenu ........................................................................... 2
2.2. Povijesni razvoj okvira za analizu podataka ................................................................... 3
3. Apache Spark ............................................................................................................ 4
3.1. Osnovni koncepti i arhitektura...................................................................................... 4
3.1.1. Spark klaster i sustav upravljanja resursima ................................................................................... 4
3.1.2. Spark aplikacija ................................................................................................................................ 5
3.1.3. Spark driver i izvršitelj ..................................................................................................................... 5
3.1.3.1. Hadoop distribuirani datotečni sustav (HDFS) i MapReduce ................................................. 6
3.1.4. Spark elementi ................................................................................................................................ 6
3.2. Otporni distribuirani skup podataka ............................................................................. 8
3.3. Primjer: Algoritam za prikaz i predikciju broja zaraženih i umrlih od koronavirusa u RH .. 9
3.3.1. Instalacija i konfiguracija Apache Spark-a ....................................................................................... 9
3.3.2. Određivanje putanje i kreiranje Spark konteksta .......................................................................... 13
3.3.3. Kreiranje SQL konteksta, učitavanje podataka .............................................................................. 14
3.3.4. Grafički prikaz umrlih, zaraženih i aktivnih slučajeva u RH ........................................................... 17
3.3.5. „Machine Learning“ algoritmi u Apache Sparku ........................................................................... 23
3.3.5.1. Linearna regresija ................................................................................................................ 24
3.3.5.2. Predikcija broja umrlih u RH pomoću linearne regresije ..................................................... 26

4. Apache Flink ............................................................................................................ 31


4.1. Apache Flink Ekosustav .............................................................................................. 31
4.1.1. Skladištenje (engl. Storage/Streaming) ......................................................................................... 32
4.1.2. Razvojno okruženje (engl. Deploy) ................................................................................................ 32
4.1.3. Jezgra (engl. Kernel) ...................................................................................................................... 32
4.1.4. Aplikacijsko programsko sučelje i datotečne knjižnice ................................................................. 32
4.2. Apache Flink Arhitektura ............................................................................................ 33
4.3. Tokovi podataka u Apache Flink-u .............................................................................. 34
4.3.1. Prozori (engl. Windows) ................................................................................................................ 36
4.3.2. Vrijeme procesiranja, vodeni žigovi i kašnjenje ............................................................................ 37
4.3.3. Stanje, kontrolna točka i tolerancija greške .................................................................................. 38

5. Primjer: Algoritam za analizu Twitter podataka unutar Apache Flink-a .................... 39


5.1. Instalacija i konfiguracija Apache Flink-a ..................................................................... 39
5.2. Prikaz Twitter podataka.............................................................................................. 40
5.2.1. Okruženje za pokretanje programa i učitavanje podataka ........................................................... 41
5.2.2. Filtriranje podataka ....................................................................................................................... 42
5.2.3. Transformacija podataka i spremanje rezultata............................................................................ 44

6. Usporedba razvojnih okvira za „Velike podatke“ ...................................................... 48


7. Zaključak ................................................................................................................. 50
Popis literature ............................................................................................................... 51
Dodaci ............................................................................................................................ 53
A. Instalacija Ubuntu Linux-a na Oracle virtualnoj mašini..................................................... 53
B. Popis slika ...................................................................................................................... 55
C. Popis tablica................................................................................................................... 55
1. Uvod

U posljednjih nekoliko godina svjedočimo brzom napretku tehnologije. Normalno je da


svi imamo jedan, dva ili pak više pametnih uređaja u svom kućanstvu. Svi ti uređaji generiraju
velike količine podataka, još kad tim podacima dodamo činjenicu da je cijeli svijet umrežen,
pristup internetu je omogućen svim stanovnicima razvijenih zemalja i zemalja u razvoju,
dolazimo do zaključka da smo okruženi sa velikom količinom digitalnoj sadržaja. Svaki dan se
generira veliki broj podataka i taj broj iz navedenih razloga eksponencijalno raste.

Iako u današnje vrijeme imamo tehnologiju koja može spremati velike količine podataka
te imamo već poznate algoritme za analizu i obradu podataka, međutim i dalje se javlja
problem skladištenja velike količine podataka, prijenosa podataka u realnom vremenu i
nestrukturiranosti podataka. Upravo iz navedenih razloga došlo je razvoja nove znanosti o
podacima (engl. Data science) kojoj je cilj iz velike sume podataka izvući korisne informacije i
znanje uz pomoću poznatih algoritama i drugih znanosti kao što su matematika, statistika,
strojno učenje, baze podataka i sl.

U ovom radu će biti opisana dva razvojna okruženja za analizu podataka Apache Spark
i Apache Flink. Prvo će teorijski biti objašnjeno kako funkcioniraju i od čega se sastoje ovih
razvojni alati, potom će kroz primjere biti objašnjen način rada navedenih razvojnih alata. Kroz
Apache Spark će biti objašnjen algoritam za strojno učenje, dok će kroz Apache Flink biti
prikazan algoritam za analizu podataka u realnom vremenu.

1
2. Veliki podaci (Big Data)

Pojam „Big Data“ teško je precizno i točno definirati, možemo reći da je to pojam koji
se odnosi na podatke i tehnologije za njihovu obradu. Glavne karakteristike koje posjeduju
veliki podaci se mogu opisati sa pojmom 3V (engl. Volume, Velocit, Varienty).
• Volumen – količina podataka je nemjerljiva, svaki dan kreira se novih 2,3 triliona
gigabajta, stoga, donja granica za volumen nije strogo definirana.
• Brzina – kako podaci pristižu velikom brzinom, tehnologije za rad s velikim
podacima moraju podržavati pohranu podataka i prikazivati rezultate u realnom
vremenu.
• Raznolikost – razlikujemo nekoliko tipova podataka, podaci mogu biti
strukturirani i nestrukturirani, te mogu nastati iz komunikacije čovjeka sa strojem
ili stroja sa strojem. („General Networks“, 2015.).

2.1. Analiza podataka u realnom vremenu

Svaki dan velike količine podataka se generiraju na internetu, pogotovo na društvenim


mrežama. Recimo svake minute korisnici komentiraju ili označe da im se sviđa neka objava
na Facebook-u više od 4 milijuna puta, dok je na Instagramu to nešto manje od 2 milijuna u
jednoj minuti. Na Youtube se prebaci 300 sati novog video sadržaja u samo jednoj minuti (Slika
1). Što se zapravo događa sa svim tim podatcima? Upravo razvojni okviri kao što su Apache
Spark i Apache Flink daju odgovor na to pitanje, oni kontroliraju i procesiraju velike količine
podataka u realnom vremenu. Primjer analize podataka u realnom vremenu možemo naći u
više različitih grana: zdravstvo, telekomunikacije, bankarstvo, tržište dionica i sl. (Dayananda,
2019).

2
Slika 1. Količina podataka na društvenim mrežama koja se generira u jednoj minuti (Dayananda,
2019).

2.2. Povijesni razvoj okvira za analizu podataka

Kao prvi okvir za analizu veliki podataka javlja se Hadoop. Ovo je besplatan skup alata koji
za pohranu podataka koristi svoj sustav datoteka HDFS (Hadoop Distributed File System), a
za obradu podataka koristi Map-Reduce programski model. Za pohranu i spremanje podataka
se koristi Hadoop klaster. (Mali, 2020).

Drugi razvojni okvir za analizu podataka je Apache Spark koji se naslanja na Hadoop.
Spark se može pokretati na Hadoop klaster i može pristupiti Hadoop izvorima podataka.
Apache Spark proširuje Map-Reduce programski model tako što uključuje iterativne upite i
„Stream processing“ odnosno procesiranje podataka u realnom vremenu. Spark obrađuje
podatke 100 puta brže od Hadoop-a unutar memorije, a 10 puta brže na disku. (Mali, 2020).

Sljedeći u generaciji alata za analizu velikih podataka je Apache Flink. Flink je besplatan
alat koji služi za obradu podataka u realnom vremenu i nema svoj sustav za pohranu podataka
(najčešće koristi HDFS). Puno brže procesira podatke od Spark-a i Hadoop-a. Razvoj alata za
analizu velikih podataka najčešće možemo usporediti sa razvojem mobilnog interneta. Hadoop
je 2G, Spark je 3G, a Flink je 4G. (Mali, 2020).

3
3. Apache Spark

Apache Spark je razvojni okvir za analizu podatka koji je nastao na sveučilištu u


Kaliforniji u Berkley-u. Napravljen je od strane nekoliko studenata sa navedenog sveučilišta i
prvi put je objavljen 2009 godine. Apache Spark je pisan u programskog jeziku Scala, ali
podržava još Javu i Python što omogućava analizu podataka u navedenim programskim
jezicima.

3.1. Osnovni koncepti i arhitektura

Kako bi razumjeli Spark i način kako on funkcionira potrebno je znati neke osnove pojmove
i elemente Sparka:
• Spark klaster
• Sustav upravljanja resursima
• Spark aplikacije
• Spark drivere
• Spark izvršitelje
U nastavku će biti objašnjeni svaki od navedenih elemenata.

Spark klaster i sustav upravljanja resursima


Spark je zapravo sustav koji brzo i efikasno distribuira velike količine podataka. Sustav se
izvršava na skupu mašina/čvorova koji se naziva Spark Klaster (engl. Spark Cluster). Veličina
klastera može biti različita pa tako imamo klastere koji sadrže samo nekoliko mašina, dok
najveći Spark Cluster sadrži preko 8 tisuća strojeva. Kako bi kompanije uspješno upravljale sa
velikim skupom mašina moraju imati Sustav upravljanja resursima (engl. The resource
management system). Dva najpoznatija sustava upravljanja resursima su Apache YARN i
Apache Mesos. Dva glavna elementa svakog sustava za upravljanje su Klaster upravitelj (engl.
Cluster manager) i radnik (engl. the worker). Na slici ispod možemo vidjeti komunikaciju Spark
aplikacije i Cluster manager-a. „Cluster manager“ zna gdje se „worker“ nalazi, koliko memorije
ima te koliko procesorskih jezgri sadrži svaki „worker“. Glavna zadaća „Cluster managera“ je
dodijeliti posao svakom „worker-u“, a svaki „worker“ nudi svoje resurse za obavljanje rada.
(Luu, 2018).

4
Slika 2. Komunikacija Spark aplikacije i Cluster managera (Luu, 2018)

Spark aplikacija
Spark aplikaciju možemo podijeliti na dva dijela:
• Logika obrade podataka aplikacije
• Spark driver
Logika obrade podataka može biti neki jednostavan program ili može biti kompleksan
„machine learning“ model koji sadrži puno iteracija i koji se izvršava nekoliko sati. Spark driver
je središnji koordinator svake Spark aplikacije, on komunicira sa „Cluster manager-om“ kako
bi odredio na kojoj mašini će se izvršiti logika obrade podataka. Za svaku mašinu driver
zahtjeva od „Cluster manager-a“ da pokrene proces koji se naziva izvršitelj (engl. Executor).
Spark driver također upravlja i distribuira zadatcima na svakom izvršitelju. Ukoliko logika
obrade podataka zahtjeva ispis podataka za korisnika, tada će Spark driver u suradnji sa
izvršiteljima prikupiti i spojiti sve podatke kako bi driver mogao ispisati rezultate. Ulazna točka
u Spark aplikaciju je kroz klasu „SparkSession“ koja omogućava postavljanje konfiguracije i
API-a za izražavanje logike obrade podataka (Luu, 2018).

Spark driver i izvršitelj


Svaki Spark izvršitelj je JVM (Java Virtual Machine) proces što znači da je svaki izvršitelj
vezan za jednu Spark aplikaciju. Životni vijek Spark izvršitelja ovisi o dužini Spark aplikacije.
Kako se sve Spark aplikacije izvršavaju na različitim Spark izvršiteljima, dijeljenje podataka
između aplikacija zahtjeva zapisivanje podataka u skladišni sistem kao što je HDFS - Hadoop
Distributed File System (Luu, 2018).
Spark podržava upravitelj-izvršitelj arhitekturu (engl. Master-slave architecture) gdje je
Spark driver gospodar, a Spark izvršitelj rob. Spark aplikacija se sastoji od samo jednog driver-
a i jednog ili više Spark izvršitelja. Spark izvršitelj radi ono što mu se naredi odnosno izvršava
logičku obradu podataka, svaki zadatak se izvršava na odvojenoj procesorskoj jezgri. Upravo
iz ovog razloga Spark može ubrzati proces obrade velike količine podataka. Dodatno Spark

5
izvršitelji imaju zadatak spremanja podataka u memoriju ili disk kada je to zadano programskog
logikom (Luu, 2018).

Slika 3. Spark klaster sa tri izvršitelja (Luu,2018)

3.1.1.1. Hadoop distribuirani datotečni sustav (HDFS) i MapReduce

Dva najvažnija podsustava ekosustava Hadoop su HDFS i MapReduce. Upravo ova dva
sustava omogućavaju paralelnu obradu podataka na više mašina unutar klastera.
HDFS je distribuirani datotečni sustav koji služi za pohranu velikih podataka na klasteru na
računalima generalne namjene. HDFS sustav je dizajniran tako da je otporan na pojavu greške
i kvar hardvera, upravo iz toga razloga se koristi hardver niskog budžeta. Ovaj sustav spreman
podatke tako da ih replicira na više računala unutar klastera, a podaci koji se zapišu jednom
mogu se čitati više puta i koristiti u raznim analizama. (White, 2010).
MapReduce je jednostavan programski model za obradu velikih podataka na klasteru
računala. Ovaj model omogućava paralelno računanje nad skupom podataka i upravo ovaj
model je omogućio razvoj i nastanak Apache Spark arhitekture. (White, 2010).

Spark elementi
Razlog zašto je Apache Spark brz i pouzdan alat za upravljanje velikom količinom
podataka su upravo njegovi elementi. Njegovi elementi su napravljeni da rješavaju sve
nedostatke koje je Hadoop MapReduce imao. Apache Spark se sastoji od sljedećih elemenata:
1. Jezgra (engl. Spark Core)
2. Spark Streaming
3. Spark SQL

6
4. GraphX
5. MLlib (Machine Learning)

Slika 4. Spark ekosustav (Apache Spark Ecosystem, bez dat.)

Spark core
Spark core je osnovni mehanizam za obradu i distribuciju podataka. Sastoji se od dva dijela:
distribuirane računalne infrastrukture i otpornog skupa podataka (engl. Resilient Distributed
Datasets , kratica RDD).
Distribuirana računalna infrastruktura je zadužena za distribuciju, koordinaciju i raspored
računalnih zadataka na mašinama unutar klastera. Ona omogućava brzu i efikasnu te
paralelnu obradu velikog broja podataka na klaster mašinama. (Luu, 2018).
RDD (Resilient Distributed Datasets) će dodatno biti objašnjen u sljedećem poglavlju

Spark Streaming
Spark Streaming je komponenta koja se koristi za tok podataka koji nastaju u realnom vremenu
iz različitih izvora kao što su Twitter, tržišta dionica i sl. (Dayananda, 2019).

Spark SQL
Spark SQL komponenta omogućava rad sa strukturiranim podacima te podržava pisanje SQL
naredbi. Ova komponenta zapravo spaja relacijsku obradu podataka sa Spark programskim
sučeljem (Dayananda, 2019).

Spark GraphX
GraphX je komponenta koja omogućava kreiranje grafova s proizvoljnim vrijednostima na
bridovima i vrhovima. Također, GraphX biblioteka sadrži kolekciju usmjerenih grafova (Luu,
2018).

7
Spark MLlib
Spark MLlib datoteka sadrži više od 50 postupaka odnosno algoritama strojnog učenja.
Omogućava razne algoritme za strojno učenje, ali nudi i funkcionalnosti kao što su evaluacija
modela i učitavanje podataka (Luu, 2018).

3.2. Otporni distribuirani skup podataka

Otporni distribuirani skup podataka (engl. Resilient distributed datasets, skraćeno RDD) je
nepromjenjiv, otporna na pogreške i paralelan skup podataka koji omogućava korisnicima da
spremaju rezultate u memoriju, kontroliraju raspodjelu podataka i manipuliraju njima pomoću
bogatog skupa operatora. (Luu, 2018).
RDD podržava dva tipa podataka:
• Transformacije – omogućavaju kreiranje novog skupa podataka od već postojećih.
• Akcije – vraćaju vrijednost driver programu nakon što naprave određene izračune
na skupu podataka („Apache Spark documentation“, bez dat.).

Neke od transformacija nad otpornim skupom podataka su:


• Map (func) – vraća novi distribucijski skup podataka tako da svaki element početnog
skupa proslijedi funkciji func.
• Filter (func) – vraća novi skup podataka ali tako da odabire one elemente početnog
skupa za koje vrijedi funkcija func vraća true.
• flatMap (func) – sličan kao Map, ali ulazni element može biti povezan sa 0 ili više
izlaznih elemenata.
• Union (other dataset) – vraća novi skup podataka koji sadrži uniju postojećeg skupa i
skupa koji je argumentiran.
• Distinct ([numPartitions]) – vraća novi skup podataka koji imaju samo jednom navede
elemente koji se u početnom skupu ponavljaju više puta („Apache Spark
documentation“, bez dat.).

Neke od akcija koje podržava Spark su:


• Collect () – vraća sve elemente skupa podataka kao niz na driver programu.
• Count () – vraća broj elemenata u skupu podataka.
• Take (n) – vraća niz od prvih n elemenata skupa podataka.
• Reduce (func) - agregacija elemenata skupa podataka koji koriste funkciju func koja
prima dva argumenta i vraća jedan. Funkcija mora biti komutativna i asocijativna kako
bi se mogla uspješno paralelno izvršavati. („Apache Spark documetation“, bez dat.).

8
Glavna razlika između transformacije i akcije je ta da transformacija kreira novi skup
podataka, dok akcija bilježi ili piše rezultat određene radnje na disk. Druga bitna razlika je ta
što je evaluacija transformacije „lijena“ (engl. lazy evaluation), a razlog tome je velika količina
podataka. To zapravo znači da će Spark odgoditi evaluaciju pozvane operacije sve dok se ne
poduzme određena akcija. Operacija transformacije će zapamtiti transformacijsku logiku koju
će kasnije pozvati ili zapisati. Pozivanjem neke operacije akcije će automatski okinuti sve
transformacije koje su prethodno zapamćene i to će rezultirati vraćanjem određenih rezultata
driver programu ili zapisom podataka na nekom sustav za pohranu podataka kao što je HDFS
ili u neku lokalnu datoteku (Luu, 2018).

3.3. Primjer: Algoritam za prikaz i predikciju broja zaraženih


i umrlih od koronavirusa u RH

U nastavku će biti prikazan primjer aplikacije na kojoj ćemo vidjeti sve ranije navedene
mogućnosti i elemente Spark-a. Prvo ćemo učitati podatke iz izvora u ovom slučaju iz .JSON
datoteke koji sadrži podatke o trenutnom stanju broja zaraženih, aktivnih i umrlih slučajeva od
Covid-a 19 u Hrvatskoj. Potom ćemo srediti te podatke i na osnovu tih sređenih podataka
napraviti određenu analizu pomoću Apache Spark mehanizama. Kako nam Spark daje
mogućnost rada sa više programski jezika (Scala i Python), ovaj program je napisan u Python-
u.

Instalacija i konfiguracija Apache Spark-a


Prije same instalacije Apache Spark-a potrebno je podesiti Windows okruženje u koje
možemo pokretati Spark aplikacije. Kako bi to ostvarili potrebno je skinuti i instalirati sljedeće
aplikacije:

• Java - Oracle JDK


• Anaconda
• Instalacijski paket za Apache Spark
• Programski jezik Scala
• Hadoop winutils

Prvo je potrebno instalirati Javu (Java se besplatno može skinuti sa Oracle službene
https://www.oracle.com/java/technologies/javase-downloads.html). Nakon instalacije Jave

9
potrebno je instalirati Python, a najbolji način da se to napravi je skinuti Anacondu za
Windowse koja podržava Python. Razlog zašto to radimo preko Anaconde je „Jupyter
notebook“ pomoću kojeg ćemo pokretati aplikaciju. Tek kada smo sve to napravili potrebno je
instalirati Apache Spark, instalacijski paket možemo skinuti sa Apache Spark službene
stranice (https://spark.apache.org/). Nakon što instaliramo Spark potrebno je još skinuti i
instalirati Scala programski jezik, koji stavljamo na istu lokaciju kao i Apache Spark. Scalu
možemo skinuti sa sljedeće stranice https://spark.apache.org/. Zadnja stvar koju moramo
instalirati je „hadoop winutils“. Postupak instalacije svih navedenih aplikacija možete pronaći
na videu koji se nalazi u literaturi pod rednim brojem osam.

Nakon što smo skinuli i instalirati sve navedene aplikacije potrebno je u naprednim
postavkama Windows okruženja dodati nove varijable. Prvo odemo na postavke računala kao
na slici ispod.

Slika 5. Napredne postavke u Windows operacijskom sustavu

Zatim odaberemo sekciju „Advanced“ unutar postavki sustava, i kliknemo na gumb


„Environment Variables“.

10
Slika 6. Opcije unutar naprednih postavki u Windows10

Potom će nam se otvoriti sljedeći prozor u koje vidimo korisničke i sistemske varijable.

11
Slika 7. Dodavanje novih varijabli

Potrebno je dodati sljedeće varijable kako bi mogli pokrenuti Spark unutar Windows okruženja:

• HADOOP_HOME = C:\spark\hadoop
• JAVA_HOME = C:\Program Files\Java\jdk1.8.0_151
• SCALA_HOME = C:\spark\scala\bin
• SPARK_HOME = C:\spark\spark\bin
• PYSPARK_PYTHON = C:\Users\user\Anaconda3\envs\python.exe
• PYSPARK_DRIVER_PYTHON = C:\Users\user\Anaconda3\envs\Scripts\jupyter.exe
• PYSPARK_DRIVER_PYTHON_OPTS = notebook

Putanja do pojedinih aplikacija ne mora nužno biti ista te ukoliko ne koristimo aplikaciju Jupyter
posljednje dvije varijable nam nisu potrebne.

Sada su sve aplikacije instalirane i okruženje je spremno za rad. Možemo otvoriti


„Command Prompt“ konzolu te ukucati sljedeću naredbu spark-submit –version i vidjet ćemo
koja se verzija Spark-a instalirana.

12
Slika 8. Spark verzija

Određivanje putanje i kreiranje Spark konteksta


Nakon što smo instalirali Spark i podesili Jupyter notebook za rad, sljedeći korak u kreiranju
Spark aplikacije je kreiranje Spark konteksta (engl. Spark Context) odnosno Spark Sesije
(engl. Spark Session). Ispod navedeni kod nam upravo omogućava kreiranje sesije i konteksa.

Kreiranje Spark konteksta

from pyspark import SparkContext


from pyspark import SparkConf
from pyspark.sql import SparkSession

conf = SparkConf().setAppName("Coronavirus")
conf = (conf.setMaster('local[2]')
.set('spark.executor.memory', '4G')
.set('spark.driver.memory', '45G')
.set('spark.driver.maxResultSize', '10G'))
sc = SparkContext.getOrCreate(conf=conf)
spark = SparkSession(sc)

13
Kreiranje SQL konteksta, učitavanje podataka
Kako bi mogli učitati određen skup podataka unutar Spark aplikacije, potrebno je kreirati
Spark SQL kontekst. SQL kontekst možemo kreirati upravo iz Spark konteksta kojeg smo
kreirali u prethodnom poglavlju. U programskom kodu ispod, osim kreiranja SQL konteksta,
možete vidjeti da su učitani podaci iz više .JSON datoteka. Svi podaci su preuzeti sa stranice
www.koronavirus.hr te su podaci jako dobro sređeni što nam omogućava lakšu manipulaciju
sa njima. Također u kodu ispod možete primijetiti da smo za svaku datoteku koju smo učitali
kreirali shemu. Prilikom učitavanja podataka prosljeđujemo tu shemu i tako kreiramo
DataFrame s određenim brojem stupaca i redova na kojima se mogu izvršavati deklarativni
upiti.

Kreiranje SQL contexta:

#Create sql context from spark context


from pyspark.sql.types import *
from pyspark.sql import SQLContext
sqlContext = SQLContext(sc)

Učitavanje podataka iz JSON datoteka i kreiranje DataFrame

#Create a data frame from a JSON file


zupanijeDf = sqlContext.read.json("dataset/zupanije.json")
zupanijeDf.show()
zupanijeDf.printSchema()

schema = StructType([
StructField("Datum", StringType(), True),
StructField("Zupanija", StringType(), True),
StructField("dob", IntegerType(), True),
StructField("spol", StringType(), True),
])

osobeDf = sqlContext.read.json("dataset/osobe.json", schema = schema)


osobeDf.show()
osobeDf.printSchema()

schema = StructType([
StructField("Datum", StringType(), True),
StructField("IzlijeceniHrvatska", IntegerType(), True),
StructField("IzlijeceniSvijet", IntegerType(), True),

14
StructField("SlucajeviHrvatska", IntegerType(), True),
StructField("SlucajeviSvijet", IntegerType(), True),
StructField("UmrliHrvatska", IntegerType(), True),
StructField("UmrliSvijet", IntegerType(), True),
])

svijetDf = sqlContext.read.json("dataset/coronavirus.json", schema =


schema)
svijetDf.show()
svijetDf.printSchema()

Učitali smo podatke iz tri različite datoteke osobe.json, zupanije.json i coronavirus.json.


Prikaz svi podataka i njihovih shema se nalazi na slikama ispod.

Slika 9. Tablica Županije

15
Slika 10. Tablica Osobe

16
Slika 11. Tablica zaraženih Hrvatska

Grafički prikaz umrlih, zaraženih i aktivnih slučajeva u RH


Na osnovu SQL konteksta smo iz DataFrame-ova u koje smo učitali podatke sada kreirali
privremene tablice te na njima napravili određene upite. Nakon što smo izvukli one podatke iz
tablica koje nas zanimaju, podatke iz upita smo spremili u liste te kreirali određeni broj grafova
koji nam prikazuju broj umrlih, zaraženih i aktivnih slučajeva koronavirusa u Republici
Hrvatskoj. Također pomoću grafova smo prikazali i postotak oboljelih prema dobi i spolu. U
nastavku će biti prvo prikazan kod pomoću kojeg smo napravili upite i kreirali grafove, a potom
će biti prikazan rezultat odnosno prikaz grafova.

Kreiranje privremenih tablica i upiti


import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

zupanije = zupanijeDf.registerTempTable("zupanije")

aktivni = sqlContext.sql("select Zupanija, broj_aktivni from zupanije


group by 1,2 order by 2")
aktivni.collect()

17
zarazeni = sqlContext.sql("select Zupanija, broj_zarazenih from zupanije
group by 1,2 order by 2")
zarazeni.collect()

umrlih = sqlContext.sql("select Zupanija, broj_umrlih from zupanije group


by 1,2 order by 2")
umrlih.collect()

x1=aktivni.toPandas()["Zupanija"].values.tolist()
y1=aktivni.toPandas()["broj_aktivni"].values.tolist()
z1=zarazeni.toPandas()["broj_zarazenih"].values.tolist()
d1=umrlih.toPandas()["broj_umrlih"].values.tolist()

Kreiranje i prikaz grafova pomoću biblioteke matplotlib.pyplot

U nastavku će biti prikazani prvo kod pomoću kojeg smo kreirali određene grafove, a nakon
koda će biti prikazani grafovi za broj aktivnih, zaraženi i umrlih slučajeva od koronavirusa u RH
poredano po županijama.

1. Broj aktivnih slučajeva:

fig = plt.figure(figsize=(20,5))

ax1 = fig.add_subplot(1,2,1)

rects1 = ax1.bar(x1, y1)


ax1.set_xticklabels(x1, rotation=60, horizontalalignment='right',
fontsize='12')
ax1.set_title("Broj aktivnih slučajeva po županijama")
ax1.set_ylabel('broj aktivnih')

def autolabel(rects):
for rect in rects:
height = rect.get_height()
ax1.text(rect.get_x() + rect.get_width()/2., height,'%d' %
int(height), ha='center', va='bottom')

autolabel(rects1)
plt.savefig("Broj_aktivnih.png", dpi=300, bbox_inches='tight')
plt.show()

18
Slika 12. Broj aktivnih slučajeva u RH

2. Broj zaraženih slučajeva:

fig = plt.figure(figsize=(20,5))

ax2 = fig.add_subplot(1,2,1)
rects2 = ax2.bar(x1, z1)
ax2.set_xticklabels(x1, rotation=60, horizontalalignment='right',
fontsize='12')
ax2.set_title("Broj zaraženih slučajeva po županijama")
ax2.set_ylabel('broj zarazenih')

def autolabel(rects):
for rect in rects:
height = rect.get_height()
ax2.text(rect.get_x() + rect.get_width()/2., height,'%d' %
int(height), ha='center', va='bottom')

autolabel(rects2)
plt.savefig("Broj_zarazenih.png", dpi=300, bbox_inches='tight')

19
plt.show()

Slika 13. Broj zaraženih slučajeva u RH

3. Broj umrlih slučajeva u RH:

fig1=plt.figure(figsize=(20,5))

ax3 = fig1.add_subplot(1,2,1)

rects3= ax3.bar(x1, d1)


ax3.set_xticklabels(x1, rotation=60, horizontalalignment='right',
fontsize='12')
ax3.set_title("Broj umrlih slučajeva po županijama")
ax3.set_ylabel('broj umrlih')

def autolabel(rects):
for rect in rects:
height = rect.get_height()
ax3.text(rect.get_x() + rect.get_width()/2., height,'%d' %
int(height), ha='center', va='bottom')

20
autolabel(rects3)
plt.savefig("broj_umrlih.png", dpi=300, bbox_inches='tight')
plt.show()

Slika 14. Broj umrlih slučajeva u RH

4. Broj oboljelih prema spolu

osobe = osobeDf.registerTempTable("osobe")
spolM = sqlContext.sql("select count(spol) as Muski from osobe where spol
= 'M'")
spolZ = sqlContext.sql("select count(spol) as Zene from osobe where spol
= 'Ž'")

muski = spolM.toPandas()["Muski"].values.tolist()
zene= spolZ.toPandas()["Zene"].values.tolist()

#Pie
labels = "Muškarci", "Žene"
values = [muski,zene]
plt.pie(values, labels = labels, autopct='%1.1f%%', startangle=140)

21
plt.title("Postotak oboljelih prema spolu")
plt.axis('equal')
plt.savefig("broj_oboljelih prema spolu.png", dpi=300,
bbox_inches='tight')
plt.show()

Slika 15. Postotak oboljelih prema spolu

5. Broj oboljelih prema dobi

mladi = sqlContext.sql("select count(dob) as Mladi from osobe where dob


>= 1995 ")
srednjadob = sqlContext.sql("select count(dob) as SrednjaDob from osobe
where dob between 1969 and 1994")
stari = sqlContext.sql("select count(dob) as Stari from osobe where dob
<= 1970 ")

mlad = mladi.toPandas()["Mladi"].values.tolist()
srednji = srednjadob.toPandas()["SrednjaDob"].values.tolist()
star = stari.toPandas()["Stari"].values.tolist()

lista = "Mladi", "Srednja Dob", "Starija Dob"


values1 = [mlad,srednji,star]
plt.pie(values1, labels = lista, autopct='%1.1f%%', startangle=140)
plt.title("Postotak oboljelih prema dobi")
plt.axis('equal')

22
plt.savefig("broj_oboljelih_prema_dobi.png", dpi=300,
bbox_inches='tight')
plt.show()

Slika 16. Postotak oboljelih prema dobi

Pod Mladi spadaju svih mlađi od 25 godina, srednja dob podrazumijeva ljude između 25 i
50 godina, dok za stariju dob mislimo na sve ljude starije od 50 godina.

„Machine Learning“ algoritmi u Apache Sparku


Prema službenoj Apache Spark dokumentaciji, datotetka MLlib (engl. Machine learning
library) sadrži razne algoritme. Neki od najpoznatiji su:

• Linearna regresija (engl. linear regression)


• Logistička regresija (engl. logistic regression)
• Stablo odluke (engl. decision tree classifier)
• Slučajna šuma (engl. random forest classifier)
• Stroj potpornih vektora (engl. linear support vector machine)
• Naivan Bayesov klasifikator (engl. naive Bayes)
• Višeslojni perceptron (engl. multilayer perceptron classifier).

U primjeru je korišten algoritam linearne regresije.

23
3.3.1.1. Linearna regresija

Regresijska analiza se sastoji od različitih metoda koje imaju za cilj ispitati ovisnost
jedne varijable o jednoj ili više drugih varijabli. Jedna od tih metoda je upravo Linearna
regresija. S obzirom na broj ulaznih i izlaznih varijabli razlikujemo više vrsta linearne regresije:

• Univarijatna jednostavna (jedan ulaz – jedan izlaz)


• Multivarijatna jednostavna (jedan ulaz – više izlaza)
• Univarijatna višestruka (više ulaza – jedan izlaz)
• Multivarijatna višestruka (više ulaza – više izlaza). (Šnajder, 2017)

Linearnu regresiju je najlakše opisati kroz model jednostavne univarijatne regresije.

Šošić (2004) komentira model linearne regresije na sljedeći način:

„Modelom jednostavne regresije analitički se izražava statistički odnos među dvjema pojavama
predočenima vrijednostima numeričkih varijabli. Model sadrži zavisnu i jednu nezavisnu
varijablu. Model jednostavne linearne regresije prikladan je za opisivanje pojava koje su u
linearnom statističkom odnosu. Primijenit će se u slučaju kada jediničnom povećanju
vrijednosti nezavisne varijable odgovara približno ista linearna promjena vrijednosti zavisne
varijable.“.

Algebarski model jednostavne linearne regresije glasi:

𝑌 = 𝑎 + 𝑏𝑋 + 𝑢

gdje je

X – nezavisna varijabla

Y = zavisna varijabla

U = odstupanje od funkcionalnog odnosa

a, b - parametri

Regresijska analiza provodi se na temelju n parova vrijednosti varijabli X i Y : (𝑥1 , 𝑦1 ), (𝑥2 , 𝑦2 ),


..., (𝑥𝑛 , 𝑦𝑛 ), pa se model predočuje sustavom od n jednadžbi:

𝑌𝑖 = 𝑎 + 𝑏𝑥𝑖 + 𝑢𝑖

Kada bi odnos među varijablama bio funkcionalan, svaka bi vrijednost varijable 𝑢𝑖 bila jednaka
nuli odnosno geometrijski, sve bi točke s koordinatama (𝑥𝑖 , 𝑦𝑖 ), i = 1,2,...,n ležale na istome
pravcu. (Šošić, 2004.)

24
Kako su odnosi među pojavama statistički, treba odrediti kriterij prema kojemu će se izabrati
jednadžba pravca ŷ = a + bx koja će ‘najbolje’ opisati odnos pojava na temelju njihovih
opaženih vrijednosti.

• 𝑢𝑖 su procjene nepoznatih vrijednost varijable u i nazivaju se rezidualnim odstupanjima:

𝑢𝑖 = 𝑦𝑖 − ŷ𝑖

a relativno izražena rezidualna odstupanja:

𝑦𝑖 − ŷ𝑖
𝑢𝑖,𝑟𝑒𝑙 = ∗ 100
𝑦𝑖

„Jednadžba pravca određena je ako su poznati parametri a i b. Do procjene parametara


najčešće se dolazi metodom najmanjih kvadrata. Navedena metoda sastoji se u određivanju
onih procjena parametara za koje rezidualni zbroj kvadrata postiže minimum“:

∑𝑛𝑖=1 𝑥𝑖 𝑦𝑖 − 𝑛 ∗ 𝑥̅𝑖 ∗ 𝑦̅𝑖


𝑏= , 𝑎 = 𝑦̅ − 𝑏 ∗ 𝑥̅
∑𝑛𝑖=1 𝑥𝑖2 − 𝑛 ∗ 𝑥̅ 2

Veličina b je regresijski koeficijent, ona pokazuje za koliko se u prosjeku mijenja vrijednost


zavisne varijable Y za jediničnu promjenu vrijednosti nezavisne varijable X. Regresijska
jednadžba je analitički izraz koji u smislu prosjeka opisuje odnos među pojavama stoga je
osnova za mjerenje reprezentativnosti disperzija oko regresije, koja se očituje na rezidualnim
odstupanjima. Što su manja odstupanja empirijskih vrijednosti zavisne varijable od regresijskih
vrijednosti to je bolja reprezentativnost regresije (Šošić, 2004.).

„Varijanca regresije je aritmetička sredina kvadrata rezidualnih odstupanja. Pozitivni drugi


korijen iz varijance regresije jest standardna devijacija regresije, a omjer standardne devijacije
i aritmetičke sredine pomnožen sa sto predočuje koeficijent varijacije regresije. Varijanca
regresije je : “
𝑛 𝑛 𝑛
1
𝜎ŷ2 = ( ∑ 𝑦𝑖2 − 𝑎 ∑ 𝑦𝑖 − 𝑏 ∑ 𝑥𝑖 𝑦𝑖 )
𝑛
𝑖=1 𝑖=1 𝑖=1

Standardna devijacija regresije:

𝑛 𝑛 𝑛
1
𝜎ŷ = √ (∑ 𝑦𝑖2 − 𝑎 ∑ 𝑦𝑖 − 𝑏 ∑ 𝑥𝑖 𝑦𝑖 )
𝑛
𝑖=1 𝑖=1 𝑖=1

Koeficijent varijacije regresije:

25
𝜎ŷ
𝑉ŷ = ∗ 100
𝑦̅

Standardna devijacija pokazuje koliko je prosječno odstupanje empirijskih vrijednosti od


regresijskih vrijednosti u mjernim jedinicama zavisne varijable, a koeficijent varijacije koliko je
to u relativnom iznosu to jest u postotcima. (Šošić, 2004.)

Pokazatelj reprezentativnosti regresije je koeficijent determinacije. Koeficijent determinacije je


proporcija modelom protumačenog dijela zbroja kvadrata u ukupnom zbroju kvadrata.
Protumačeni dio kvadrata jednak je zbroju kvadrata odstupanja regresijske vrijednosti od
aritmetičke sredine zavisne varijable, a ukupan zbroj kvadrata odnosi se na zbroj kvadrata
odstupanja vrijednosti zavisne varijable od njezine aritmetičke sredine. Koeficijent
determinacije:

𝑎 ∑𝑛𝑖=1 𝑦𝑖 + 𝑏 ∑𝑛𝑖=1 𝑥𝑖 𝑦𝑖 − 𝑛 ∗ 𝑦̅ 2
𝑅2 = , 0 ≤ 𝑅2 ≤ 1
∑𝑛𝑖=1 𝑦𝑖2 − 𝑛 ∗ 𝑦̅ 2

Model je reprezentativniji što je koeficijent determinacije bliži jedinici. (Šošić, 2004.)

3.3.1.2. Predikcija broja umrlih u RH pomoću linearne regresije

Za kraj analize kreiran je algoritam koji pomoću linearne regresije računa predikciju
broja umrlih na osnovu 5 varijabli: broja zaraženih u svijetu, broja zaraženih u RH, broja umrlih
u svijetu, broj izliječenih u svijetu i broj izliječenih u RH. Svi podaci za testiranje ovog algoritma
su preuzeti iz sljedeće tablice:

Slika 17. Tablica koronavirus

Kako bi napravili predikciju prvo je potrebno odrediti zavisne i nezavisne varijable. Cilj
je izračunati predikciju za broj umrlih osoba u RH stoga kolonu „UmrlihHrvatska“ uzimamo kao

26
zavisnu varijablu. Varijabla „UmrlihHrvatska“ zapravo ovisi od drugih kolona unutar ove tablice
pa kao nezavisne varijable u ovom slučaju se mogu uzeti sve ostale kolone osim datuma. U
ovom primjeru imamo više ulaza, a samo jedan izlaz pa možemo zaključiti da se radi o
univarijatnoj (višestrukoj) linearnoj regresiji. Nezavisne varijable u ovom primjeru su:
„IzliječeniHrvatska“, „IzliječeniSvijet“, „SlučajeviHrvatska“, „SlučajeviSvijet“, „UmrliSvijet“, a
zavisna varijabla je „UmrlihHrvatska“.

Pomoću sljedećeg koda smo izvukli sve podatke iz gore navedene tablice, definirali
varijable i podijelili podatke na trening podatke i testne podatke:

from pyspark.sql.functions import col, when, to_date


from pyspark.sql import functions as F
from pyspark.sql.types import *
from pyspark.ml.regression import LinearRegression
from pyspark.ml.feature import VectorAssembler

coronaSvijet = svijetDf.registerTempTable("coronavirus")
data = sqlContext.sql("select * from coronavirus where SlucajeviSvijet >
0 order by 4")
data.collect()
data.show(15)
#data.printSchema()

#podjela podataka, 80% za trening, 20% za testiranje


dividedData = data.randomSplit([0.80, 0.20])
trainingData = dividedData[0] #index 0 = data training
testingData = dividedData[1] #index 1 = data testing
train_rows = trainingData.count()
test_rows = testingData.count()
print ("Redovi za trening podataka:", train_rows, "; Redovi za
testiranje:", test_rows)

#definiranje varijabli
assembler = VectorAssembler(inputCols = [
"IzlijeceniHrvatska","IzlijeceniSvijet",
"SlucajeviHrvatska", "SlucajeviSvijet",
"UmrliHrvatska","UmrliSvijet"], outputCol="varijable")

#prikazivanje varijabli u kolonama


trainingDataFinal = assembler.transform(trainingData).select(

27
col("Datum"),col("varijable"),
(col("UmrliHrvatska").cast("Int").alias("UmrliHrvatska")))
#trainingDataFinal.show(truncate=False , n=50)

Kao rezultat ove radnje dobit ćemo sljedeću tablicu:

Slika 18. Podjela podataka na testne i trening podatke

Model je napravljen tako da podijeli podatke na trening podatke i testne podatke. Algoritam 80
% podataka uzima kao trening podatke, a 20 % kao testne podatke pa zato imamo 259
nasumičnih redova koji su pripremili ovaj model, a 63 reda koji predviđaju stvarnu vrijednost.
Na tablici se pod kolonom „varijable“ nalaze sve nezavisne varijable, dok je kolona
„UmrlihStvarno“ zavisna varijabla.

Kada smo odredili varijable i podijelili podatke pomoću dolje navedenog koda pozovemo
funkciju „Linear regresion“ te pomoću naredbe „fit“ testiramo ovaj naše model, a zatim
usporedimo stvarne vrijednosti sa onim koje je algoritam predvidio.

#pozivanje funkcije Linearne regresije


algoritma = LinearRegression(
labelCol="UmrliHrvatska",featuresCol="varijable",
maxIter=20, regParam=3.3)

#Testiranje modela pomoću testnih podataka


model = algoritma.fit(trainingDataFinal)
print ("Model regresije je spreman!")

#kreiranje kolona sa testnim podacima

28
testingDataFinal = assembler.transform(
testingData).select(
col("Datum"),col("varijable"),
(col("UmrliHrvatska")).cast("Int").alias("UmrlihStvarno"))
testingDataFinal.show(truncate=False, n=10)

#predviđanje testnih rezultata pomoću našeg modela


prediction = model.transform(testingDataFinal)
#prikaz rezultata predikcije
prediction.show(100)
(Izvor, Routray, 2020)

Rezultat ove radnje je prikazan na slici ispod. Vidimo da predikcija ne odstupa puno od stvarnih
vrijednosti.

Slika 19. Slika 19. Rezultat predikcije

Iako možemo vidjeti da su rezultati predikcije dosta točni, potrebno je to provjeriti. Kako je
navedeno u prethodnom poglavlju pokazatelj reprezentativnosti modela možemo provjeriti
pomoću koeficijenta determinacije. Pomoću funkcije „RegressionEvaluator“ je izračunat
koeficijent determinacije.

#evaluator
evaluator = RegressionEvaluator(
labelCol="UmrlihStvarno", predictionCol="prediction",
metricName="r2")
#izračun koeficijenta determinacije

29
r2 = evaluator.evaluate(prediction)
print ("koeficijent determinacije R2= ", r2)

Dobijemo:

koeficijent determinacije R2= 0.9997001939241197

Koeficijent determinacije je blizu jedinice pa možemo zaključiti da je ovaj model


reprezentativan. Dobili samo veliku točnost modela, ali razlog tome je što imamo nekoliko
stotina redova za analizu. Ukoliko bi se broj redova povećao, odnosno kada bi imali više
dostupnih podataka, velika je vjerojatno da bi se koeficijent determinacije smanjivao. Također
je bitno napomenuti da smo uzeli 5 nezavisni varijabli i to također povećava točnost modela,
kada bi uzeli manji broj varijabli koeficijent determinacije bi bio manji.

30
4. Apache Flink

Projekt Apache Flink je započeo u Berlinu 2009 godine te je tek nakon par godina
istraživanja odnosno u prosincu 2014 prihvaćen kao jedan od glavnih Apache projekata.
Glavna zadaća ovog programa je distribucija podataka uz visoku propusnost i nisku latenciju.
Podržava programsko sučelje za Java i Scala programske jezike.

Najpoznatija definicija Apache Flinka je upravo ona sa njihovih službenih stranica: „Apache
Flink je platforma otvorenog koda za distribuciju/raspodjelu/ distribuiranih tokova i podataka.
Jezgra Apache Flinka je mehanizam za strujanje podataka (data streaming) koji pruža
distribuciju podataka, komunikaciju i toleranciju grešaka za raspodijeljene proračune preko
protoka podataka. Flink gradi skupnu obradu na vrhu strujnog motora, preklapajući podršku
izvorne iteracije, upravlja memorijom i optimizira programe“. („Apache Flink documentation“,
bez dat.)

4.1. Apache Flink Ekosustav

Apache Flink ekosustav sastoji se od različitih komponenti:

• Skladištenje (engl. Storage)


• Razvojno okruženje (engl. Deployment)
• Jezgra (engl. Kernel)
• Korisničko sučelje i biblioteke (engl. API & Libraries)

Slika 20. Apache Flink Ekosustav (Apache Flink Tutorial- Ecosystem Components, bez dat.)

31
Skladištenje (engl. Storage/Streaming)
Prema prezentaciji „Introduction to Apache Flink“ (Edureka, 2016) možemo reći da je Flink
zapravo jedini alat za obradu podataka koji nema sustav skladištenja. Dizajniran je tako da
može čitati i pisati podatke sa različitih sustava skladištenja. Nije bitno radi li se o datoteci,
skupu podataka ili nekim „streaming“ podatcima. Na slici 20 navedeni su neki sustavi
skladištenja sa koji Flink može čitati/pisati podatke:

• HDFS – Hadoop Distributed File System


• Local-FS – Local File System
• HBase – NoSQL Database in Hadoop ecosystem
• MongoDB – NoSQL Database
• RBDBMs – Any relational database
• S3 – Simple Storage Service from Amazon
• Kafka – Distributed messaging Queue
• Flume – Data Collection and Aggregation Tool
• RabbitMQ – Messaging Queue

Razvojno okruženje (engl. Deploy)


Kako je navedeno u prezentaciji „Introduction to Apache Flink“ (Edureka, 2016) drugi sloj
Flink ekosustava je razvoj okruženje na kojem se sustav izvodi. Flink se može nalaziti na
različitim sustavima ovisno o tome želimo li da se sustav nalazi lokalno, na klasteru ili na cloud.
Flink može biti implementiran na sljedećim lokacijama:
• Lokalno - na jednoj Java virtualnoj mašini(JVM)
• Na klasteru – Standalone, YARN, Mesos
• U oblaku – Amazon, Google.

Jezgra (engl. Kernel)


Sljedeći sloj Flink ekosutava je jezgra. Ovaj sloj omogućava pouzdanu distribuciju
podataka u realnom vremenu i tolerantan je na pogrešku. (Edureka, 2016)

Aplikacijsko programsko sučelje i datotečne knjižnice


Zadnji sloj Apache Flink ekosustava je aplikacijsko programsko sučenje (API) i datotečne
knjižnice (engl. libraries). U ovom sloju su opisane tablice, datoteke, strojno učeni algoritmi.
Strojni algoritmi se nalaze u knjižici „Flink ML“, funkcije za grafiku nalaze u „Gelly“ knjižici, a

32
ukoliko želimo raditi sa SQL upitima potrebno je uključiti „Table“ knjižicu u svoj program. Sve
navedene datotečne knjižnice sadrže algoritme i funkcije koje se mogu koristit u izradi
aplikacije. Također prilikom izrade aplikacije postoje dvije mogućnosti distribucije podataka. U
prvoj opciji podaci se obrađuju na nekom određenom skupu, taj skup je sastavljen od podataka
koji su prikupljeni u određenom vremenskom periodu, te je skup konačan. Ovaj tip procesiranja
i skupljanja podataka naziva se „Batch processing“ i još je jedna stvar karakteristična za njega,
skup podataka koji se analiza uvijek je negdje spremljen. Druga opcija je procesiranje
podataka u realnom vremenu, odnosno slanje i analiza podataka čim se podaci generiraju.
Ovaj tip prijenosa i analize podataka se naziva „Stream processing“. Prvi oblik nam omogućava
da prikupimo točne i sigurne podatke, ali druga opcija omogućava veću propusnost podataka,
ali često njihov sadržaj nije potpun. (Edureka, 2016)

4.2. Apache Flink Arhitektura

Apache Flink kao i Apache Spark također podržava upravitelj – izvršitelj arhitekturu. Ova
arhitektura je najbolje vidljiva priliko pokretanja nekog Flink programa. Svaki Flink program
sastoji se od dva procesa: upravitelj (engl. master) i izvršitelj (engl. worker). Na sljedećoj slici
možemo vidjeti od koji procesa se sastoji pokretanje nekog Flink programa.

Slika 21. Pokretanje Flink programa (Deshpande, 2017)

33
Kako se može vidjeti na slici postoje tri glavne uloge odnosno procesa koja sudjeluju u
pokretanju nekog Flink programa. Kada se program pokrene on automatski predaju radnju
„klijentu“ (engl. Job Client). Klijent ima ulogu proslijediti taj proces do „Voditelja poslova“ (engl.
Job Manager). Voditelj poslova provjerava koji „Upravitelj poslova“ (engl. Task Manager) ima
najviše resursa potrebnih za obavljanje određenog zadatka. Upravitelj poslova koji ima najviše
resursa će dobiti zadatak od Voditelja poslova. Nakon toga Upravitelj poslova inicira dretvu
koja pokreće program, osim toga Upravitelj šalje izvještaj ukoliko se status ove radnje
promjeni. Nakon što je radnja završena, rezultati se preko Voditelja poslova šalju nazad do
klijenta i time je proces pokretanja Flink programa završen. (Deshpande, 2017).

Ulogu „upravitelja“ u ovoj arhitekturi ima Voditelj poslova (engl. „Job Manager“). Ovaj
proces je zadužen za raspoređivanje zadataka, upravljanje greškama, kreiranja kontroli
točaka. Kako bi uspješno obavio sve navedene zadatke, ova proces ima tri glavne
komponente: sustav uloga, raspored i kontrolu točku. U svakom programu može biti više
Voditelja procesa, ali jedan je glavni. U slučaju da je on nedostupan, drugi preuzima njegovu
ulogu. (Deshpande, 2017).

Ulogu „izvršitelja“ u ovoj arhitekturi ima Upravitelj poslova (engl. „Task Manager“). On je
zadužen za pokretanje jednog ili više zadataka koje dobije od Voditelja poslova. Ovaj proces
se može podijeliti na „slotove“ (engl. slots) tako da recimo svaki slot dobije 25 % ukupno
alocirane memorije na nekom „Task manager-u“ što omogućava paralelno izvršavanje više
zadataka istovremeno. Bitno je napomenuti da svaki slot može pokrenuti jednu ili više dretvi.
(Deshpande, 2017).

Klijent zapravo ne spada u ovu arhitekturu i nije dio Flink programa priliko pokretanja, ali
od njega kreće ovaj proces i on je zadužen za prihvaćanje programa od korisnika i kreiranje
toka podataka. Nakon toga prosljeđuje podatke „Job Manager-u“ te je zadužen za prikazivanje
rezultata korisniku, nakon što je program završio. (Deshpande, 2017).

4.3. Tokovi podataka u Apache Flink-u

Kako smo ustanovili ranije Apache Flink je alat pomoću kojega možemo procesirati i
analizirati velike količine podataka u realnom vremenu. U nastavku će ukratko biti opisan
proces prijenosa podataka unutar Apache Flink okruženja. Kako bi proces prijenosa podataka
bio što jasniji prvo je potrebno definirati što je to zapravo tok ili prijenos podataka (engl.
DataStream).Tok ili prijenos podataka možemo definirati kao skup podataka koji može biti
konačan ili neograničen. Bitno je napomenuti da se podaci unutar ovog skupa ne mogu
mijenjati, ali se mogu prosljeđivati te se na njima se mogu raditi razne analize pomoću

34
„DataStream“ operacija unutar Flink-a, te operacije se još nazivaju i transformacije. Osnovne
transformacije za prijenos podataka unutar Flink okruženja su:

• Map – prima jedan element ili skup i rezultat ove operacije je jedan element ili skup.
• FlatMap - prima jedan element i vraća nula, jedan ili više elemenata.
• Filter – filtrira skup podataka i vraća samo one elemente koji zadovoljavaju uvjet
istinitosti.
• KeyBy - logički dijeli skup na dva dijela, elementi sa istim ključevima će biti svrstati
u isti grupu.
• Reduce – smanjiva skup tako što svaku novu vrijednost elementa uspoređuje sa
njegovom smanjenom vrijednosti te prikaže zadnju vrijednost.
• Aggregations – skupljanje podataka po određenim ključevima i kreiranje novog
skupa podataka.
• Window – grupira podatke prema određenim karakteristikama (npr. Svi podaci koji
su došli u zadnji 5 minuta).
• WindowAll - grupira podatke prema određenim karakteristikama (npr. Svi podaci
koji su došli u zadnji 5 minuta). Razlikuje se od Window transformacije po tome što
grupira sve podatke, dok Window transformacija grupira podatke koji su podijeljeni
odnosno samo jedan manji skup podataka. Zapravo to znači da će ova naredba u
programu doći prije KeyBy transformacije, a Window transformacija će doći poslije
KeyBy transformacije.
• Window Apply – primjenjuje generalnu funkciju na prozor (engl. Window) u cijelosti
• Window Reduce - primjenjuje „reduce“ funkciju na određeni prozor i vraća skup
sa reduciranim vrijednostima.
• Aggregations on windows - sakuplja sadržaj određenog prozora.
• Union – spaja dva ili više toka podataka i kreira novi skup koji sadrži sve podatke
iz oba toka.
• Window Join – spaja dva toka podataka prema određenom ključu u zajednički
prozor.
• Interval Join – povezuje dva elementa iz dva različita toka podataka preko
zajedničkog ključa u određenom vremenskom intervalu.
• Window CoGroup – grupira dva toka i to svaki prema zadanom ključu u zajednički
prozor.
• Connect – spaja dva toka podataka tako tokovi ne gube svoja svojstva. Ova
transformacija omogućava dijeljenje podataka između dva toka podataka.
• CoMap, CoFlatMap – slično kao map i flatMap na spojenom toku podataka.

35
• Iterate – kreira povratnu petlju tako što prosljeđuje rezultat jednog operatora na
neki stari postojeći operator. Ova transformacija je korisna za kreiranje algoritama
koji konstanto ažuriraju neki model. („Apache Flink documentation“, bez dat.)

Na osnovu navedenih transformacija možemo zaključiti da se tokovi podataka unutar Apache


Flink okruženja uvelike oslanjaju na prozore (engl. Windows) pa će tako u nastavku biti opisani
prozori, vrijeme i mehanizmi koji sudjeluju u procesu prijenosa podataka unutar Flink-a.

Prozori (engl. Windows)


Windows je glavi dio Flink „streaming“ procesa koji dijeli „stream“ na manje dijelove
ograničene veličine na kojima možemo raditi izračune. Unutar Flink okruženja svaki
„datastream“ možemo podijeliti na tokove sa ključem (engl. „keyed streams“) i tokove podataka
bez ključa (engl. „non-keyed streams“). „Non-keyed“ stream dolazi prije „keyBy“
transformacije, a „keyed streams“ dolazi poslije „keyBy“ transformacije. Ova transformacija je
najsličnija groupby funkciji unutar SQL-a i njen zadatak je grupirati određeni „stream“ prema
nekom zadanom ključu. Nakon što specificiramo vrstu „stream-a“, sljedeći korak je definirati
windows ustupitelj (engl. „windows assigner“). Uloga „windows assigner-a“ je dodijeliti
elemente koji dolaze na jedan ili više „window-a“. („Apache Flink documentation“, bez dat.)

Unutar Flink-a definirani su sljedeći „windows assigneri“:

• Prevrnuti prozori (engl. „Tumbling Windows“) – dodjeljuje svaki element


prozoru koji ima određenu fiksnu veličinu i nema mogućnost preklapanja. Npr.
„tumbling windows“ sa veličinom od 5 minuta. To zapravo znači da se svaki prozor
ocjenjuje nakon isteka tih 5 minuta i pokreće se novi prozor.
• Klizni prozori (engl. „Sliding Windows“) - slično kao i „Tumbling Windows“ ovaj
prozor dodjeljuje elemente određene veličine, ali razlika je ta što ovaj tip prozora
ima mogućnost preklapanja. Preklapanje se ostvaruje pomoću parametra „window
slide“ koji određuje nakon koliko vremena se pokreće novi prozor. Upravo zbog
toga dolazi do preklapanja jer može se dogoditi da jedan prozor još ima prostora i
sprema elemente, a u međuvremenu je ovaj parametar već kreirao novi prozor.
Npr. Imamo prozor veličine 10 minuta, a parametar „windows slide“ pokreće novi
prozor svakih 5 minuta.
• Prozori sesije (engl. Session Windows) – ovaj tip prozora grupira podatke ovisno
o vremenu aktivnosti. Nema definiran početak ni kraj i ne dolazi do preklapanja
nego jednostavno kada prestane primati podatke prema određenoj sesiji tada se
ovaj prozor zatvara. Određuje se vrijeme neaktivnosti te kada to vrijeme istekne
ovaj prozor se zatvori.

36
• Globalni prozor (engl. Global Windows) – ovaj tip prozora dodjeljuje sve
elemente istog ključa u individualni „global window“. Uz ovaj tip prozora se koristi
okidač (engl. trigger) i nema kraj na koji možemo proslijediti agregirane elemente.
Okidač unutar Apache Flink programa određuje kada je window spreman za
procesiranje podataka. Pomoću sljedećih naredbi okidač određuje što uraditi sa
podatcima:
o CONTINUE – ne radi ništa,
o FIRE – napravi izračun,
o PURGE – izbriši sadržaj prozora,
o FIRE_AND_PURGE – napravi izračun i izbriši sadržaj prozora nakon toga.
Za brisanje sadržaja prozora koristi se „Evictor“ koji dolazi nakon naredbe okidača,
a prije ili poslije „window“ funkcije. („Apache Flink documentation“, bez dat.)

Vrijeme procesiranja, vodeni žigovi i kašnjenje


Vrijeme ima važnu ulogu u procesu prijenosa podataka. Kada pričamo o vremenu unutar
nekog „streaming“ programa ono se može referencirati na sljedeće pojmove vremena:

• Vrijeme procesiranja (engl. Processing time) - odnosi se na vrijeme mašine na kojoj


se pokreće program. Sve vremenske operacije (npr. Vrijeme trajanja određenog
prozora) koriste sistemsko vrijeme mašine na kojoj se program izvodi. Prednost
korištenja ovog tipa vremena je dobra iskorištenost performansi programa i mašine te
malo kašnjenje, ali negativna strana je ta što ovisi o performansama neke mašine i nije
pogodno za distribuciju velike količine podataka.
• Vrijeme događaja (engl. Event time) – odnosi se na vrijeme koje svaki događaj dobije
na svom izvornom uređaju. Ovo vrijeme je već uključeno u neki zapis prije nego što
dođe u Flink program i vrijeme događaj se može pročitati iz svakog zapisa, a to zapravo
znači da vrijeme ovisi o podatcima koji dolaze u aplikaciju. U savršenom slučaju obrada
vremena događaja dala bi konzistentne i determinističke rezultate, bez obzira na to
kada je neki događaj stigao i koji redoslijedom, ali i vrijeme događaja pokazuje
određeno kašnjenje zbog događaj koji dođu izvan reda. („Apache Flink documentation“,
bez dat.)

Svaki „streaming“ proces koji podržava vrijeme događaja mora imati način kako mjeriti
napredak vremena događaja. Mehanizam koji mjeri napredak vremena događaja unutar Flink
programa zove se vodeni žig (engl. „Watermark“). Vodeni žig mjeri koliko je vremena prošlo u
nekom „stream-u“. Recimo ako imamo neki prozor koji ima vrijeme trajanja od jedan sat Vodeni

37
žig će nam javiti kada je to vrijeme događaja isteklo i poslije toga taj prozor više neće primati
nove elemente. („Apache Flink documentation“, bez dat.)

Već smo ranije napomenuli da neki elementi dođu izvan reda odnosno da postoji određeno
kašnjenje prilikom prijenosa podataka. Elemente koji dođu nakon što je Vodeni žig označio
istek vremena nazivaju se Kasni elementi (engl. Late elements). Program neće odmah nužno
odbaciti te elemente zato što unutar Flink programa postoji mehanizam koji se zove
„Dozvoljeno kašnjenje“ (engl. Allowed lateness). Dozvoljeno kašnjenje je dopušteno
vremensko kašnjenje elemenata prije nego što elementi budu odbačeni. Početna vrijednosti
Dozvoljenog kašnjenja je nula, ali za svaki program se može odrediti kašnjenje po želji. Ukoliko
elementi dođu izvan tog vremena bit će odbačeni, ali ako dođu unutar tog vremena uzrokovat
će ponovo pokretanje prozora sa novim rezultatima. Kao izlaznu vrijednost dobit ćemo više
rezultata za isti izračun. („Apache Flink documentation“, bez dat.)

Stanje, kontrolna točka i tolerancija greške


Stanje (engl. state) je snimak aplikacije u bilo kome vremenskom periodu koje pamti
informacije o prošlim ulazim ili događajima. Stanje aplikacije može biti korisno za sljedeće
stvari:

• pretraga događaja unutar aplikacije koji su se dogodi do sad,


• treniranje modela za strojno učenje,
• pristup povijesnim podacima,
• ostvarivanje tolerancije na pogrešku preko kontrolne točne, stanje pomaže obnoviti
sustav od pogreške,
• omogućuje paralelno izvršavanje u obavljaju poslova. („Apache Flink documentation“,
bez dat.)

Tolerancija pogreške (engl. Fault tolerance) prilikom pogreške unutar Flink aplikacije
omogućava vratiti stanje kakvo je bilo prije same pogreške unutar programa. Otpornost na
pogrešnu unutar Flink programa omogućava kontrolna točka. Kontrolna točka (engl.
checkpointing) je neprestano snimanje distribuiranih tokova podataka. Svaki snimak čuva
stanje aplikacije u određenom vremenskom periodu. Ovi snimci stanja ne koriste puno resursa
i spremaju se na postojeće skladište, najčešće je to HDFS. („Apache Flink documentation“,
bez dat.)

38
5. Primjer: Algoritam za analizu Twitter podataka
unutar Apache Flink-a

U ovom primjeru će biti prikazano kako možemo povući podatke sa Twittera i na njima
napraviti analizu u realnom vremenu. Kako bismo ovo napravili potrebno je prvo kreirati
programerski Twitter račun koji nam omogućava „streaming“ podataka u našu aplikaciju. Cilj
same aplikacije će biti spremati statuse (engl. Twits) koje u sebi sadrže podatke o potresima
u svijetu. Unutar svakog statusa Twitter nam omogućava da vidimo sa kojeg je uređaja
odnosno operacijskog sustava status napisan. Upravo to će biti iskorišteno kako bi napravili
analizu sa koji uređaja dolazi najviše statusa. Ova analiza može pomoći programerima koji
žele kreirati neku aplikaciju, a nisu sigurni koji operacijski sustav je najbolji za tu aplikaciju.

5.1. Instalacija i konfiguracija Apache Flink-a

Prije same instalacije bitno je napomenuti da Apache Flink najbolje radi na Linux
operacijskom sustavu, stoga ćemo u ovom primjeru instalirati Linux Ubuntu, na Virtualnoj
mašini, na koje će biti instaliran Apache Flink. Postupak instalacije Linux Ubuntu-a se nalazi u
poglavlju Dodaci.

Prvobitno je potrebno instalirati Javu. Za instalaciju Jave je potrebno skinuti zadnju stabilnu
verziju te unutar Linux terminala ukucati sljedeće naredbe:

apt install default-jre


apt install openjdk-11-jre-headless
Nakon toga možemo sa naredbom:

java – version
provjeriti koja verzija je instalirana.

Instalacija Apache Flink-a je također veoma jednostavna. Prvo je potrebno skinuti zadnju
verziju Apache Flink-a i potom u terminal upisati sljedeću naredbu:

tar xzf flink-1.11.2-src.tgz


Nakon instalacije Flink-a, potrebno je pokrenuti „flink klaster“ pomoću naredbe:

./bin/start-cluster.sh
Flink kao i Spark ima svoju nadzoru ploču (engl. Dashboard) u kojoj možemo vidjeti sve
procese koji su pokrenuti ili završeni unutar Flink aplikacije. Na Nadzornoj ploči možemo vidjeti
i logove te tako pratiti rad ili eventualne greške Flink aplikacija.

39
Nadzora ploča se nalazi na web-u i možemo joj pristupiti tako da u web pregledniku ukucamo
sljedeću lokaciju: localhost: 8081. Nakon toga bi trebali dobiti prozor kao na slici ispod.

Slika 22. Apache Flink nadzorna ploča

Ukoliko je navedena lokacija uspješno otvorena Apache Flink je uspješno instaliran i


konfiguriran.

5.2. Prikaz Twitter podataka

Prema službenoj Apache Flink dokumentaciji („Apache Flink documentation“, bez dat.)
svaki Flink program koji radi transformacije nad nekim podaci se sastoji od sljedećih dijelova:

1. Kreiranje okruženja za pokretanje programa (engl. Execution enviroment)


2. Učitavanje ili kreiranje podataka
3. Određivanje transformacija koje će biti primijenjene na podatke
4. Odrediti gdje spremiti rezultate izračuna
5. Pokrenuti program.

Program smo kreirali prema gore navedenim uputama, program je pisan u Java
programsko jeziku pa je zbog toga korištena Eclipse razvojna okolina. Kreirali smo novi projekt
unutar Eclipsa kojeg smo nazvali „P1“. Unutar tog projekta smo kreirali klasu „Use_Case“ u
kojoj se nalazi logika samo programa.

40
Okruženje za pokretanje programa i učitavanje podataka
Pomoću sljedeće naredbe unutar naše klase „Use_Case“ kreiramo okruženje za
„streaming“ podataka:
StreamExecutionEnvironment env =
StreamExecutionEnvironment.getExecutionEnvironment();

Kada smo kreirali okruženje potrebno je prije samog učitavanja podataka unijeti pristupne
podatke koje smo dobili kada smo kreirali aplikaciju na našem programerskom Twitter računu.
To smo napravili pomoću sljedećeg koda:

Properties twitterCredentials = new Properties();


twitterCredentials.setProperty(TwitterSource.CONSUMER_KEY,
"********************");
twitterCredentials.setProperty(TwitterSource.CONSUMER_SECRET,
"*******************");
twitterCredentials.setProperty(TwitterSource.TOKEN,
"*******************");
twitterCredentials.setProperty(TwitterSource.TOKEN_SECRET,
"*******************");

DataStream<String> twitterData = env.addSource(new


TwitterSource(twitterCredentials));

Tek nakon što Twitter potvrdi gore navedene ključeve i tokene te utvrdi da se radi o našoj
aplikaciji i našem Twitter profilu, biti ćemo u mogućnosti povući podatke sa Twitter-a. Nakon
što povučemo podatke spremamo u „datastream“ koji smo nazvali „twitterData“.

41
Filtriranje podataka
Nakon što smo učitali podatke i otvorili smo vezu prema Twitteru, potrebno je raščlaniti i
filtrirati podatke. Za ova dva zadatka su kreirane 4 funkcije:

1. „TweerParse“ učitava podatke i kreirane nove objekte koji će biti u .JSON formatu.

public static class TweetParser implements MapFunction<String, JsonNode>


{
public JsonNode map(String value) throws Exception
{
ObjectMapper jsonParser = new ObjectMapper();
JsonNode node = jsonParser.readValue(value, JsonNode.class);
return node;
}
}
2. „EnglishFilter“ funkcija sprema samo one podatke sa Twittera kod kojih je primarni
jezik engleski.

public static class EnglishFilter implements FilterFunction<JsonNode>


{
public boolean filter(JsonNode node)
{
boolean isEnglish =
node.has("user") &&
node.get("user").has("lang") &&
node.get("user").get("lang").asText().equals("en");
return isEnglish;
}
}
3. „FilterByKeyWords“ funkcija filtrira i sprema samo one podatke koji u sebi sadrže riječi
koje smo definirali u listi koja se zove „keywords“. To zapravo znači da želimo primati
samo one statuse koji u sebi sadrže podatke vezano za potres. Npr. Ukoliko netko
objavi na svom Twitter profilu vezano za potres mi želimo taj status spremiti, ukoliko
ne sadrži te ključne riječi onda nam taj status ne treba.

42
{
final List<String>
keywords=Arrays.asList("earthquake","earthquakes","magnitude","Richter
scale","kilometers","epicenter","depth","sezmiologist","Croatia","world","E
urope","earthquake victims","plate
tectonics","clefts","litosfere","hipocenter","geophysics","Mercalli
scale","sezmiograph","landslide");

public static class FilterByKeyWords implements FilterFunction<JsonNode>


{
private final List<String> filterKeyWords;
public FilterByKeyWords(List<String> filterKeyWords)
{
this.filterKeyWords = filterKeyWords;
}
public boolean filter(JsonNode node)
{
if (!node.has("text"))
return false;
// odabir tweet-ova po ključnim riječima
String tweet = node.get("text").asText().toLowerCase();
return filterKeyWords.parallelStream().anyMatch(tweet::contains);
}
}
4. Zadnja funkcija pomoću koje radimo filtriranje je „ExtractTweetSource“. Ova funkcija
zapravo radi onaj najvažniji dio, provjerava sa kojeg je uređaja odnosno operacijskog
sustava objavljen status koji sadrži ključne riječi o potresima (engl. Tweet). Unutar
našeg programa operacijske sustave smo podijelili na: Android, Apple mobile (ipadm
iphone), Apple Mac, Black Berry, web i „other“. „Web“ se odnosi na statuse koji su
napisani preko web-a sa bilo kojeg operacijskog sustava, „other“ su svi ostali
operacijski sustavi koji se ne nalaze u ovoj podijeli.

public static class ExtractTweetSource implements MapFunction<JsonNode,


Tuple2<String, JsonNode>>
{
public Tuple2<String, JsonNode> map(JsonNode node)
{
String source = "";
if (node.has("source"))
{

43
String sourceHtml = node.get("source").asText().toLowerCase();
if (sourceHtml.contains("ipad")||
sourceHtml.contains("iphone"))
source = "AppleMobile";
else if (sourceHtml.contains("mac"))
source = "AppleMac";
else if (sourceHtml.contains("android"))
source = "Android";
else if (sourceHtml.contains("BlackBerry"))
source = "BlackBerry";
else if (sourceHtml.contains("web"))
source = "Web";
else
source = "Other";
}
return new Tuple2<String, JsonNode>(source, node); //
rezultat (Android,tweet)
}
}
Nakon toga pozove sve kreirane funkcije jednu po jednu kako bi na kraju dobili samo one
vrijednosti koje nam trebaju.

DataStream<JsonNode> parsedData = twitterData.map(new TweetParser());

DataStream<JsonNode> englishTweets = parsedData.filter(new


EnglishFilter());

DataStream<JsonNode> RelevantTweets = parsedData.filter(new


FilterByKeyWords(keywords));
// Format: <source, tweetObject>

DataStream<Tuple2<String, JsonNode>> tweetsBySource =


RelevantTweets.map(new ExtractTweetSource());

Transformacija podataka i spremanje rezultata


Zadnji korak je transformacija podataka. Prvo smo kreirali funkciju „ExtractHourOfDay“
kako bi izvukli samo sate kada je kreiran određenih „Tweet“. Informacija kada je kreiran
određeni „Tweet“ nam je potrebna radi lakšeg ispisa rezultata. Rezultati će biti prikazani tako

44
da nakon svakog sata ponovo krećemo zbrajati sa koji uređaja odnosno operacijskih sustava
je napisan status.

public static class ExtractHourOfDay implements


MapFunction<Tuple2<String, JsonNode>, Tuple3<String, String, Integer>>
{
public Tuple3<String, String, Integer> map(Tuple2<String,
JsonNode> value)
{
JsonNode node = value.f1;
String timestamp = node.get("created_at").asText();
String hour = timestamp.split(" ")[3].split(":")[0] + "th
hour";
return new Tuple3<String, String, Integer>(value.f0, hour,
1);
}
}
Potom smo pozvali tu funkciju i transformirali podatke tako da smo ih prvo grupirali i potom
sumirali tako da dobijemo ime operacijskog sustava i koliko puta je preko tog operacijskog
sustava objavljen status o potresima. Npr. Android, 150.

// Format: <source, hourOfDay, 1>


tweetsBySource.map(new ExtractHourOfDay())
.keyBy(0,1) // groupBy izvor i sat
.sum(2) // suma tweeto-ova iz izvora u određenom satu
.writeAsText("/home/oliver/earthquake.txt");

env.execute("Twitter Analysis");

Na kraju smo rezultat ove analize zapisali u tekstualnu datoteku tako što okinuli naredbu
za pokretanje programa. Kada odemo na novo kreirani folder možemo vidjeti rezultate naše
analize. Na osnovu ovi podataka možemo odrediti koji operacijski sustav je najbolji i tako
donijeti odluku te napravi aplikaciju za potrese za onaj operacijski sustav koji ima najviše
objavljenih statusa. Sljedeća slika nam pokazuje podatke koji su generirani u našoj tekstualnoj
datoteci „earthquake.txt“. „Stream“ podataka je trajao dva sata i dobili smo rezultate da je u
periodu od 8 do 9 sati napisano :

• 462 statusa sa android uređaja


• 256 statusa sa AppleMobile uređaja
• 144 statusa sa Web-a
• 42 statusa sa ostalih uređaja.
45
Slika 23. Prikaz rezultata u vremenskom periodu od 8 do 9 h

Nakon isteka ovog sata brojač se vrati na nulu i ponovo broji rezultate. Tako da u periodu
od 9 do 10 imamo sljedeće rezultate:

• 595 statusa sa Android uređaja


• 251 status sa Apple Mobile uređaja
• 158 statusa sa Web-a
• 43 statusa sa ostalih uređaja.

46
Slika 24. Prikaz rezultata u vremenskom periodu od 9 do 10 h

Unutar ove kratke analize od dva sata možemo zaključiti da je aplikaciju najbolje praviti za
android uređaje, dok su nam Apple Mobile uređaji druga najbolja opcija. Vidimo da se
BlackBerry uređaji ne pojavljuju, a razlog tome je upravo taj što jako mali broj ljudi koristi ove
uređaje. Vidimo također da veliki broj korisnika statuse piše preko web-a, ali ipak je to puno
manji broj u odnosnu na prva dva operacijska sustava.

47
6. Usporedba razvojnih okvira za „Velike podatke“

Tablica 1. Usporedba razvojnih okvira

Apache Hadoop Apache Spark Apache Flink

Godina nastanka 2005 2009 2009

Mjesto nastanka MapReduce (Google) University of California, Technical University of


Hadoop (Yahoo) Berkeley Berlin

Mehanizmi procesiranja Serijski (engl. Batch ) Serijski (engl. Batch ) Protočno, neprekidno
podataka (engl. stream)

Brzina Sporiji od Spark-a i Flink- 100 puta brži od Hadoop- Brži od Spark-a
a a

Programski jezici Java, C, C++, Ruby, Java, Scala, Python, R Java, Scala, R, Python

Groovy, Perl, Python

Model MapReduce Otporni distribuirani skup Ciklični protok podataka


podataka

Upravljanje memorijom Orijentiran na disk Upravljanje pomoću JVM Aktivno upravljanje


(Java Virtual machine)

Kašnjenje Nisko Srednje Nisko

Propusnost Srednja Visoka Visoka

Optimizacija Ručno Ručno Automatski

API Niska-razina Visoka-razina Visoka-razina

„Streaming“ podrška Spark Streaming Flink Streaming

SQL podrška Hive, Impala SparkSQL Table API i SQL

Grafička podrška GraphX Gelly

Podrška za strojno SparkML FlinkML


učenje

(Izvor: Mali, 2020)

Na osnovu navedene tablice možemo vidjeti koje su točno razlike između Spark-a i Flink-a.
Glavna razlika je upravo to što je Flink razvojni okvir koji omogućava procesiranje i obradu
podataka u realnom vremenu, dok Spark radi na nekom konačnom skupu podataka sa
određenim kašnjenjem. Također je bitno napomenuti da su okviri implementirati u različitim
programskim jezicima, Flink je implementiran u Javi, a Spark u Scala programskom jeziku.
Flink je brži u obradi podataka i omogućava aktivno upravljanje memorijom pa se rijetko kad

48
može dogoditi da se memorija zapuni odnosno da ostane bez memorijskom prostora. Ranije
verzije Spark-a nisu imale aktivno upravljanje memorijom, međutim u noviji verzijama je
omogućeno aktivno upravljanje memorijom. Navedeni alati zahtijevaju visoku kvalitetu
hardvera i mnogo RAM-a. Oba razvoja okvira sadrže podršku za strojno učenje, kao i grafičku
podršku te podršku za SQL. Kako se može vidjeti na primjerima iznad, navedena svojstva se
koriste u obliku knjižica (engl. Libarires) koje sadrže klase i algoritme koje možemo koristit za
implementaciju grafova, SQL upita te kreiranje algoritama za strojno učenje.

49
7. Zaključak

U ovom radu predstavljena su dva okvira za analizu podataka Apache Spark i Apache
Flink. Okviri su korišteni kroz dva različita pristupa, Apache Spark smo koristili za serijsku
obradu podataka odnosno za obradu i analizu podataka preko izvora koji se ne mijenja, dok
smo Apache Flink koristili za obradu toka podataka u realnom vremenu. Kako su navedeni
alati slojevite arhitekture, pomoću Spark-a smo prikazali SQL model i model strojnog učenja,
dok smo pomoću Flink-a prikazali „data streaming“ model. Također jako bitno je napomenuti
da su alati dostupni u više programski jezika kao što su: Scala, Java i Python te da su oba
alata besplatna. Prvi algoritam za prikaz stanja i predikciju broja oboljelih je pisan u Python-u,
dok je algoritam za obradu Twitter podataka napisan u Java programskom jeziku. Osim toga,
navede su razlike između ova dva alata i možemo zaključiti da je Flink brži i pouzdani alat za
obradu podataka u realnom vremenu.

Količina digitalnih podataka nekontrolirano raste stoga alati poput Flink-a i Spark-a
predstavljaju budućnost obrade i analize podataka. Kako i puno puta do sada, kako bi se
prilagodili društvenim i tehnološkim promjenama ljudi konstanto moraju stjecati nova znanja i
vještine. Podatkovna znanost je mlada znanost i sigurno će se u idući nekoliko godina dodatno
razvijati. Znanja poput programiranja i analize podataka u navedenim ili nekim drugim alati su
definitivno zanimanja budućnosti.

50
Popis literature

1. Dayananda, S. (2019). What is Apache Spark? Preuzeto 29.08.2019. s


https://www.edureka.co/blog/spark-tutorial/#What_Is_Apache_Spark
2. General Networks (15.03.2015) „Big data important“. Preuzeto 29.08.2019 s
https://gennet.com/big-data/big-data-important/
3. Hien Luu (2018). Beginning Apache Spark 2: With Resilient Distributed Datasets, Spark
SQL, Structured Streaming and Spark Machine Learning library. USA: Apress.
4. White T. (2010). Hadoop: The Definitive Guide, 2nd Edition. USA: O' Reill Media, Inc.
5. Apache Spark „RDD Programming Guide“ preuzeto 06.09.2019 s
http://spark.apache.org/docs/latest/rdd-programming-guide.html#resilient-distributed-
datasets-rdds
6. Strojno čitljivi podaci preuzeto 08.09.2020 s https://www.koronavirus.hr/otvoreni-
strojno-citljivi-podaci/526
7. Apache Flink Documentation „Flink-docs-stable“ preuzeto 08.09.2019 s
https://ci.apache.org/projects/flink/flink-docs-stable/
8. Edureka (26.05.2016). Introduction to Apache Flink | Edureka [Video file]. Preuzeto
12.09.2019 s https://www.youtube.com/watch?v=BtL_WxAo1W8&t=1819s
9. Adrian Umam (05.12.2017). 01 Install and Setup Apache Spark 2.2.0 Python in
Windows – PySpark | [Video file].
Preuzeto 06.09.2020 s
https://www.youtube.com/watch?v=WQErwxRTiW0&ab_channel=ArdianUmam
10. Tanmay Deshpande (2017). Learning Apache Flink. UK: Packt Publishing.
11. Jan Šnajder (2017). Linearan model regresije preuzeto 23.12.2020 s
https://www.fer.unizg.hr/_download/repository/SU-Regresija.pdf
12. Ivan Šošić (2004). Primijenjena statistika. Zagreb: Školska knjiga
13. Dikshant Mali (2020) Big Data Frameworks – Hadoop vs Spark vs Flink Preuzeto
26.12.2020 s https://www.geeksforgeeks.org/big-data-frameworks-hadoop-vs-spark-
vs-flink/
14. Andy Konwinski; Holden Karau; Patrick Wendell; Matei Zaharia (2015). Learning
Spark. O'Reilly Media
15. Dana-Flair „Flink Tutorial – A Comprehensive Guide for Apache Flink“ preuzeto
13.01.2021 s https://data-flair.training/blogs/flink-tutorial/

51
16. Apache Spark Ecosystem [slika] (bez dat.) preuzeto 14.01.2021 s
https://www.analyticsvidhya.com/blog/2020/11/introduction-to-spark-streaming-add-
new-tag/
17. Kornelije Rabuzin (2011). Uvod u SQL Varaždin: Fakultet organizacije i informatike
18. Maleković, M., Rabuzin K. (2016). Uvod u baze podataka. Varaždin etc.: Fakultet
organizacije i informatike etc.
19. Rabuzin, K. (2014). SQL : napredne teme. Varaždin: Fakultet organizacije i informatike.
20. Routray S. (2020) Machine Learning : Linear Regression using Pyspark preuzeto
19.01.2021 s https://towardsdatascience.com/machine-learning-linear-regression-
using-pyspark-9d5d5c772b42

52
Dodaci

A. Instalacija Ubuntu Linux-a na Oracle virtualnoj mašini

Za instalaciju Linux-a na virtualnoj mašini prvo je potrebno skinuti Oracle virtualnu mašinu
sa sljedeće stranice: https://www.virtualbox.org/wiki/Downloads. Zatim je potrebno skinuti
zadnju verziju Ubuntu Linux-a sa sljedeće stranice: https://ubuntu.com/download/desktop.
Bitno je da skinete 64-bitnu LTS verziju sa navedene stranice.
Nakon što smo preuzeli instalacijske pakete možemo pokrenuti virtualnu mašinu. Kada je
mašina pokrenuta odaberemo opciju „New“ kako je prikazano na slici ispod.

Slika 25. Konfiguracija virtualne mašine

Nadalje je potrebno obarati redom sljedeće opcije:

• „Keep the memory to 4 GB (recommended)“.


• „Create a virtual hard drive now“.
• „VDI (VirtualBox Disk Image)“
• „Dynamically allocated“
• „Give the memory 40 GB ( you can give more)“
• „Click on Settings as shown in image.“
Nakon što odredite performanse vaše mašine potrebno je odabrati operacijski sustav
koji želite instalirati na tu mašinu. Odaberete opciju „Settings“ i unutar te opcije kliknete na

53
opciju „Storage“ → Controlloer:IDE → Choose disk i odaberete Linux LTS datoteku koju ste
prethodno skinuti.

Slika 26. Odabir operacijskog sustava na VM

Nakon toga jednostavno pokrenete svoju virtualnu mašinu i odaberete vremensku zonu, jezik
i naziv vaše računala. Nakon što Linux završi sa instalacijom obavezno ponovo pokrenite vašu
mašinu i time je instalacijski postupak završio.

54
B. Popis slika

Slika 1. Količina podataka na društvenim mrežama koja se generira u jednoj minuti


(Dayananda, 2019). .................................................................................................... 3
Slika 2. Komunikacija Spark aplikacije i Cluster managera (Luu, 2018) ..................... 5
Slika 3. Spark klaster sa tri izvršitelja (Luu,2018) ....................................................... 6
Slika 4. Spark ekosustav (Apache Spark Ecosystem, bez dat.) ................................. 7
Slika 5. Napredne postavke u Windows operacijskom sustavu ................................ 10
Slika 6. Opcije unutar naprednih postavki u Windows10 .......................................... 11
Slika 7. Dodavanje novih varijabli ............................................................................. 12
Slika 8. Spark verzija ................................................................................................ 13
Slika 9. Tablica Županije........................................................................................... 15
Slika 10. Tablica Osobe ............................................................................................ 16
Slika 11. Tablica zaraženih Hrvatska ........................................................................ 17
Slika 12. Broj aktivnih slučajeva u RH ...................................................................... 19
Slika 13. Broj zaraženih slučajeva u RH ................................................................... 20
Slika 14. Broj umrlih slučajeva u RH ......................................................................... 21
Slika 15. Postotak oboljelih prema spolu .................................................................. 22
Slika 16. Postotak oboljelih prema dobi .................................................................... 23
Slika 17. Tablica koronavirus .................................................................................... 26
Slika 18. Podjela podataka na testne i trening podatke ............................................ 28
Slika 19. Slika 19. Rezultat predikcije ....................................................................... 29
Slika 20. Apache Flink Ekosustav (Apache Flink Tutorial- Ecosystem Components,
bez dat.).................................................................................................................... 31
Slika 21. Pokretanje Flink programa (Deshpande, 2017) ......................................... 33
Slika 22. Apache Flink nadzorna ploča ..................................................................... 40
Slika 23. Prikaz rezultata u vremenskom periodu od 8 do 9 h .................................. 46
Slika 24. Prikaz rezultata u vremenskom periodu od 9 do 10 h ................................ 47
Slika 25. Konfiguracija virtualne mašine ................................................................... 53
Slika 26. Odabir operacijskog sustava na VM .......................................................... 54

C. Popis tablica

Tablica 1. Usporedba razvojnih okvira ..................................................................................48

55

You might also like