Hadoop a Python

Raz som tak rozmýšlal či som pracoval na projekte ktorý by spadal do kategórie BigData. Na jednom projekte máme okolo 100GB dát, takže to je ešte skôr MiniData :) Keď sme začínali s projektom tak sme vedeli že budeme zbierať väčšie množstvo dát a zvolili sme cloudovú službu AppEngine od Googlu. Takže hosting rastie snami bez toho aby sme sa museli o čokoľvek starať. Ale jeden problém s AppEngine predsa len máme. Raz za mesiac potrebujeme počítať rôzne štatistiky, AppEngine síce má možnosť spúšťat "crony" ale ich beh je obmedzený len na 10 minút. Preto musíme dáta stiahnuť na externý server kde sa spracujú a následne sa posielajú naspäť. Nad dátami sa vykonávajú zložité geo lokačné výpočty a začína to už celkom trvať a preto hladáme spôsob ako výpočty rozdistribuovať medzi viac počítačov a hlavne zrýchliť. Síce to zatiaľ nehorí ale lepšie je byť pripravený :)

Pojem BigData sa často spája s projektom Hadoop. Keď sa chcem dozvedieť niečo o technológii ktorú nepoznám, je pre mňa najjednoduchšie si prejsť nejaký online kurz ako čítať knižku. Tento krát som si prešiel kurz Intro to Hadoop and MapReduce na UDACITY.

Čo je to vlastne ten Hadoop? V skratke, Hadoop umožňuje spracovávať veľké množstvo dát distribuovaním záťaže na viac počítačov. Teda vie spracovať "veľké" dáta ktoré by nebolo možné spracovať na jednom počítači alebo to vie spraviť oveľa rýchlejšie. Hadoop vie spracovávať neštruktúrované dáta, teda dáta nemusia mať zadefinovanú "pevnú" štruktúru ako napríklad pri relačných databázach. Na spracovanie dát používa algoritmus MapReduce o ktorom si povieme za chvíľu viac.

Kurz pozostáva zo štyroch lekcií a finálneho projektu. Kurz bol celkom dobre organizovaný a spracovaný až na štvrtú lekciu, kde som mal problém pochopiť zadanie (úlohy boli dosť nezrozumiteľne popísané). Na kurze sa mi páčilo hlavne to že som nemusel zložito konfigurovať a inštalovať aplikácie, ku kurzu je k dispozícii virtuálny stroj, kde je už všetko pred pripravené a nainštalované.

Počas kurzu som sa dozvedel dve veci:

  • Neexistuje definícia čo je vlastne BigData. Ale rádovo 100-ky GB / TB a viac.
  • Paradoxne na "menších" dátach sú väčšinou rýchlejšie "klasické" SQL databázy ako Hadoop.

Jednou zo základných častí Hadoop-u je distribuovaný súborový systém HDFS (The Hadoop Distributed File System). Ten sa postará o to aby "veľké" súbory boli rozdelené na menšie časti a rozdistribuované medzi viac počítačov pre rýchlejšie a ľahšie spracovanie. Súbory sú distribuované medzi počítače redundantne pre prípad ak by napríklad došlo k chybe / výpadku niektorého počítača kde sú dáta uložené aby ho vedel zastúpiť iný počítač.

Takže prvou úlohou je nahrať súbor alebo dáta ktoré chceme spracovať do distribuovaného súborového systému HDFS. S ktorým sa pracuje celkom intuitívne ak zvládate základnú prácu na Unixových systémoch budete sa cítiť ako ryba vo vode.

# zobraz súbory uložené na HDFS
hadoop fs -ls

# nahraj lokálny súbor do HDFS
hadoop fs -put subor.txt

# zmaž súbor uložený na HDFS
hadoop fs -rm subor.txt

# nahraj súbor z HDFS na lokálny disk
hadoop fs -get subor.txt  

V druhom kroku je potrebné napísať skripty pre MapReduce. MapReduce je programovací model, ktorý sa používa pri paralelnom alebo distribuovanom spracovávaní dát. Dáta sa spracovávajú v dvoch fázach Map a Reduce. V prvej fáze Map sa dáta upravia do formátu s ktorým bude vedieť pracovať fáza Reduce v ktorej sa dáta môžu buď filtrovať podľa zadefinovaných pravidiel alebo napríklad robiť štatistické výpočty. Najlepšie keď si jednotlivé fázy popíšeme a ukážeme priamo na príklade.

Veľkou výhodou Hadoop-u je že skripty MapReduce môžete písať v rôznych programovacích jazykoch. Stačí aby skripty boli samostatne spustiteľné a vedeli pracovať so štandardným vstupom / výstupom. V podstate si vystačíte s jednoduchými programovacími technikami a nemusíte sa učiť žiadne komplikované API.

Skripty MapReduce môžete vyvíjať / testovať aj u seba na počítači, bez toho aby ste mali nainštalovaný Hadoop. Stačí keď si spustíte v temináli tento príkaz:

cat data.txt | ./mapper.py | sort | ./reducer.py  

Samozrejme nebudete skript vyvýjať a testovať na celom produkčnom súbore (trvalo by to veľmi dlho). Ale si z produkčného súboru vyextrahujete napríklad len 100 riadkov.

cat big_data.txt | tail -n 100 > data.txt  

Tak poďme na príklad. Majme dáta z viacerých internetových obchodov ktoré vlastní jedna firma a ktorá chce mať prehľad koľko jednotlivé produkty "zarobili". Firma má obchody vo viacerých krajinách a preto sú ceny uvedené v rôznych menách. Ceny produktov budeme prepočítavať na eurá kvôli lepšej prehľadnosti výsledkov.

; currency, product, price, datetime
GBP,Phone X,100,2014-04-01 10:01  
EUR,TV XYZ,1000,2014-04-01 17:21  
...

Výstupom skriptu mapper.py bude názov produktu a jeho cena v eurách, ak je cena v inej mene ako EUR tak ju prepočítame na eurá.

#!/usr/bin/python3

import sys

GBP_EUR = 1.27

is_first_line = True  
for line in sys.stdin:  
    if is_first_line:  # skip header
        is_first_line = False
        continue

    data = line.strip().split(",")

    currency, product, price, stamp = data

    price = float(price)
    if currency == "GBP":
        price = price * GBP_EUR

    print("{0}, {1}".format(product, str(price)))

# vystup
# Phone X,100
# ...

V skripte reduce.py spočítame počet a celkovú cenu predaných kusov pre jednotlivé produkty.

#!/usr/bin/python3
import sys

last_product = None  
product_count = 0  
product_price_sum = 0

for line in sys.stdin:  
    data = line.strip().split(',')

    product, price = data
    price = float(price)

    if last_product and last_product != product:
        print("{0},{1}x,{2} EUR".format(last_product, product_count, product_price_sum))
        product_count = 1
        product_price_sum = price
    else:
        product_count += 1
        product_price_sum += price

    last_product = product

print("{0},{1}x,{2} EUR".format(last_product, product_count, product_price_sum))

# vystup
# Phone X,100x,10000EUR
# ...

Keď už máme skripty naprogramované a otestované na lokálnom počítači, môžeme skript spustiť na Hadoop-e s produkčnými dátami. V tom prípade musíme postupovať takto:

  • najprv nahrať súbor s dátami na HDFS
hadoop fs -put big_data.txt  
  • spustiť Hadoop s trocha komplikovanými paramterami
hadoop jar contrib/streaming/hadoop-0.20.2-streaming.jar -file mapper.py -mapper mapper.py -file reducer.py -reducer reducer.py -input big_data.txt -output output_data  
  • po skončení výpočtu stiahnuť dáta z HDFS na lokálny počítač
hadoop fs -get output_data/part-00000  

Skript by s dal ešte upraviť aby zobrazil len napríklad desať najpredávanejších produktov, alebo sa dáta dajú ešte dodatočne spracovať podľa potreby. V podstate toto je všetko čo potrebujete vedieť aby ste s Hadoop MapReduce mohli začat pracovať, už to chce len tréning :)

Hadoop sa stal za posledné roky veľmi "populárny" a tak okolo neho začali vznikať zaujímavé projekty ako napríklad projekt Hive, ktorý umožňuje dotazovať sa nad dátami SQL syntaxou.

hive> SELECT a.foo FROM invites a WHERE a.ds='2008-08-15';  

Otázkou je či sa pustiť do inštalovania a konfigurovania vlastného clusteru. Ja si myslím že najjednoduchšie je využiť službu ktorá ponúka už prednastavený Hadoop cluster. Nemusíte nič instalovať a zložito konfigurovať a môžete Hadoop takmer ihneď začať používať. Hlavne v prípadoch ak robíte len nejaké sumárne výpočty len raz za mesiac, tak sa neoplatí "vytvárať" vlastný cluster. Napríklad služba Amazonu Elastic Map Reduce umožňuje využiť ich cluster len počas trvania výpočtu čo je určite zaujímavá ponuka.

Show Comments