Sunteți pe pagina 1din 21

ISI - Seminar 1

Conf. Univ. Dr. Diaconița Vlad


Activități:

 Rulare Hadoop (distribuția Hortonworks)


 Colectare date folosind Apache Flume.
 Utilizarea soluției tip depozit de date Hive și limbajul HiveQL
Unde este marcat Print Screen sau Interogare veți include propriile rezultate.

Obs. Masina virtuala poate fi descarcata de aici: http://hortonworks.com/downloads/#sandbox Când


importăm mașina virtuală in Virtualbox (Ctrl-A), selectăm Base Memory minim 4096 MB.

Se pornește mașina virtuală din Virtual Box.

In setarile de proxy are navigatorului, excludem 127.0.0.1


Ne conectăm din browser la IP-ul: http://127.0.0.1:8080

User: maria_dev

Parola: maria_dev

Figura 1 Conectare in Ambari

După autentificare, din meniul Start, alegem HDFS Files.

Navigăm folosind HDFS Files în /user/<banuta_adriana>. Dacă directorul nu există îl putem construi
folosind opțiunea New directory (dreapta-sus).

Înlocuiți in document banuta_adriana cu numele si prenumele vostru


folosind Find and Replace in Word (crtl-h). Capturile de ecran vor
contine doar fereastra in cauza si vor include, unde exista, nume si
prenumele provenit de la denumirea directoarelor (in caz contrar, nu
vor fi punctate).
Un cluster HDFS este alcătuit dintr-un nod central (NameNode) care gestionează metadatele, un nod
central secundar și mai multe noduri pe care sunt stocate datele (DataNode). În cazul unui cluster, zona
HDFS este distribuită pe nodurile care alcătuiesc clusterul, existând un factor de replicare ce reprezintă
numărul de noduri pe care se află fiecare bloc de date în parte.

Pentru exemplele următoare, voi folosi în HDFS calea /user/banuta_adriana.

Figura 2 Navigare in HDFS folosind Ambari

Selectăm Upload și încărcăm fișierul example.xml.

In arhivă există aplicația foxe.exe care poate fi folosită pentru vizualizarea fișierelor XML.

Folosind un client de SSH, spre exemplu Putty


(http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html) , ne conectăm la 127.0.0.1, port
2222
Figura 3 Autentificare folosind Putty

Putem folosi și clientul SSH web: http://127.0.0.1:4200/

Utilizator: root
Parola: masterbdsa

Figura 4 Autentificare folosind interfața web – http://127.0.0.1:4200

Putem considera HDFS o partiție separată de sistemul local de fișiere (al MV cu linux) care poate fi
accesată folosind interfața web sau instrucțiuni din linia de comandă de tipul hdfs dfs. Spre exemplu,
pentru a afișa fișierele și directoarele din rădăcina HDFS putem folosi următoarea comandă:
hdfs dfs -ls /
Construirea unui director în HDSF se poate realiza astfel:

hdfs dfs -mkdir NumeDirector


Verificarea integrității HDFS se poate realiza astfel:

hdfs fsck /
Pentru a copia un fișier din sistemul de fișiere gazdă în directorul /user/banuta_adriana din HDFS se
poate folosi următoarea comandă:

hdfs dfs -put denumire_fisier /user/banuta_adriana


Copiem fisierul XML din HDFS în sistemul local de fișiere:

hdfs dfs -get /user/banuta_adriana/example.xml


Toate argumentele comenzii hdfs dfs sunt explicate pe pagina oficială Hadoop:
https://hadoop.apache.org/docs/r2.4.1/hadoop-project-dist/hadoop-common/FileSystemShell.html

Vom edita (cu Notepad) fișierul flume_example.conf din arhivă, rândul:

hdfs-agent.sinks.hdfs-write.hdfs.path = /user/banuta_adriana/flume

Fișierul va fi creat pe mașina virtuală folosind vi, astfel:

 Putem afla directorul curent folosind pwd


 vi flume_example.conf
 intrăm în insert mode apăsând i
 facem copy-paste la textul fișierului de configurare (flume_example.conf) – Atentie:
asigurați-va că s-a copiat tot conținutul fișierului de configurare (se mai întâmplă să se
truncheze)
 ieșim din insert mode cu Esc
 salvăm cu :w și ieșim cu :q

Rulam: cat flume_example.conf


Print Screen
Construim directorul flume în HDFS:

hdfs dfs -mkdir /user/banuta_adriana/flume


Pornim agentul Flume: Commented [V1]: Atenție: Dacă lucrează două persoane
pe același cont, toți pașii până la pornirea lui Hive vor trebui
realizați mai întâi de o persoană iar mai apoi, de cealaltă
flume-ng agent -n hdfs-agent -f ./flume_example.conf persoană.
Print Screen
Commented [V2]: Flume este o soluție pentru colectare,
agregare și încărcare de volume mari de date. Mai multe
informații despre Flume puteți găsi aici:
https://flume.apache.org/
Îl lăsăm pornit. Deschidem în paralel o nouă conexiune SSH folosind Putty sau interfața web
(root/parola). Trimitem loturi către agentul flume care ascultă pe portul 11111 și care scrie ceea ce
primește în hdfs în directorul configurat mai sus hdfs-agent.sinks.hdfs-write.hdfs.path =
/user/banuta_adriana/flume

Trimitem primele 20 de rânduri din fișierul XML:

head -n 20 example.xml | nc localhost 11111


În sesiunea în care rulează flume, se vor afișa mesaje precum următoarele (in funcție de versiune și
configurări e posibil ca mesajele să nu apară și la consolă și doar in /var/log/flume/flume.log):

18/01/12 14:21:41 INFO hdfs.HDFSDataStream: Serializer = TEXT,


UseRawLocalFileSystem = false
18/01/12 14:21:41 INFO hdfs.BucketWriter: Creating
/user/banuta_adriana/flume/FlumeData.1515766901227.tmp
18/01/12 14:21:44 INFO hdfs.BucketWriter: Closing
/user/banuta_adriana/flume/FlumeData.1515766901227.tmp
18/01/12 14:21:44 INFO hdfs.BucketWriter: Renaming
/user/banuta_adriana/flume/FlumeData.1515766901227.tmp to
/user/banuta_adriana/flume/FlumeData.1515766901227
18/01/12 14:21:44 INFO hdfs.BucketWriter: Creating
/user/banuta_adriana/flume/FlumeData.1515766901228.tmp
18/01/12 14:21:44 INFO hdfs.BucketWriter: Closing
/user/banuta_adriana/flume/FlumeData.1515766901228.tmp
18/01/12 14:21:44 INFO hdfs.BucketWriter: Renaming
/user/banuta_adriana/flume/FlumeData.1515766901228.tmp to
/user/banuta_adriana/flume/FlumeData.1515766901228
18/01/12 14:21:44 INFO hdfs.BucketWriter: Creating
/user/banuta_adriana/flume/FlumeData.1515766901229.tmp
18/01/12 14:21:44 INFO hdfs.BucketWriter: Closing
/user/banuta_adriana/flume/FlumeData.1515766901229.tmp
18/01/12 14:21:45 INFO hdfs.BucketWriter: Renaming
/user/banuta_adriana/flume/FlumeData.1515766901229.tmp to
/user/banuta_adriana/flume/FlumeData.1515766901229
18/01/12 14:21:45 INFO hdfs.BucketWriter: Creating
/user/banuta_adriana/flume/FlumeData.1515766901230.tmp […]
Putem vizualiza lista fișierelor create:

hdfs dfs -ls /user/banuta_adriana/flume


Vizualizarea conținutului unui fișier (se va folosi unul dintre fișierele returnate de comanda anterioară):

hdfs dfs -cat


/user/banuta_adriana/flume/FlumeData.1479745518581
Print Screen
Următoarele 30 de rânduri:

sed '20,50!d' example.xml | nc localhost 11111


Restul de rânduri:

head -n -50 example.xml | nc localhost 11111


Procesul durează câteva minute (poate fi întrerupt folosind CTRL-C). Putem vizualiza încă o dată fișierele
create de către flume, sau le putem număra:

hdfs dfs -count /user/banuta_adriana/flume


Ar trebui sa fie peste 6800 de fișiere.

Oprim flume-ng (ctrl+c).

Pornim Hive din linia de comandă:

hive
Hive este o soluție open-source pentru gestionarea depozitelor de date care rulează într-un mediu
Hadoop. Datele în Hive sunt organizate în tabele care pot fi partiționate în bucăți mai ușor de gestionat.
Hive implementează un limbaj de interogare tip SQL denumit HiveQL.

În Hive există două tipuri de tabele: interne (numite și managed) și externe. Cele interne (tipul implicit)
sunt create într-un subdirector din directorul declarat în parametrul hive.metastore.warehouse.dir din
hive-site.xml (stocat în /etc/hive/2.4.0.0-169/0/hive-site.xml pentru versiunea folosită în acest seminar).
Implicit acest director este: /apps/hive/warehouse.
Tabelele sunt organizate în baze de date, acestea fiind mai degrabă un catalog de tabele. Baza de date
implicită este default iar tabelele sale sunt construite în rădăcina directorului implicit. Putem crea o nouă
bază de date folosind comanda:

CREATE DATABASE [IF NOT EXISTS] <nume_baza_de_date>;


La construirea unei baze de date se va crea un nou subdirector în directorul implicit.

Afișare baze de date:

SHOW DATABASES;
Afișare director bază de date:

DESCRIBE DATABASE <nume_baza_de_date>;


Selectare bază de date:

USE <nume_baza_de_date>;
Afișare tabele din baza de date curentă:

SHOW TABLES;
Afișare coloane dintr-o tabelă:

DESCRIBE <nume_tabela>;
Când se șterge o tabelă internă (drop nume_tabelă), Hive va șterge automat și fișierele de date, nu
același lucru se întâmplă pentru tabelele externe. Ambele tipuri de tabele pot fi procesate și cu alte
utilitare (spre exemplu Pig) dar tabelele interne aparțin lui Hive iar procesarea lor cu alte utilitare poate fi
mai dificilă din cauza drepturilor de acces. Pentru a vedea tipul unei tabele, putem folosi comanda
DESCRIBE EXTENDED <nume_tabelă>:
 ... tableType:MANAGED_TABLE) -> tabele interne
 ... tableType:EXTERNAL_TABLE) -> tabele externe

Construim tabela flume_example în baza de date default care va avea pe fiecare rând câte un rând din
fișierele din /user/banuta_adriana/flume_example:

hive>
CREATE EXTERNAL TABLE IF NOT EXISTS flume_example (record
string)
ROW FORMAT DELIMITED
LINES TERMINATED BY '\n'
LOCATION '/user/banuta_adriana/flume';
Durează cam 40 de secunde.

Afișam primele 10 rânduri:

select * from flume_example limit 10;


Print Screen

Dacă dorim să vizualizăm și fișierul din care provine fiecare rând:

select INPUT__FILE__NAME,
f.* from flume_example f limit 3;
hdfs://sandbox.hortonworks.com:8020/banuta_adriana/flume/FlumeD
ata.1479745518580 <record><Customer>Jolie A.
Hoffman</Customer><Email>lectus@vulputateeu.edu</Email><Purchas
eDate>1368111464</PurchaseDate><Price>472</Price><FlightsAvaila
ble>97, 13</FlightsAvailable></record>
hdfs://sandbox.hortonworks.com:8020/banuta_adriana/flume/FlumeD
ata.1479745518580 <record><Customer>Leroy J.
Fox</Customer><Email>mattis.ornare.lectus@Vestibulumanteipsum.o
rg</Email><PurchaseDate>1335377562</PurchaseDate><Price>203</Pr
ice><FlightsAvailable>7, 67, 41, 43,
3</FlightsAvailable></record>
hdfs://sandbox.hortonworks.com:8020/banuta_adriana/flume/FlumeD
ata.1479745518580 <record><Customer>Evangeline Z.
Davenport</Customer><Email>Sed.malesuada.augue@consectetuereuis
modest.org</Email><PurchaseDate>1383190668</PurchaseDate><Price
>611</Price><FlightsAvailable>97,
67</FlightsAvailable></record>
Print Screen
Pentru a vizualiza data achiziției (UNIX TIMESTAMP) și zborurile disponibile la acel moment:

SELECT xpath_int(record, "/record/PurchaseDate"), Commented [V3]: Extragem PurchaseDate din fiecare


înregistrare XML
xpath_string(record, "/record/FlightsAvailable") FROM
Commented [V4]: Extragem FlightsAvailable din fiecare
flume_example limit 30; înregistrare XML
Pentru a converti UNIX TIMESTAMP (număr de secunde trecute de la 01.01.1970) în format DATE putem
folosi funcția from_unixtime:

SELECT from_unixtime(xpath_int(record,
"/record/PurchaseDate")), xpath_string(record,
"/record/FlightsAvailable") FROM flume_example limit 30;
Putem ordona după PurchaseDate:

SELECT from_unixtime(xpath_int(record, "/record/PurchaseDate"))


a, xpath_string(record, "/record/FlightsAvailable") b FROM
flume_example order by a desc limit 30;
E posibil să primim un mesaj care ne anunță că nu avem destulă memorie (java.lang.OutOfMemoryError:
Java heap space). O soluție ar fi să schimbăm motorul de execuție din Tez (mai rapid dar și mai
consumator de resurse, implicit pentru Hive) în MapReduce (rulam si daca nu am primit eroarea de
memorie):

set hive.execution.engine=mr;
Rulăm din nou interogarea (obervam diferenta fata de Tez).

Mai multe informații despre Tez putem găsi aici: http://hortonworks.com/apache/tez/


Pentru a construi o tabelă pe baza unei interogări:

CREATE TABLE flight_arrays AS SELECT xpath_string(record,


"/record/Customer") as customer, xpath_int(record,
"/record/PurchaseDate") as purchase_date,
split(xpath_string(record, "/record/FlightsAvailable"), ",") as Commented [V5]: Se va construi o listă având separatorul
virgulă care conține zborurile disponibile
available_flights FROM flume_example;
Dureaza peste 110 secunde.

După ce s-a creat și tabela, revenim la Tez:

set hive.execution.engine=tez;
Pentru a afla de câte ori a fost oferit fiecare zbor la o dată anume:

SELECT FROM_UNIXTIME(purchase_date), flight_no,


COUNT(flight_no) FROM flight_arrays LATERAL VIEW Commented [V6]: Reprezintă de câte ori a fost oferit
zborul flight_no la data respectivă
explode(available_flights) flight_table as flight_no GROUP BY
Commented [V7]: Face joncțiune între rezultatul
FROM_UNIXTIME(purchase_date), flight_no; interogării principale și rezultatul aplicării lui EXPLODE pe
lista de zboruri
Print Screen
Commented [V8]: Transformă lista într-o tabelă in-line
având o coloană și atâtea rânduri câte valori sunt în listă
(lista de zboruri disponibile)

Exerciții:

- Afișați doar primele 30 rânduri în ordinea descrescătoare a numărului de câte ori a fost oferit un
zbor la o data anume – interogare + print screen
SELECT FROM_UNIXTIME(purchase_date), flight_no,

COUNT(flight_no) FROM flight_arrays LATERAL VIEW explode(available_flights) flight_table as flight_no

GROUP BY FROM_UNIXTIME(purchase_date), flight_no

ORDER BY flight_no DESC

LIMIT 30;

- Să se afișeze datele când un anumit zbor a fost oferit de 4 ori – interogare + print screen

Nu au fost returnate rezultate pentru un zbor oferit de 4 ori.


SELECT FROM_UNIXTIME(purchase_date), flight_no,

COUNT(flight_no) FROM flight_arrays LATERAL VIEW explode(available_flights) flight_table as flight_no

GROUP BY FROM_UNIXTIME(purchase_date), flight_no

HAVING flight_no = 4;

Putem folosi Hive și din interfața web (Apache Ambari http://127.0.0.1:8080/ )

În directorul <banuta_adriana> din HDFS încărcăm fișierul descărcat de aici (dezarhivat):


https://s3.amazonaws.com/hw-sandbox/tutorial1/NYSE-2000-2001.tsv.gz
După aceea, selectăm Hive View (sub Files View):

Figura 5 Hive din Ambari

Hive suportă comenzile LMD (daca se activeaza ACID): INSERT, UPDATE, DELETE. Încărcarea unui volum
mai mare de date putându-se realiza și folosind comanda LOAD DATA.

Putem scrie instrucțiuni și le vom executa, selectând instrucțiunea și apăsând mai apoi butonul Execute:

 create database cotatii;


 use cotatii;
 create table cotatii_nyse_2010 (stock_exchange string, stock_symbol string, tdate string,
stock_price_open float, stock_price_high float, stock_price_low float, stock_price_close float,
stock_volume bigint, stock_price_adj_close float) ROW FORMAT DELIMITED FIELDS TERMINATED
by '\t' stored as textfile tblproperties ("skip.header.line.count"="1"); Commented [V9]: Primul rand contine numele coloanelor
 LOAD DATA INPATH '/banuta_adriana/NYSE-2000-2001.tsv' OVERWRITE INTO TABLE
cotatii.cotatii_nyse_2010;

Figura 6 Instrucțiuni HiveQL

Notă: Din cauza drepturilor de acces, ultima instrucțiune va rula doar din interfața web, nu și din linia de
comandă, unde se va primi eroarea:

Loading data to table cotatii.cotatii_nyse_2010


chmod: changing permissions of
'hdfs://sandbox.hortonworks.com:8020/apps/hive/warehouse/cotati
i.db/cotatii_nyse_2010/NYSE-2000-2001.tsv': Permission denied.
user=banuta_adriana is not the owner of inode=NYSE-2000-
2001.tsv
Putem testa câteva instrucțiuni SQL:

 describe cotatii.cotatii_nyse_2010;
 select * from cotatii.cotatii_nyse_2010 limit 10;
 select stock_symbol, round(avg(stock_volume),2) avg_stock from cotatii.cotatii_nyse_2010
group by stock_symbol;
 select stock_symbol, round(avg(stock_volume),2) avg_stock from cotatii.cotatii_nyse_2010
group by stock_symbol having round(avg(stock_volume),2) >50000;
Print Screen
 select c.tdate data_cotatie,CURRENT_DATE data_curenta,
CAST(datediff( from_unixtime( unix_timestamp() ), from_unixtime( unix_timestamp(c.tdate,
'YYYY-MM-DD'))) / 365 AS INT) nr_ani from cotatii.cotatii_nyse_2010 c limit 100;
 select * from cotatii.cotatii_nyse_2010 where stock_volume= (select max(stock_volume) from
cotatii.cotatii_nyse_2010); -- nu merge, Hive nu acceptă funcții de grup în sub-interogări, poate
fi rescrisă astfel:
o select c.* from cotatii.cotatii_nyse_2010 c join (select max(stock_volume) max_v from
cotatii.cotatii_nyse_2010) m where c.stock_volume=m.max_v;
sau
o select * from cotatii.cotatii_nyse_2010 order by stock_volume desc limit 1;

Print Screen

Exerciții:

1. Folosind tabela cotatii.cotatii_nyse_2010, să se afișeze pentru simbolul AIT, cotațiile pentru zilele
în care volumul tranzacționat (stock_volume) este mai mare decât media pentru AIT.
2. Să se genereze de pe site-ul BNR o serie de date zilnice pentru cursul valutar:
http://www.bnr.ro/Baza-de-date-interactiva-604.aspx#.
Fișierul se va genera în format CSV și va fi transformat folosind Excel sau alt instrument în Tab
Separated File. Cu un editor de text (notepad sau vi) se vor elimina primele 4-5 rânduri (până la
rândul care începe cu Data). Se va încărca fișierul în HDFS folosind File Browser și se va construi,
folosind o instrucțiuni CREATE TABLE, o tabelă cotatii_bnr în baza de date cotatii. Datele se vor
încărca cu LOAD DATA. Observație: pentru ca datele numerice sa fie corect încărcate este
necesar ca virgula să fie înlocuită cu punct în fișierul text, înainte de a fi încărcat. Daca
separatorul dintre campuri nu este TAB ci ; sau , se va folosi CREATE TABLE ... FIELDS
TERMINATED BY '\;' ... – Instrucțiune CREATE TABLE + LOAD

create table cotatii.bnr(Data string, CURSZ_AUD float, CURSZ_CAD float, CURSZ_CHF float,
CURSZ_CZK float, CURSZ_DKK float, CURSZ_EGP float, CURSZ_EUR float, CURSZ_GBP float,
CURSZ_HUF float, CURSZ_JPY float, CURSZ_MDL float, CURSZ_NOK float, CURSZ_PLN float,
CURSZ_SEK float, CURSZ_TRY float, CURSZ_USD float, CURSZ_XAU float, DST_CURSZ_XDR float,
URSZ_RUB float, CURSZ_SKK float, CURSZ_BGN float, CURSZ_ZAR float, CURSZ_BRL float,
CURSZ_CNY float, CURSZ_INR float, CURSZ_KRW float, CURSZ_MXN float, CURSZ_NZD float,
CURSZ_RSD float, CURSZ_UAH float, CURSZ_AED float, CURSZ_HRK float, CURSZ_THB float)
ROW FORMAT DELIMITED FIELDS TERMINATED by '\t' stored as textfile tblproperties
("skip.header.line.count"="1");
LOAD DATA INPATH '/banuta_adriana/bnr_good.csv' OVERWRITE INTO TABLE cotatii.bnr;

3. Folosind HiveQL să se afișeze media cotațiilor pentru EUR -Interogare

select avg(cursz_eur) from cotatii.bnr;

4. Folosind HiveQL să se afișeze media cotațiilor pentru USD în anul 2014 –Interogare

select avg(cursz_usd) from cotatii.bnr

where year(to_date(from_unixtime(UNIX_TIMESTAMP(data,'dd.MM.yyyy')))) = 2014;


5. Să se afișeze datele pentru care cursul AUD este mai mare decât cel pentru CAD -Interogare

select to_date(from_unixtime(UNIX_TIMESTAMP(data,'dd.MM.yyyy')))

from cotatii.bnr where cursz_aud > cursz_cad;

Bibliografie:

 Oracle Academy's Data Science Bootcamp – Bootcamp 1


 Hortonworks tutorials
 Edward Capriolo, Dean Wampler, and Jason Rutherglen, Programming Hive, O’Reilly Media, 2012

S-ar putea să vă placă și