dersblog

Hadoop - Ilk Ornek (Python), Esleme-Indirgeme

Şimdi bir önceki yazıda Java ile yapılanı Python ile yapalım. Önce mapper.py kodunu /home/hduser altında yaratalım,

#!/usr/bin/env python
import sys
# input comes from STDIN (standard input)
for line in sys.stdin:
    # remove leading and trailing whitespace
    line = line.strip()
    # split the line into words
    words = line.split()
    # increase counters
    for word in words:
        # write the results to STDOUT (standard output);
        # what we output here will be the input for the
        # Reduce step, i.e. the input for reducer.py
        #
        # tab-delimited; the trivial word count is 1
        print '%s\t%s' % (word, 1)

Sonra aynı dizinde reducer.py

#!/usr/bin/env python
from operator import itemgetter
import syscurrent_word = None
current_count = 0word = None
# input comes from STDINfor line in sys.stdin:
    # remove leading and trailing whitespace
    line = line.strip()
    # parse the input we got from mapper.py
    word, count = line.split('\t', 1)
    # convert count (currently a string) to int
    try:
        count = int(count)
    except ValueError:
        # count was not a number, so silently
        # ignore/discard this line
        continue
    # this IF-switch only works because Hadoop sorts map output
    # by key (here: word) before it is passed to the reducer
    if current_word == word:
        current_count += count
    else:
        if current_word:
            # write result to STDOUT
            print '%s\t%s' % (current_word, current_count)
        current_count = count
        current_word = word# do not forget to output the last word if needed!
if current_word == word:
    print '%s\t%s' % (current_word, current_count)

İşe başlamadan önce mapper.py işliyor mu hemen kontrol edelim,

echo "foo foo quux labs foo bar quux" | /home/hduser/mapper.py

Sonuc

foo
    1foo
    1quux
    1labs
    1foo
    1bar
    1quux
    1

olmalı. İndirgeyiciyi test edelim

echo "foo foo quux labs foo bar quux" | /home/hduser/mapper.py | /home/hduser/reducer.py

Sonuc

foo

 2quux


1
labs

 1foo  
 1bar

 1quux

 1

Eğer bir önceki örnek yüzünden mevcut dizine yazılamayacağı gibi bir hata gelmesin istersek (ya da gelirse) bu dizini silebiliriz,

bin/hadoop dfs -rmr /user/hduser/gutenberg-output

Şimdi Python süreçleri başlatabiliriz, Python kodunun kullanılabilmesi için Hadoop Streaming kullanacağız, HS sayesinde işleyici süreçlerin verilerini standart girdi (standard ınput, STDİN) üzerinde alırlar, ve çıktıları standart çıktı (standard output, STDOUT) üzerine yazarlar. [HADOOP DIZIN]/contrib/streaming/hadoop-*streaming*.jar dosyası bu işi yapmaktadır. Ayrıca HS kullanılınca STDIN, STDOUT ile iletişim yapabilen (neredeyse her programlama dili) her türlü stil / dil işleyici yazmak için kullanılabilir.

bin/hadoop jar contrib/streaming/hadoop-*streaming*.jar -mapper /home/hduser/mapper.py -reducer /home/hduser/reducer.py -input /user/hduser/gutenberg/* -output /user/hduser/gutenberg-output

Sonuçları daha önce yaptığımız gibi geri alırız,

bin/hadoop dfs -getmerge /user/hduser/gutenberg-output /tmp/gutenberg-output

Artık üstteki dosya tüm sonuçları içeren sonuç dosyasıdır.

Daha detaylı eşle/indirge anlatımı için İstatistik notlarımıza bakılabilir.

Not: Kelime sayma probleminde anahtarlara ayırma işlemi basit gibi duruyor, "kelimenin kendisi anahtar zaten" vs. Fakat bu evrede bazı veri temizleme işlemleri olabilir, ki bu işlemler kendi iç mantıklarını taşıyor olabilirler; ya da anlamsal (semantic) farklı işlemler devreye sokabiliriz. Kelimelerde Ankara, ankara, annkara kelimelerinin aynı anahtara eşleneceğinin kararını bu aşamada veriyor olabilirdiik mesela. Belki elimizde yazma hatalarını algılayabilen bir algoritmamiz vardır, onu bu aşamada kullanmaya karar verdik vs. Geometrik transformasyonlardan tutun, coğrafi, kelimesel her türlü eşleştirme bu safhada kullanılabilir.

Kaynaklar

[1] http://developer.yahoo.com/hadoop/tutorial/module4.html

[2] http://www.michael-noll.com/tutorials/running-hadoop-on-ubuntu-linux-single-node-cluster/


Yukarı