Cloudera Impala
Cloudera Impala čini jedan moćan SQL engine za paralelnu obradu ogromnih količina podataka na klasteru. Da bi smo što približnije objasnili šta je Cloudera Impala i kako ona radi, osvrnimo se na Apache Hadoop sistem. Cloudera je jedna od platformi koja pruža usluge korišćena Apache Impale kao i drugih projekata vezanih za Hadoop tako da ćemo u nastavku dokumenta poistovetiti pojmove Cloudera Impala i Apache Impala.
Sadržaj
Hadoop
Apache Hadoop, kao sofverska platforma za distribuirano skladištenje i obradu ogromnih količina podataka (petabajti podataka) sastoji se iz servisa koje pružaju razne mogućnosti upravljanja tim istim podacima. Zbog raznolikosti korisnika koji koriste ovu platformu u pogledu željenog vremena odziva ili raznolikosti potrebnih informacija za njihovo poslovanje/istraživanje, nad njom je razvijeno i nekoliko alata koji su tim potrebama prilagođeni. Dakle hadoop možemo posmatrati kao skup servisa i alata.
Podsetimo se arhitekture hadoop-a. U osnovi hadoop-a nalaze se HDFS (Hadoop Distributed File System) i MapReduce. HDFS je zadužen za čuvanje velikih količina podataka, a MapReduce sistem, pisan u Javi, za njihovu obradu i transformaciju. Ove komponente mogu biti multiplicirane preko više čvorova kreirajući hadoop klaster.
Govoreći o pojedinačnim čvorovima MapReduce server se još zove i TaskTracker koji je zadužen za pokretanje zadatka na određenom čvoru. HDFS server naziva se DataNode i on obezbeđuje velike propusne kapacitete za pristup podacima. Jedan TaskTracker i DataNode čine jednu celinu.
Za upravljanje MapReduce poslovima na različitim mašinama koristi se JobTracker čiji je zadatak balansiranje opterećenja i dodeljivanje poslova različitim TaskTracker-ima. Još jedan od zadataka JobTracker-a je da vodi računa o tome da li su svi TaskTracker-i dostupni, pa da u slučaju kvara prebaci zadatak na drugi čvor. Svaki TaskTracker javlja JobTracker-u o uspešnom ili neuspešnom izvršenju upita. Slično, upravljač DataNode-ova zove se NameNode. NameNode se brine o lokacijama podataka i informaciju o lokaciji prosleđuje korisniku. Dakle sam transfer podataka ne obavlja se kroz NameNode, njegova svrha je da koordinira.
Važni alati koji hadoop koriste kao osnovu su:
- Apache Pig
- Apache Hive
- Apache Impala
Apache Pig se može smatrati skripting platformom koja korisnicima hadoop-a omogućava da čak i sa osnovnim znanjem o programiranju pišu kompleksne programe za manipulaciju podacima. Pig ove programe pisane u takozvanom Pig Latin jeziku, koji dosta smanjuje obim koda, prevodi u MapReduce zadatke.
Apache Hive razvijen od strane Facebook-a je alat dizajniran za data warehouse sisteme u cilju olakšanja kompleksnih upita nad ogromnim količinama podataka. Data warehouse možemo zamisliti kao veliko skladište koje prikuplja podatke sa više različitih izvora koje uglavnom čine transakcione aplikacije. Hive je zadužen za izvlačenje, transformaciju i smeštanje (engl. ETL) ovih podatka kao i njihovu obradu i analizu, u procesu u kojem pouzdanost podataka veoma bitna. Hive pomaže u agregaciji i analizi ovih podataka korišćenjem HiveQL-a, jezika koji je sličan SQL-u. Kao i Pig, Hive svoje upite prevodi u MapReduce zadatke.
Jedan od bitnih pojmova za Hive infrastrukturu je Hive MetaStore Database. MetaStore je relaciona baza koja sadrži informacije o Hive bazama, tabelama, kolonama, kao i informacije vezane za samu srž hadoop-a tj. informacije o lokacijama blokova podataka na HDFS-u.
Apache Impala za sada pruža najbrže vreme pristupa podacima na HDFS-u. Impala kao i Hive koristi jezik sličan SQL-u, pored čega takođe ima prisutup podacima u MetaStore bazi. Međutim, za razliku od Pig-a i Hive Impala svoje upite ne prevodi u MapReduce zadatke već direktno pristupa podacima sa HDFS-a.
U nastavku teksta proći ćemo korake koji se tiču instalacije jednog manjeg testnog okruženja, a zatim ćemo proći kroz primere i videti kako se performanse Apache Impale porede sa performansama Apache Hive-a. Razmotrimo prvo najvažnije komponente ovog alata.
Osnovne komponente
Glavna komponenta Impale je pozadinski proces pokrenut na svakome od čvorova sa podacima (HDFS DN – Data Node), takozvani impalad proces. Kada se zahtev uputi nekom čvoru u klasteru, impala servis za taj čvor postaje koordinator upita i bavi se njegovom distribucijom i izvršavanjem, prikupljajući posebne rezultate sa svih ostalih čvorova u klasteru.
Kao koordinator svih impalad procesa StateStore komponenta vodi računa o njihovom statusu. U slučaju kvara na nekom od čvorova statestored proces obaveštava sve ostale impalad procese da ne bi došlo do situacije u kojoj impalad pokušava upit da distribuira na nepostojeći čvor. Dakle StateStore komponenta u sebi sadrži mehanizam za broadcast poruka.
Naime da bi svaki impalad proces mogao da izvršava upite, on mora biti svestan o svim promenama nad meta podacima u MetaStore-u. Ovo zaduženje obavlja CatalogService komponenta, koja koristeći isti mehanizam za broadcast obaveštava sve impalad procese o promenama nad meta podacima napravljenim od strane drugih impalad procesa.
Obzirom da Impala i Hive imaju deljeni pristup MetaStore-u, u slučaju da Hive izmeni meta podatke, catalogd servise mora uraditi invalidate metadata ili refresh operacije nad bar jednim impalad procesom ne bi li promene bile vidljive u celom sistemu. Invalidate operacija čeka da izmenjeni podaci budu potrebni na korišćenje od strane nekog upita i ponovo učitava sve meta podatke jedne izmenjene celine, što za velike tabele može biti dosta skupa operacija. Refresh sa druge strane ažurira podatke odmah ali, učitava samo informacije o lokacijama blokova koji su izmenjeni.
Instalacija
Cloudera platforma pruža nam mogućnost testiranja Apache Impale na CentOS okruženju postavljenom na virtuelnoj mašini koja se može skinuti putem sledećeg linka. Za pokretanje virtuelne mašine možete iskoristiti alate kao što su Vmware, VirtualBox ili Docker, a biće Vam potreban 64-bitni operativni sistem kao i najmanje 4+ GB rama (oni se moraju dodeliti virtuelnoj mašini).
Ako ste uspešno pokrenuli virtuelnu mašinu primetićete da je podrazumevani korisnik sa korisničkim imenom cloudera, a isto se odnosi i na lozinku. Ovaj korisnik je root korisnik sistema.
Primer
U narednih nekoliko primera pokazujemo način upotrebe Impale, kao i neke osnovne komande za rad sa podacima. Impala mogućnostima se može pristupiti pomoću Hue web aplikacije, ili korišćenjem JDBC ili ODBC interfejsa. U sledećim primerima koristićemo impala-shell alat putem terminala. Terminal za rad možete otvoriti klikom na ikonicu u gornjem levom uglu ili pretragom kroz Applications meni, stavka System Tools.
Da bi ste pristupili impala-shell-u i povezali na instancu impalada potrebno je iskoristiti komandu impala-shell:
[cloudera@quickstart ~]$ impala-shell #Povezivanje na impalad čija se instanca nalazi na trenutnom host-u Connected to quickstart.cloudera:21000 Welcome to the Impala shell. (Impala Shell v2.9.0-cdh5.12.0 (03c6ddb) built on Thu Jun 29 04:17:31 PDT 2017) [cloudera@quickstart ~]$ impala-shell -i [hostname] #Opcije za konektovanje na neki drugi host [cloudera@quickstart ~]$ impala-shell -i [hostname]:[port] [quickstart.cloudera:21000] > show databases; Query: show databases +------------------+---------------------------------------------------------+ | name | comment | +------------------+---------------------------------------------------------+ | _impala_builtins | System database for Impala builtin functions | | default | Default Hive database | +------------------+---------------------------------------------------------+ Fetched 2 row(s) in 0.15s
Nova Impala instanca uvek ima dve baze. Baza default je trenutna baza, dok je baza _impala_builtins sistemska, i sadrži neke meta podatke i funkcije. Za potrebe ovog primera pratićemo sledeću strukturu podataka uz koju će nam biti potrebna i nova baza. Reč je o uprošćenom sistemu za rezervaciju karti za letove.
Za kreiranje nove baze i odgovarajućih tabela možete iskoristiti sledeće komande:
[quickstart.cloudera:21000] > create database ticket_reservation; #Kreiranje nove baze Query: create database ticket_reservation Fetched 0 row(s) in 0.24s [quickstart.cloudera:21000] > use ticket_reservation; #Prebacivanje na rad sa novom bazom Query: use ticket_reservation [quickstart.cloudera:21000] > select current_database(); #Prikaz trenutne baze nad kojom se radi Query: select current_database() +------------------------+ | current_database() | +------------------------+ | ticket_reservation | +------------------------+ Fetched 1 row(s) in 0.24s
Što se tipova podataka tiče, u primerima će tip date biti zamenjen tipom timestamp, dok će tip varchar biti zamenjen tipom string. Impala podržava dve vrste tabela:
- Interne tabele
- Eksterne tabele
Interne tabele se kreiraju podrazumevano. Kod ovih tabela Impala upravlja njihovom unutrašnjom strukturom i fajlovima vezanim za sav unos koji se u slučaju brisanja cele tabele takođe briše.
[quickstart.cloudera:21000] > create table IF NOT EXISTS ticket_types (type_id int, type_name varchar(255), type_pricing double); #Kreiranje interne tabele ticket_types ukoliko već ne postoji Query: create table IF NOT EXISTS ticket_types (type_id int, type_name varchar(255), type_pricing double) Fetched 0 row(s) in 0.76s [quickstart.cloudera:21000] > show tables; #Prikazivanje svih tabela za trenutnu bazu Query: show tables +--------------+ | name | +--------------+ | ticket_types | +--------------+ Fetched 1 row(s) in 0.08s
Upiti se takođe mogu izvršavati navođenjem putanje do fajla. Da bi ste isprobali ovu mogućnost na lokaciji ~/ kreirajte folder sql i unutar njega kreirajte sql fajl create_tables.sql sa istim sadržajem upita.
[cloudera@quickstart ~]$ impala-shell [quickstart.cloudera:21000] > use ticket_reservation; Query: use ticket_reservation [quickstart.cloudera:21000] > source sql/create_ticket_types.sql; #Zavisi od lokacije na kojoj se trenutno nalazite #Izvršavanje upita iz prosleđenog fajla, rezultat isti kao u primeru 3 Query: create table IF NOT EXISTS ticket_types (type_id int, type_name string, type_pricing double) Fetched 0 row(s) in 0.27s [quickstart.cloudera:21000] > describe ticket_types; #Pregled šeme tabele Query: describe ticket_types +--------------+--------+------------+ | name | type | comment | +--------------+--------+------------+ | type_id | int | | | type_name | string | | | type_pricing | double | | +--------------+--------+-----------+ Fetched 3 row(s) in 2.20s [quickstart.cloudera:21000] > insert into ticket_types values (1,"Eco",2000.00); Query: insert into ticket_types values (1,"Eco",2000.00) Modified 1 row(s) in 0.67s [quickstart.cloudera:21000] > select * from ticket_types order by type_id asc; Query: select * from ticket_types order by type_id asc +---------+-----------+-------------------+ | type_id | type_name | type_pricing | +---------+-----------+-------------------+ | 1 | Eco | 2000 | | 2 | Buss | 8000 | +---------+-----------+------------------+ Fetched 2 row(s) in 2.49s
Izaberite neki od načina iz primera i kreirajte internu tabelu tickets sa poljima: 1. ticket_id INT 2. ticket_type INT 3. flight_id INT 4. passenger_id INT 5. price DOUBLE
Eksterne tabele su takve tabele kod kojih se podaci za unos nalaze na lokaciji na HDFS-u, pa čak i u slučaju brisanja cele tabele oni ostaju neizmenjeni. Za naredni primer potrebno je da kreirate podatke za popunjavanje preostalih tabela sa šeme, fajlovi sa podacima mogu biti u csv formatu, dakle razdvojeni zarezom ili bilo kom sličnom formatu, recimo razdvojeni uspravnom crtom. Za kreiranje potrebnih fajlova iskoristite narednu bash skriptu koja fajlove popunjava nasumičnim podacima:
table_data.sh
mkdir -p ~/external_data cd ~/external_data for i in {1..10} do jet_capacity=$(( ( RANDOM % 300 ) + 100 )) echo "$i,JetName_$i,JetType_$i,$jet_capacity" >> jets.dat echo "$i,CityName_$i" >> cities.dat passenger_sex="M" passenger_age=$(( ( RANDOM % 120 ) + 1 )) passenger_random=$(( RANDOM % 2 )) if [ $passenger_random -eq 0 ] then passenger_sex="W" fi echo "$i,PassengerName_$i,PassengerPhone_$i,$passenger_sex,$passenger_age" >> passengers.dat echo "$i,$(date '+%Y-%m-%d %H:%M:%S'),$i,$(( ( RANDOM % 90 ) + 1 ))" >> flights.dat done counter=1 for ((i=1; i<=10; i++)) do for ((j=i+1; j> miles.dat let counter++ echo "$counter,$j,$i,$miles_random" >> miles.dat let counter++ fi done done
Lokacija skripte nije bitna, a ukoliko imate problema sa dozvolama za pokretanje upotrebite komandu chmod +x. Skripta table_data.sh kreira po 10 redova za svaku tabelu, sem naravno za tabelu miles, gde kombinuje sve moguće gradove. Fajlove je sada potrebno ubaciti u odgovarajuće foldere na HDFS-u.
Komandom hdfs dfs -ls možete videti strukturu direktorijuma trenutnog korisnika na HDFS-u, cloudera. Pogodno je da nove foldere nazovete po imenima tabela, a evo i primera skripte koju možete iskoristiti za njihovo kreiranje, kao i kreiranje tabela u popunjavanje podacima.
external_tables.sh
hdfs dfs -mkdir /user/cloudera/external_data hdfs dfs -mkdir /user/cloudera/external_data/cities hdfs dfs -mkdir /user/cloudera/external_data/jets hdfs dfs -mkdir /user/cloudera/external_data/flights hdfs dfs -mkdir /user/cloudera/external_data/passengers hdfs dfs -mkdir /user/cloudera/external_data/miles cd ~/external_data for data in cities jest flights passengers miles do hdfs dfs -put ${data}.dat /user/cloudera/external_data/${data} done hdfs dfs -chmod +rw /user/cloudera/external_data/* hdfs dfs -chmod +rw /user/cloudera/external_data/*/*.dat hdfs dfs -ls /user/cloudera/external_data/*
Sada kada je postavljena odgovarajuća struktura, tabele možete kreirati na sledeći način: create_external_tables.sql
DROP TABLE IF EXISTS jets; CREATE EXTERNAL TABLE jets ( jet_id INT, jet_name STRING, jet_type STRING, jet_capacity INT ) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' – separator kolona LOCATION '/user/cloudera/external_data/jets'; -- lokacija podataka na hdfs-u DROP TABLE IF EXISTS cities; CREATE EXTERNAL TABLE cities ( city_id INT, city_name STRING ) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' LOCATION '/user/cloudera/external_data/cities'; DROP TABLE IF EXISTS passengers; CREATE EXTERNAL TABLE passengers ( passenger_id INT, passenger_name STRING, passenger_phone STRING, passenger_sex STRING, passenger_age INT ) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' LOCATION '/user/cloudera/external_data/passengers'; DROP TABLE IF EXISTS miles; CREATE EXTERNAL TABLE miles ( miles_id INT, miles_source INT, miles_destination INT, miles_pricing DOUBLE ) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' LOCATION '/user/cloudera/external_data/miles'; DROP TABLE IF EXISTS flights; CREATE EXTERNAL TABLE flights ( flight_id INT, flight_date TIMESTAMP, jet_id INT, miles_id INT ) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' LOCATION '/user/cloudera/external_data/flights';
Sada kada su svi podaci na mestu možemo ih iskoristiti za rezervaciju karti. Putnik Pera Perić želi da rezerviše mesto u avionu, Pera želi da ide bilo gde ali ima ograničen budžet od svega 5000 dinara pa mu ne bi smetalo da bude u ekonomskoj klasi. Prvo je potrebno da proverite da li postoje letovi koji su u okviru Perinog budžeta.
[quickstart.cloudera:21000] > select * from ticket_types where type_name like 'Eco%'; +---------+-----------+-------------------+ | type_id | type_name | type_pricing | +---------+-----------+-------------------+ | 1 | Eco | 2000 | +---------+-----------+-------------------+ Impala time – 0s, Hive time 0s – (via Hue) #Nakon provere dodatne cene za ekonomsku kartu, ispotavlja se da Pera ima budžet od 3000 dinara [quickstart.cloudera:21000] > select flight_id, source, destination, flight_date, jet_name, jet_capacity, miles_pricing from ( select flight_id, flight_date, jet_name, jet_type, jet_capacity, miles_id from flights join jets using(jet_id) ) t1 join ( select miles_id, c1.city_name as source, c2.city_name as destination, miles_pricing from miles m join cities c1 join cities c2 where miles_source = c1.city_id and miles_destination=c2.city_id ) miles using(miles_id); where miles_pricing <= 3000; Impala time – 4.57s, Hive time 5m – (via Hue)
Pošto se Peri dopada let 4 potrebno je da proverite da li na tom letu ima mesta.
[quickstart.cloudera:21000] > select count(flight_id) as passenger_number from tickets group by flight_id having flight_id = 4; +------------------------+ | passenger_number | +------------------------+ | 1 | +------------------------+
Obzirom da je kapacitet aviona 252, a trenutni broj putnika 1, Pera može rezervisati kartu. Potrebno je da unesete Peru u sistem i rezervišete let.
[quickstart.cloudera:21000] > insert into passengers values(11, ‘Pera’,’Perin telefon’,’M’,22) >insert into tickets values(2, 1, 4, 11, 3147);
Karta je rezervisana i Pera je na putu. Dakle Impala podržava agregacije i spajanja kao i skoro sve standarne tipove podataka sa malo izmenjenom sintaksom sql jezika.
SQL engine-i na Hadoop-u
Kao neke od važnih alata koji rade nad Hadoop-om naveli smo Pig i Hive. Ovi alati su ujedno bili i prvi alati koji nisu radili direktno sa MapReduce zadacima. Pisanje na jeziku sličnom sql-u i/ili lakšem za zadavanje zadataka ove alate mogli su da koriste i ljudi sa malo iskustva u programiranju. Najveći problem ovih alata bio je, a i dalje jeste to što za bilo kakvu manipulaciju podacima koriste MapReduce sistem. MapReduce sistem kreiran je za duge, naporne poslove, zadaci se dugo izvršavaju i treba im vremena da se pokrenu u punom kapacitetu.
Obzirom da su zahtevi za većom brzinom izvršavanja i pristupom podacima u realnom vremenu sve veći, danas postoji nekoliko alata koji zadovoljavaju te potrebe. Neki od njih su Impala i Presto.
Na kraju imamo različite alata koji su prilagođeni različitim potrebama a pritom ih je nemoguće spojiti u jedan univerzalni alata. Cilj svih ovih prozvoda je da imaju što bolje performanse i da pružaju širok spektar usluga. U nastavku objašnjavamo razliku u performansama Impale i Hive-a ne bi li videli uzrok nastajanja različitih engine-a.
Impala vs. Hive
Iako je Impala dosta brža od Hive-a ne znači da je bolji izbor koristiti je za sve probleme. Impala je memorijski zahtevija i ne izvršava efikasno određene operacije, posebno kada su baš velike količine podataka u pitanju. Dakle ukoliko je potrebno serijski obraditi veliku količinu podataka, Hive je bolje rešenje, a ukoliko je potrebna brza obrada podataka i malo kašnjenje, bolje je izabrati Impalu.
Za primere kojima ćemo uporediti performanse Hive-a i Impale koristi se malo drugačija struktura podataka u odnosu na prethodne primere.
Podaci za testiranje određenih upita nalaze se na sledećem linku.
- Potrebno je skinuti i raspakovati sledeći fajl TPC-DS_Tools_v2.5.0.zip, tj. source code za Benchmark TPC-DS.
- Fajl je potrebno raspakovati na lokaciju /home/cloudera pod nazivom tpcds.
- Sledeći korak je prebacivanje potrebnih fajlova kao i kreiranje određene strukture direktorijuma na osnovu koje će se kreirati tabele. Ovo možete uraditi pokretanjem skripte tpcds-setup.sh, koja će biti data u nastavku. Vodite računa o tome da ste dobro postavili lokaciju u koraku dva. Da bi ste iz ove skripte pozvali skriptu za kreiranje tabela izmenite lokaciju u poslednjem redu.
Ukoliko je potrebno postaviti dozvole nad skriptom za njeno pokretanje, to možete uraditi u terminalu komandom chmod +x tpcds-setup.sh, a zatim je i pokrenuti ./tpcds-setup.sh.
tpcds-setup.sh
#!/bin/bash cd ~/tpcds cd tools make clean make export PATH=$PATH:. DIR=$HOME/tpcds/data mkdir -p $DIR SCALE=1 FORCE=Y #Skripta za generisanje podataka dsdgen dsdgen -verbose -force $FORCE -dir $DIR -scale $SCALE -table store_sales dsdgen -verbose -force $FORCE -dir $DIR -scale $SCALE -table date_dim dsdgen -verbose -force $FORCE -dir $DIR -scale $SCALE -table time_dim dsdgen -verbose -force $FORCE -dir $DIR -scale $SCALE -table item dsdgen -verbose -force $FORCE -dir $DIR -scale $SCALE -table customer dsdgen -verbose -force $FORCE -dir $DIR -scale $SCALE -table customer_demographics dsdgen -verbose -force $FORCE -dir $DIR -scale $SCALE -table household_demographics dsdgen -verbose -force $FORCE -dir $DIR -scale $SCALE -table customer_address dsdgen -verbose -force $FORCE -dir $DIR -scale $SCALE -table store dsdgen -verbose -force $FORCE -dir $DIR -scale $SCALE -table promotion hdfs dfs -mkdir /user/hive/tpcds hdfs dfs -mkdir /user/hive/tpcds/date_dim hdfs dfs -mkdir /user/hive/tpcds/time_dim hdfs dfs -mkdir /user/hive/tpcds/item hdfs dfs -mkdir /user/hive/tpcds/customer hdfs dfs -mkdir /user/hive/tpcds/customer_demographics hdfs dfs -mkdir /user/hive/tpcds/household_demographics hdfs dfs -mkdir /user/hive/tpcds/customer_address hdfs dfs -mkdir /user/hive/tpcds/store hdfs dfs -mkdir /user/hive/tpcds/promotion hdfs dfs -mkdir /user/hive/tpcds/store_sales hdfs dfs -mkdir /user/hive/tpcds/store_returns cd $HOME/tpcds/data for t in date_dim time_dim item customer customer_demographics household_demographics customer_address store promotion store_sales store_returns do hdfs dfs -put ${t}.dat /user/hive/tpcds/${t} done hdfs dfs -ls -R /user/hive/tpcds/*/*.dat #Kreiranje tabela putem Hive-a, potrebno je da se navede lokacija skripte tpcds_ss_tables.sql hive -f /home/cloudera/impalascripts/tpcds_ss_tables.sql
tpcds_ss_tables.sql
create external table store_returns ( sr_returned_date_sk int, sr_return_time_sk int, sr_item_sk int, sr_customer_sk int, sr_cdemo_sk int, sr_hdemo_sk int, sr_addr_sk int, sr_store_sk int, sr_reason_sk int, sr_ticket_number bigint, sr_return_quantity int, sr_return_amt float, sr_return_tax float, sr_return_amt_inc_tax float, sr_fee float, sr_return_ship_cost float, sr_refunded_cash float, sr_reversed_charge float, sr_store_credit float, sr_net_loss float ) row format delimited fields terminated by '|' location '/user/hive/tpcds/store_returns'; create external table store_sales ( ss_sold_date_sk int, ss_sold_time_sk int, ss_item_sk int, ss_customer_sk int, ss_cdemo_sk int, ss_hdemo_sk int, ss_addr_sk int, ss_store_sk int, ss_promo_sk int, ss_ticket_number int, ss_quantity int, ss_wholesale_cost float, ss_list_price float, ss_sales_price float, ss_ext_discount_amt float, ss_ext_sales_price float, ss_ext_wholesale_cost float, ss_ext_list_price float, ss_ext_tax float, ss_coupon_amt float, ss_net_paid float, ss_net_paid_inc_tax float, ss_net_profit float ) row format delimited fields terminated by '|' location '/user/hive/tpcds/store_sales'; create external table customer_demographics ( cd_demo_sk int, cd_gender string, cd_marital_status string, cd_education_status string, cd_purchase_estimate int, cd_credit_rating string, cd_dep_count int, cd_dep_employed_count int, cd_dep_college_count int ) row format delimited fields terminated by '|' location '/user/hive/tpcds/customer_demographics'; create external table date_dim ( d_date_sk int, d_date_id string, d_date timestamp, d_month_seq int, d_week_seq int, d_quarter_seq int, d_year int, d_dow int, d_moy int, d_dom int, d_qoy int, d_fy_year int, d_fy_quarter_seq int, d_fy_week_seq int, d_day_name string, d_quarter_name string, d_holiday string, d_weekend string, d_following_holiday string, d_first_dom int, d_last_dom int, d_same_day_ly int, d_same_day_lq int, d_current_day string, d_current_week string, d_current_month string, d_current_quarter string, d_current_year string ) row format delimited fields terminated by '|' location '/user/hive/tpcds/date_dim'; create external table time_dim ( t_time_sk int, t_time_id string, t_time int, t_hour int, t_minute int, t_second int, t_am_pm string, t_shift string, t_sub_shift string, t_meal_time string ) row format delimited fields terminated by '|' location '/user/hive/tpcds/time_dim'; create external table item ( i_item_sk int, i_item_id string, i_rec_start_date timestamp, i_rec_end_date timestamp, i_item_desc string, i_current_price float, i_wholesale_cost float, i_brand_id int, i_brand string, i_class_id int, i_class string, i_category_id int, i_category string, i_manufact_id int, i_manufact string, i_size string, i_formulation string, i_color string, i_units string, i_container string, i_manager_id int, i_product_name string ) row format delimited fields terminated by '|' location '/user/hive/tpcds/item'; create external table store ( s_store_sk int, s_store_id string, s_rec_start_date timestamp, s_rec_end_date timestamp, s_closed_date_sk int, s_store_name string, s_number_employees int, s_floor_space int, s_hours string, s_manager string, s_market_id int, s_geography_class string, s_market_desc string, s_market_manager string, s_division_id int, s_division_name string, s_company_id int, s_company_name string, s_street_number string, s_street_name string, s_street_type string, s_suite_number string, s_city string, s_county string, s_state string, s_zip string, s_country string, s_gmt_offset float, s_tax_precentage float ) row format delimited fields terminated by '|' location '/user/hive/tpcds/store'; create external table customer ( c_customer_sk int, c_customer_id string, c_current_cdemo_sk int, c_current_hdemo_sk int, c_current_addr_sk int, c_first_shipto_date_sk int, c_first_sales_date_sk int, c_salutation string, c_first_name string, c_last_name string, c_preferred_cust_flag string, c_birth_day int, c_birth_month int, c_birth_year int, c_birth_country string, c_login string, c_email_address string, c_last_review_date string ) row format delimited fields terminated by '|' location '/user/hive/tpcds/customer'; create external table promotion ( p_promo_sk int, p_promo_id string, p_start_date_sk int, p_end_date_sk int, p_item_sk int, p_cost float, p_response_target int, p_promo_name string, p_channel_dmail string, p_channel_email string, p_channel_catalog string, p_channel_tv string, p_channel_radio string, p_channel_press string, p_channel_event string, p_channel_demo string, p_channel_details string, p_purpose string, p_discount_active string ) row format delimited fields terminated by '|' location '/user/hive/tpcds/promotion'; create external table household_demographics ( hd_demo_sk int, hd_income_band_sk int, hd_buy_potential string, hd_dep_count int, hd_vehicle_count int ) row format delimited fields terminated by '|' location '/user/hive/tpcds/household_demographics'; create external table customer_address ( ca_address_sk int, ca_address_id string, ca_street_number string, ca_street_name string, ca_street_type string, ca_suite_number string, ca_city string, ca_county string, ca_state string, ca_zip string, ca_country string, ca_gmt_offset float, ca_location_type string ) row format delimited fields terminated by '|' location '/user/hive/tpcds/customer_address'; quit;
- Sada je potrebno da zadavanjem komande impala-shell -r obavestite Impala procese da je došlo do izmene meta podataka.
- Ukoliko je sve prošlo kako treba, upotrebom komande show tables bi trebalo da dobijete sledeći rezultat.
[quickstart.cloudera:21000] > show tables; Query: show tables +------------------------+ | name | +------------------------+ | customer | | customer_address | | customer_demographics | | date_dim | | household_demographics | | item | | promotion | | store | | store_returns | | store_sales | | time_dim | +------------------------+ Fetched 11 row(s) in 0.11s
Za izvršavanje upita možete koristiti konzolu ili alat kao što je Hue koji je malo više orijentisan na korisnike. Hue je web aplikacija za analizu, manipulaciju i deljenje podataka. Omogućava uvid u baze i tabele, a rezultati se sem tabelarno mogu predstaviti u obliku grafikona. U kombinaciji sa jezikom koji podseća na sql krajnje je lak za korišćenje.
Još jedan od razloga za korišćenje Hue-a, jednim klikom na dugme lako možemo prelaziti sa Hive-a na Impalu i obrnuto, pa je testiranje i poređenje performansi utoliko lakše.
Ovo su neki od izdvojenih rezultata testiranja na virtuelnoj mašini za ubrzano učenje koje obezbeđuje Cloudera.
Impala | Hive | Upit |
---|---|---|
7.84s | 7m 37s | 55.sql |
8.78s | 5m 29s | 3.sql |
23.11s | 9m 27s | 27.sql |
30s | 19m 11s | 17.sql |
41.36s | 30m + | 1.sql |
Kao što možemo videti, Impala zaista ima dosta bolje performanse od Hive-a, ali ovi rezultati mogu dosta zavisiti od količine test podataka kao i mašina na kojima se zadaci izvršavaju. Jedan od razloga zašto se Hive duže izvršava je i startup ovehead, MapReduce zadacima je potrebno neko vreme da iskoriste pun kapacitet čvorova.
Prednost Hive-a je velika tolerancija na greške, naime ako dođe do kvara čvora sa podacima, korisnik će ipak dobiti rezultat, dok se kod Impale ceo upit mora pokrenuti ponovo. Hive ima veliku toleranciju baš zato što je zadužen za obrade koje drugo traju, dakle i po nekoliko sati.
Upiti su birani po kompleksnosti, kojoj doprinosi veći broj spajanja, agregacija, ugnježdavanja ili brojem podataka koji proizvedu.
3.sql
select dt.d_year ,item.i_brand_id brand_id ,item.i_brand brand ,sum(ss_ext_sales_price) sum_agg from date_dim dt ,store_sales ,item where dt.d_date_sk = store_sales.ss_sold_date_sk and store_sales.ss_item_sk = item.i_item_sk and item.i_manufact_id = 436 and dt.d_moy=12 group by dt.d_year ,item.i_brand ,item.i_brand_id order by dt.d_year ,sum_agg desc ,brand_id limit 100;
55.sql
select i_brand_id brand_id, i_brand brand, sum(ss_ext_sales_price) ext_price from date_dim, store_sales, item where date_dim.d_date_sk = store_sales.ss_sold_date_sk and store_sales.ss_item_sk = item.i_item_sk and i_manager_id=36 and d_moy=12 and d_year=2001 group by i_brand, i_brand_id order by ext_price desc, i_brand_id limit 100 ;
17.sql
select i_item_id ,i_item_desc ,s_state ,count(ss_quantity) as store_sales_quantitycount ,avg(ss_quantity) as store_sales_quantityave ,stddev_samp(ss_quantity) as store_sales_quantitystdev ,stddev_samp(ss_quantity)/avg(ss_quantity) as store_sales_quantitycov ,count(sr_return_quantity) as_store_returns_quantitycount ,avg(sr_return_quantity) as_store_returns_quantityave ,stddev_samp(sr_return_quantity) as_store_returns_quantitystdev ,stddev_samp(sr_return_quantity)/avg(sr_return_quantity) as store_returns_quantitycov from store_sales ,store_returns ,date_dim d1 ,date_dim d2 ,store ,item where d1.d_quarter_name = '2000Q1' and d1.d_date_sk = store_sales.ss_sold_date_sk and item.i_item_sk = store_sales.ss_item_sk and store.s_store_sk = store_sales.ss_store_sk and store_sales.ss_customer_sk = store_returns.sr_customer_sk and store_sales.ss_item_sk = store_returns.sr_item_sk and store_sales.ss_ticket_number = store_returns.sr_ticket_number and store_returns.sr_returned_date_sk = d2.d_date_sk and d2.d_quarter_name in ('2000Q1','2000Q2','2000Q3') group by i_item_id ,i_item_desc ,s_state order by i_item_id ,i_item_desc ,s_state limit 100;
27.sql
select i_item_id, s_state, avg(ss_quantity) agg1, avg(ss_list_price) agg2, avg(ss_coupon_amt) agg3, avg(ss_sales_price) agg4 from store_sales, customer_demographics, date_dim, store, item where store_sales.ss_sold_date_sk = date_dim.d_date_sk and store_sales.ss_item_sk = item.i_item_sk and store_sales.ss_store_sk = store.s_store_sk and store_sales.ss_cdemo_sk = customer_demographics.cd_demo_sk and customer_demographics.cd_gender = 'F' and customer_demographics.cd_marital_status = 'D' and customer_demographics.cd_education_status = 'Unknown' and date_dim.d_year = 1998 and store.s_state in ('KS','AL', 'MN', 'AL', 'SC', 'VT') group by i_item_id, s_state order by i_item_id ,s_state limit 100;
1.sql
select * from store_sales ,store_returns ,date_dim d1 ,store ,item ,customer ,customer_address ,customer_demographics ,household_demographics ,time_dim ,promotion
Šabloni upiti koje možete iskoristiti za kreiranje upita za testiranje nalaze se na lokaciji ~/tcpds/query_templates.
Literatura
- Impala tutorijal – https://www.cloudera.com/documentation/enterprise/5-8-x/topics/impala.html
- Hue – https://www.cloudera.com/documentation/enterprise/5-8-x/topics/hue.html
- Hive vs. Impala – https://www.dezyre.com/article/hive-vs-impala-sql-war-in-the-hadoop-ecosystem/148
- Quick start – http://blog.cloudera.com/blog/2013/06/quickstart-vm-now-with-real-time-big-data
- Dodatne informacije – http://blog.cloudera.com blog/2013/06/quickstart-vm-now-with-real-time-big-data
- Podaci za testiranje – http://www.tpc.org/tpc_documents_current_versions/current_specifications.asp