Hadoop Üzerinde Alıştırmalar

Genel Açıklamalar

Bu alıştırma belgesindeki tüm alıştırmaları Dilişim tarafından sizlere verilen ve içinde CentOS 6.5 Linux dağıtımı bulunan VM ile çalıştırabilirsiniz.

VM'lerde Pseudo-Distributed mode CDH(Apache Hadoop içeren Cloudera Dağıtımı) yüklüdür. Pseudo-Distributed mode Hadoop çalıştırabilmek için gereken daemonların tek bir makinede yüklü olduğu bir yöntemdir. Bu yüzden VM içinde çalıştırılacak alıştırmalarda hız ikinci plandadır ve performans beklemek yanlış bir yaklaşım olacaktır.

VM hakkında bilinmesi gerekenler :

1) VM dilisim kullanıcısı olarak başlayacaktır ve içinde gerekli tüm şifreler dilisim olarak ayarlanmıştır.

2) Bu alıştırma dosyasında aşağıdaki gibi komutlar göreceksiniz :

$ hadoop fs -put roman \ 
/user/dilisim/roman

Bu komutlarda kullanılan ' $ ' işareti, bu karakterden sonrasının komut olduğunu ve ' \ ' karakteri komutun bitmediğini alt satırda devam ettiğini ifade etmektedir

3) Sizler için hazırladığımız ve alıştırmalarda kullanılacak tüm içerik ~/dilisim_materials/ klasörü altındadır

İlk olarak yapmanız gereken https://www.virtualbox.org/ adresinde VM yi indirip kurmak

Ardından http://www.dilisim.com adresine giriniz ve en altta bulunan hadoop linkine tıklayakarak Dilişim VM'yi indiriniz

...

İndirdikden sonra exe'ye çift tıklayıp çalıştırıyoruz karsımıza bu ekran geliyor

...

İmport diyerek yüklüyoruz

Genel alıştırmaları uygulamak için teminali sol üst menüden açıp kullanabilirsiniz
Application/System Tools/Terminal

...

Alıştırma 1
Hdfs Kullanımı ve Genel Komutlar

Bu alıştırmada kullanılacak veriler :

~/dilisim_materials/roman 
~/dilisim_materials/2013_table_logs

Hdfs Temel Komutları

VM’lerinizde Hadoop yüklenmiş ve ayarlanmış bir şekilde hazır bulunmaktadır. hadoop komutunu arguman vermeden çalıştırdığınızda size yardım mesajı döndürecektir

1) Komutları yürütebilmek için VM'inizde üst menüden terminal ikonuna tıklayarak yeni bir terminal penceresi açınız. Aşağıdaki gibi sadece hadoop yazarak deneyebilirsiniz
$ hadoop

Hadoop komutlarının çalıştığı alt sistem FsShell ' dir. Bu alt sistemi çalıştırmak için kullanılan kod ise
hadoop fs
komutudur.

2) Terminal penceresine aşağıdaki komutu yazınız

$ hadoop fs

FsShell alt sistemi ile ilgili yardım mesajını göreceksiniz.

3) Aşağıdaki komutu çalıştırdığınızda ise :

$ hadoop fs -ls /

HDFS deki root klasörünün içeriğini göreceksiniz.

4) Linux sistemlerde kullandığınız gibi birçok komutu başına hadoop fs – ekleyerek FsShell'de de kullanabilirsiniz. HDFS ana klasörünüzün derinliklerine inip içeriğini görüntülemek için :

$ hadoop fs -ls /user

Veya

$ hadoop fs -ls /user/dilisim

Komutlarını yürütebilirsiniz. Dosyanız boş olduğu için hiç bir sonuç dönmeyecektir. HDFS'deki home klasörünüz /user/dilisim olarak ayarlanmıştır. Örneklerde kullanacağımız klasör ve dosyalar bu klasör altında toplanacaktır.

HDFS 'e dosya gönderme

1) Komutları çalıştırdığınız klasörünüzün yerini bu dosyadaki alıştırmalarda kullanacağımız klasöre eşlememiz gerekiyor bunun için

 $ cd ~/dilisim_materials/

komutunu çalıştırıyoruz.

2) HDFS ' e dosyamızı göndermek için :

 $ hadoop fs -put roman /user/dilisim/roman 

hadoop komutunu çalıştırıyoruz. Bu komutta son parametre dosyanın HDFS'te gideceği yerin yolunu tam olarak söylemek için yazıldı, eğer amacımız ana klasöre (/user/dilisim/ ) veri yollamak ise

$ hadoop fs -put roman 

komutunu çalıştırarak da aynı işi yapabiliriz

Not : Eğer ilk komutunuz sağlıklı bir şekilde çalıştıysa ikinci kez komutu çalıştırmayı denediğinizde dosyalar zaten var şeklinde hata mesajı alacaksınız. HDFS varsayılan ayarlarında var olan bir dosyanın veya klasörün üzerine yazma eğilimine girmez ve hata mesajı döndürür.

3) HDFS ana klasörümüze dosyamızı gönderebildiğimizi test etmek için :

$ hadoop fs -ls /user/dilisim

komutunu çalıştırınız. roman klasörümüzü görmüş olmamız gerekiyor.

4) İsterseniz dosya yolu vermeden :

$ hadoop fs -ls

komutunu yürütebilirsiniz. Bu komutu yürüttüğünüzde de aynı sonucu göreceksiniz.

5) Şimdiki komutumuzda ise HDFS'e klasör yaratma işlemini gerçekleştireceğiz :

$ hadoop fs -mkdir loglar

loglar klasörümüzün yaratılmış olması gerekiyor doğrulamak için tekrar:

$ hadoop fs -ls

komutunu yürütebiliriz

6) Oluşturduğumuz bu klasöre ~/dilisim_materials/ dosyası altındaki 2013_table_logs dosyasını atmak için :

$ hadoop fs -put 2013_table_log /user/dilisim/loglar

komutunu çalıştırınız. Doğrulamak için :

$ hadoop fs -ls loglar/

komutunu çalıştırınız.

Dosya görüntüleme ve silme işlemleri

1) Önceden HDFS ' e atttığımız klasörün içeriğini görüntüleyelim :

$ hadoop fs -ls roman

Görünen liste HDFS 'teki /user/dilisim/roman klasörünün içeriğidir. İçerisinde calikusu, huzur, incememed, kavim ve kurkmantolumadonna olmak üzere beş adet romanımız bulunmaktadır

2) İçlerinden kavim adlı romanı silmek için :

$ hadoop fs -rm roman/kavim 

komutunu çalıştıralım. Silme işlemi bittiğinde işlemimizi doğrulamak için :

$ hadoop fs -ls roman

komutunu çalıştıralım. Klasörümüzün içinde kavim adında romanımız olmadığını görmüş olmamız lazım.

3) Romanlarımızın bir tanesinin içeriğine bakmak için :

$ hadoop fs -cat roman/calikusu | tail -n 50

komutunu çalıştırabilirsiniz. tail -n 50 parametresi dosyamızın sonundan 50 satırını bize gösterir

Not : HDFS'e atılan verilerin ve MapReduce işlemi sonucu oluşacak çıktıların boyutları ve içerdikleri satır sayıları genellikle büyük olur. Bunun için tail veya head gibi parametrelerle dosyanın görmek istediğiniz kadarını başından veya sonundan belirleyebilirsiniz

4) HDFS ' teki bir dosyayı local sisteme almak için ise :

$ hadoop fs -get roman/calikusu calikusu.txt

komutu ile alabiliriz. get komutu iki parametre alır. İlki HDFS üzerindeki dosya ve ikincisi local sisteminizdeki dosyayı almak istediğiniz dosya yolu/dosya adıdır.

Diğer Komutlar

Yukarıda temel olarak sürekli kullanılan komutlardan örnekler verdik. Diğer komutları görmek isterseniz:

$ hadoop fs

Komutunu çalıştırarak dönen yardım mesajından diğer komutları ve kısa açıklamalarını görebilirsiniz.

Alıştırma 2
WordCount Örneği ile MapReduce İşi Çalıştırma

Bu alıştırmada kullanılacak veriler :

 ~/dilisim_materials/roman 
 ~/workspace/wordcount/src/

Bu alıştırmamızda HDFS'teki roman klasörü içerisindeki romanları kullanarak romanların içinde geçen kelimelerin sayılarını bulacağız. Bir önceki alıştırmamızı sağlıklı bir şekilde bitirdiğimizde HDFS üzerinde roman klasörümüz hazır durumda olacaktır. Henüz ilk alıştırmayı tamamlamadıysanız bu alıştırmaya başlamadan önce ilk alıştırmayı tamamlamanız gerekmektedir.

wordcount dosyamızın içinde üç adet java dosyamız bulunuyor.

WordCount.java : MapReduce'un basit driver class'ıdır .

WordMapper.java : İş için gerekli Mapper class'ıdır.

SumReducer.java : İş için gerekli Reducer class'ıdır.

Derleme ve MapReduce İşi Başlatma

1) Terminal penceresinden içinde bulunduğumuz klasörü :

$ cd ~/workspace/wordcount/src/

komutu ile değiştiriyoruz.

$ ls solution/

Komutu ile klasörün içeriğine baktığımızda yukarıda bahsettiğimiz üç dosyamızı göreceğiz

2) Derleme yapmadan önce hadoop kullanmak için yapılandırılan classpath i inceleyelim :

$ hadoop classpath

Bu kodu çalıştırdığımızda bize Hadoop core uygulamasının classlarının yüklü olduğu yerleri listeler.

3) Üç java classımızı derleyelim :

$  javac -classpath `hadoop classpath` solution/*.java

Bu kodu çalıştırdığımızda solution dosyamız içerisinde .class dosyaları oluşacaktır.

Not: Derlemeniz başarılı bir şekilde bittiyse (hata almadıysa) aşağıdaki gibi deprecated uyarılarını görmezden gelebilirsiniz.

-->Note: solution/WordCount.java uses or overrides a deprecated API.

-->Note: Recompile with -Xlint:deprecation for details

Not :
hadoop classpath
komut parçası hadoop classpath komutunu çalıştırıp çıktısını komutumuza ekler. ` ( alt + ş ) karakteri kullanmaya dikkat ediniz, komut diğer ' veya “ karakterleriyle çalışmayacaktır.

4) Derlenmiş java dosyalarını jar dosyası haline getirelim :

$ jar cvf wc.jar solution/*.class

5) roman klasörü içerisindeki romanları ve yarattığımız jar dosyasını kullanarak Mapreduce işi başlatalım.

$ hadoop jar wc.jar solution.WordCount roman kelimesayimi

Komutunu çalıştırdığımızda iş başlayacaktır.

Verdiğimiz parametrelerin açıklamaları :

Hadoop, jar wc.jar parametresi ile wc.jar dosyasını HDFS'e yükleyip işçi nodelara dağıtır.

solution.WordCount : MapReduce işimizin driver classı

roman : işin üzerinde çalışacağı klasör ismi (input)

kelimesayimi : çıktının HDFS'te kaydedileceği klasör ismi (output)

Not : İş bittiğinde üstteki komutu tekrar çalıştırmayı denerseniz hata mesajı alırsınız. İşin sonuçlarının yazıldığı klasör HDFS'te mevcut olduğu için işi tekrar çalıştırmanız gerektiğinde; output klasörü için verdiğiniz parametreyi değiştirmeniz veya bir önceki çalıştırmanızda oluşan output klasörünü HDFS'ten silmeniz gerekir.

6) Output klasörünün içeriği :

$ hadoop fs -ls kelimesayimi

komutunu çalıştırdığınızda işin çıktısının part-r-00000, _SUCCESS ve _logs gibi dosyalardan oluştuğunu görebilirsiniz. İşinizin sonuç dosyası part-r-00000 dır.

7) Çıktıları görebilmek için

$ hadoop fs -cat kelimesayimi/part-r-00000 | less
    

komutunu çalıştırabilirsiniz veya

$ hadoop fs -cat kelimesayimi/* | less
    

komutu ile de aynı sonucu görebilirsiniz

8) Output klasörünü silmek için :

$ hadoop fs -rm -r kelimesayimi

komutunu çalıştırabilirsiniz.

Not : İlk alıştırmada yaptığımız -rm komutu dosya siler. -rm -r ise klasör siler.

MapReduce işini durdurma

Komut sisteminde herhangi bir olayı durdurmak için kullandığımız ^C tuş kombinasyonu Mapreduce işimizi durdurmaz. İş çalışırken ^C tuşlarına bastığımızda sadece işin çalışma esnasında verdiği logları ekrana bastırmasını durdurabiliriz. İşimiz arka planda çalışmaya devam edecektir

1) Çalıştırdığımız MapReduce işini output klasörünün ismini değiştirip tekrar çalıştıralım :

$ hadoop jar wc.jar solution.WordCount roman kelimesayim2

2) İş çalışırken başka bir terminal açıp :

$ mapred job -list
    

Komutunu çalıştıralım. Bu komut bize şuan çalışan işlerin id’lerini listeler

Örnek olarak görünecek id: job_201432101356_0003 şeklindedir.

3) Örnekte verildiği gibi gördüğünüz job id’sini kopyalayıp :

$ mapred job -kill [kopyaladığınız id]

komutunu çalıştırdığınızda JobTracker işi durduracaktır. İşin çalıştığı orjinal terminalde de iş çalışmayı durduracaktır.

Alıştırma 3
Hive ile Ters İndeks (Inverted Index) Uygulaması

Veri Kümesi

Bu örnekte Deli Dumrul hikayesinin bir bölümü veri kümesi olarak kullanılacaktır. Veriyi inceleyelim.

$ cat ~/dilisim_materials/deli_dumrul.txt
    

Bu veri kümesi; her satırında virgüllerle ayrılmış halde satır no ve metin sütunlarından oluşuyor. Satır no tamsayı tipinde ve metin adından da anlaşılacağı gibi katar (string) tipinde.

Hive Kabuğu

Hive projesi; Hadoop üzerinde koşan bir SQL veri ambarı yazılımıdır.

VM lerinizde Hive yüklenmiş ve ayarlanmış bir şekilde hazır bulunmaktadır. hive komutunu argüman vermeden çalıştırdığınızda, sizi Hive kabuğu (Hive shell) karşılayacaktır.

$ hive

Tablo Yaratımı

Verimizin şemasına uyan bir tablo yaratmak için Hive kabuğunda aşağıdaki komutu yürütelim:

CREATE TABLE deli_dumrul(satir_no INT, metin STRING)
ROW FORMAT DELIMITED 
FIELDS TERMINATED BY ",";
    

Eğer daha önceden bir SQL standartına uyumlu veritabanı sistemi kullandıysanız, komutun ilk kısmı hiç yabancı gelmeyecektir. Hive’da VARCHAR(MAX) yerine STRING veri tipi kullanılıyor. Komutun geri kalanı bizim tablomuzun salt metin (raw-text) tipinde veri saklayacağını anlatıyor. Verinin içindeki her bir kayıtta alanlar birbirinden virgül karakteri ile ayrılıyor.

Veri Yüklenmesi

Bu aşamada geleneksel veritabanı sistemlerinde olduğu gibi elimizde boş bir tablo var. Bunu aşağıdaki Hive komutuyla teyit ettirebiliriz:

SELECT * FROM deli_dumrul;

Sonuç kümesinde sıfır kayıt dönecektir.

Şimdi yerel dosya sistemindeki bir dosyayı bu tablonun verisi olmak için sisteme yükleyelim;

LOAD DATA LOCAL INPATH '/home/dilisim/dilisim_materials/deli_dumrul.txt'
INTO TABLE deli_dumrul;

Bu komut içinde LOCAL argümanı geçtiği için INPATH kısmından sonraki dosya yerel dosya sisteminde aranacak ve bulunması halinde deli_dumrul tablosunu doldurmak için HDFS’e yüklenecektir.

Ters İndeks (Inverted Index)

Ters indeks (inverted index) bir indeks veri yapısında indeks terimlerinden konumlara eşleme olarak düşünülebilir. Bizim veri kümemiz için her bir kelimenin hangi satırlarda geçtiği bilgisini kelime ile eşleyerek bir ters indeks oluşturacağız. Bunun için aşağıdaki komutu kullanıyoruz:

SELECT kelime, collect_set(satir_no) AS satirlar
FROM deli_dumrul LATERAL VIEW explode(split(metin, ' ')) deli_dumrul AS kelime 
GROUP BY kelime;

Bu sorgu size; her bir satırda ilk sütun, kelimenin kendisi ve ikinci sütun, o kelimenin hangi satırlarda geçtiği bilgisini döndürecektir.

İlk bakışta epey karmaşık görünecek bu sorguyu parça parça inceleyelim:

Diğer SQL standartlarında olduğu gibi Hive da fonksiyon çağrılarına destek veriyor. split(metin, ' ') parçacığı ile metin sütununu boşluk karakterlerinden ayırarak bir diziye (array) dönüştürüyoruz, bu diziyi explode() fonksiyonuna verince de dizideki her bir eleman için, sonuç kümesinde bir kayıt yaratıyoruz.

Kelimelere sorgunun SELECT kısmında atıfta bulunabilmek için AS kelime kısmıyla takma ad geçiriyoruz (aliasing)

Sonuç kümesinde her kelime için bir kayıt görmek istediğimize göre kelime etrafında sonuçları gruplamak için GROUP BY kelime ifadesini kullanıyoruz. SQL’da GROUP BY yaptığımızda grup içine girmeyen sütunlara, SELECT ifadesi içinde yalnızca biriktirme (aggregation) fonksiyonları kullanarak erişebiliriz. Örnek biriktirme fonksiyonları: SUM, MIN, MAX, AVG. Bu örnekte kullanılan biriktirme fonksiyonu olan collect_set() kendisine bir küme verildiğinde, elemanlarını (tekrarları düşürerek) bir dizi gösterimine çevirir.