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.
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
Bu alıştırmada kullanılacak veriler :
~/dilisim_materials/roman
~/dilisim_materials/2013_table_logs
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 fskomutudur.
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.
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.
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
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.
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.
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.
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
hadoop classpathkomut 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)
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.
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.
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 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
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.
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 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.