Monday, September 30, 2013

Bir Veri Akış Dili: Pig

Hadoop icin yazilan bazi veri analizleri oldukca cetrefil hale gelebilir. Ilginctir ki SQL bazli veri tabanlari ortaminda tablolar, dosyalar ile ugrasirken, Buyuk Veri / Hadoop devreye girince duz dosyalar (flat file) ortamina geri donduk. Aslinda bu bir bakima iyi oldu, daha daginik, yapisiz (unstructured) veriler ile ugrasiyoruz, ve onlari sonradan analiz etmek icin daha yaratici cozumler bulmamiz gerekiyor. Verinin uzerinde onceden bir sablon koymuyoruz, analiz gerektiginde veriyi o ihtiyaca yonelik olarak okuyoruz. Veri parcali parcali, bir takim duz dosyalar, bir tar.gz dosyasi icindeki birkac, yuzlerce, binlerce bir halde karsimiza cikabiliyor.

Daha once MRJob'tan bahsettik. Bu ortamda bir islemden (job) digerine veri aktarimi kolaydir, her basamakta direk Python icinde kalarak kod yazabilirsiniz, map() icinden yayinladiginiz anahtar degerler mesela, sonraki reduce() basamagina direk Python tipleri olarak aktarilir.

Fakat MRJob'in hala bazi eksikleri var, tum veri akisinizi ayarlamak icin bir arac degil. Diyelim ki elinizde girdi olarak iki dosya var, bu dosyalari birlestireceksiniz (join) sonra sonuc olarak iki dosya ureteceksiniz, bunlarin biri, bir sonraki basamak icin referans olacak, vs. Bu tur isleri idare etmek icin bir veri analiz diline ihtiyac var.

En son surumu Pig 0.12 bu ihtiyaclara cevap veriyor, ayrica, bizim icin en onemli ozelligi Python icin Jython uzerinden degil, artik direk baglanti kurabiliyor olmasi, yani numpy, scipy gibi kutuphaneleri Pig uzerinden kullanmak mumkun olacak. Bu surum hakikaten yeni, duyurusu surada.

Konusma

Apache Pig

Pig musteri tarafinda (client side) isleyen bir programdir. Yani bir Pig script yazdigimizda bu script'i tum Hadoop makinalarina ayri ayri gondermeye gerek yoktur mesela. Pig script'iniz Hadoop kumenize baglanir, ve o kumeye, veri akis kodunuza gore arka planda bazi esle/indirge islemleri islettirir. Pig'i bir nevi derleyici gibi gorebiliriz, Pig kodu yazariz, "derleyince" arka planda EI islemleri uretilir (ve kumeye gonderilir). Demek ki tek bir makinada Pig kurulmus olmasi yeterlidir.

Once baglantidan Pig 0.12 indirin, unzip yapin. Kurulusu hduser altina yapsaniz iyi olur. Sonra su - hduser ile hduser olun ve .bashrc icine PATH sonuna [PIG DIZINI]/bin ekleyin

Kullanmak icin soyle bir veriyi

1950    0    1
1950    22    1
1950    -11    1
1949    111    1
1949    78    1


/tmp/sample.txt icine yazin. Su kodu /tmp/sample.pig icine yazin

records = LOAD '/tmp/sample.txt' AS (year:chararray, temperature:int, quality:int);

filtered_records = FILTER records BY temperature != 9999 AND (quality == 0 OR quality == 1 OR quality == 4 OR quality == 5 OR quality == 9);

grouped_records = GROUP filtered_records BY year;

max_temp = FOREACH grouped_records GENERATE group, MAX(filtered_records.temperature);

DUMP max_temp;


Simdi hduser olun, ve komut satirindan pig -x local /tmp/sample.pig isletin.

(1949,111)
(1950,22)

gibi bir sonuc ekrana basilmali. Ilk Pig script'imiz boyle.

Bir birlestirme yapalim, /tmp/A icine

Joe    2
Hank    4
Ali    0
Eve    3
Hank    2


/tmp/B icine

2    Tie
4    Coat
3    Hat
1    Scarf


Simdi /tmp/join.pig icine

A = LOAD '/tmp/A';
B = LOAD '/tmp/B';

C = JOIN A BY $0, B BY $1;
DUMP C;


Isletelim

pig -x local /tmp/join.pig

Sonuc

(2,Tie,Joe,2)
(2,Tie,Hank,2)
(3,Hat,Eve,3)
(4,Coat,Hank,4)


Kurulus Notlari

Kurulus acisindan en rahati Pig'i hduser altinda kurmak, sonra diger gunluk kullanilan kullanici icindeyken ssh hduser@localhost araciligi ile pig cagrisini hduser'a yaptirmak. Bu sekilde local durumunda ciktilar /home/hduser altina gidecektir. Bu ssh kullanimina bir ornek soyle

$ ssh hduser@localhost "\
export JAVA_HOME=/usr/lib/jvm/java-6-openjdk-amd64; \
/home/hduser/pig-0.12.0/bin/pig -x local \
/home/burak/dizin/filanca.pig \


Tabii ustte pig script'in oldugu dizinin hduser tarafindan erisilebiliyor olmasi lazim, bunu chmod +x ile script'in icinde oldugu dizinleri disariya acarak basarabilirsiniz.

Dizinler

Pig ile store ... into 'filanca' komutlari into'dan sonra gelen isim altinda bir dizin yaratir, ve sonuclar tanidik Hadoop formatinda part-r-.. gibi dosyalardir. Fakat ayni script tekrar isletilirse bu dizinin ustune yazilmaya ugrasilir ve Pig hata verir. Dizinin uzerine yazmak problem degilse, script basinda

fs -rmr filanca

ile bu dizin silinebilir, sonra script'in geri kalani o dizini yeniden yaratacaktir.

Bu yaziya ekler olacak.

Sunday, September 29, 2013

Tuesday, September 24, 2013

Yerel Ag Kurmak - Ubuntu

Ubuntu temelli bir yerel ag (network) nasil kurulur? Ubuntu uzerinden bunu yapmak aslinda cok basit (dis Internet baglantisinin paylastirma konularina daha girmiyoruz), dinamik IP adres kullanmadan, tum makinalara bir statik (ve yerel) IP adresi atayarak bu ag kurulabilir. Belki evde bir Hadoop kumesi kurmak istiyorsunuz, vs.

Once tum makinalarda sshd kurulursa iyi olur:

apt-get install openssh-server

Ag kurmak icin su resimdeki hareketler




Adres olarak 192.168.0.1 sayisi kullanildi, bu adres dis baglantilar icin anlamsiz bir sayidir, sadece yerel ic ag icinde gecerlidir. Bu tur disaridan bagimsiz IP adresleri vardir. Eger ikinci, ucuncu makinayi eklerseniz, 0.2, 0.3, vs. gibi bu makinalar adreslenebilir.

Fiziki baglanti icin en azindan switch denen bir donanim gerekli. Bu donanim uzerinde Ethernet kablo baglantilari olur, eger laptop baglanacaksa, ve son zamanlarda artik laptop'lar uzerinde Ethernet girisi olmadigi icin, bir USB / Ethernet donusturucusu lazim.

Neyse, switch baglantisi ve IP atamasi yapildigi anda o bilgisayarin komut satirindan

sudo ifconfig

isletince yeni IP'nin gorulmesi lazim. Diger makinalar baglaninca, onlardan bu makinaya

ssh 192.168.0.1 -l [kullanici]

diye erisebilirsiniz. Eger tum makinalara sifresiz (ama guvenli) baglanmak icin daha once pek cok kez bahsettigimiz ssh-keygen -t rsa, ile anahtar uretmek, sonra id_rsa.pub'in alinip oteki makinaya kopyalanip .ssh/authorized_keys'e eklenmesi, ardindan ustteki ssh (ve scp) komutu sifresiz olarak giris yapma numarasi kullanilabilir.

Kaynak

Tuesday, September 17, 2013

Storm, Python, Gercek Zamanda Veri Islemek



Storm, Hadoop'un toptan (batch) dunyada yaptigini gercek zamanli (real-time) veri akislarinda, hesaplarinda yapmaya ugrasiyor. Yatay olarak olcekleme (scaling) destekleniyor, veri akisinin muhakkak / en az bir kere islenme garantileri var. Islem noktalarinda emit() cagrisi gorulebilir, veri akisi alip veri akisi yaratmak mumkun yani. FieldsGrouping kavrami ile Hadoop'un esle/indirge basamagindaki indirge basamagi benzer kavramlar. Ustteki prezentasyon ilginc, cunku JVM / Java bazli Storm icin arkadas bir Python arayuzu yaratmis. Kod suna benziyor:


MariaDB

Link

En populer veri tabani sistemi olmasina ragmen, Oracle'in MySQL'nin basi dertte. Red Hat ve SuSE gibi en unlu Linux dagitimlari paketlerinden MySQL'i cikartip yerine onun kodundan gelistirilmeye baslanmis (fork) MariaDB'ye geciyor. Wikipedia gibi buyuk Web siteleri de arka plan kodlarini MySQL'den MariaDB'ye geciriyorlar. En son da Google'in MySQL'i atip yerine MariaDB'ye gecmesi yaraya tuz surmek gibi oldu.

---

Bu konu hakkinda daha once yazmistik. Acik kaynak dunyasinda care tukenmez. Fakat problem cikmadan once insanlarin gecis yapmaya baslamalari ilginc. Burada ticari bir sirketin acik kaynak bir yazilima sahip olmasinin diger ticari sirketler icin potansiyel problemi olabilme durumu var. Oracle ileride MySQL'i bir silah gibi kullanabilir; kimse Oracle'a guvenmiyor. O yuzden problem cikmadan once MySQL'i kenara atmak, ozellikle Google gibi bir sirketin isine gelir.

Thursday, September 12, 2013

Python ile SQL Tabandan CSV Uretmek

Alttaki kod SQL ile kursor (cursor) acarak veriyi satir satir alir ve CSV dosyasina yazar. Oracle icin

import csv
import cx_Oracle as odb


oraclepass = [SIFRE]
user = [KULLANICI]
conn = odb.connect("%s/%s@TABAN" % (user,oraclepass) )

cursor = conn.cursor()
query = """
select vs,vs from vs
"""

cursor.execute(query)

csv_writer = csv.writer(open("/tmp/out.csv", "wt"),delimiter=';')
csv_writer.writerow([i[0] for i in cursor.description])
csv_writer.writerows(cursor)
del csv_writer



Tuesday, September 3, 2013

MySQL Kurulus

MySQL Ubuntu kurulusu

sudo apt-get install mysql-server

Baglanmak (kendi makinanizdan)

mysql --host=localhost --user=root --password=[sifre]

Kurulurken root icin sifre vs istenir, fakat bu kullanici disaridan kullanis sirasinda problem cikartir. Makina ici ve disindan kullanilacak bir kullanici yaratmak icin (suradan)

CREATE USER 'monty'@'localhost' IDENTIFIED BY 'some_pass';
GRANT ALL PRIVILEGES ON *.* TO 'monty'@'localhost'
    WITH GRANT OPTION;
CREATE USER 'monty'@'%' IDENTIFIED BY 'some_pass';
GRANT ALL PRIVILEGES ON *.* TO 'monty'@'%'
    WITH GRANT OPTION;


Taban Dizini

Eger veri tabanlarinin tutuldugu dizini degistirmek istiyorsaniz, /etc/mysql/my.cnf ayar dosyasindaki dataDir dizini degismeli. Hatta mevcut tabanlarin verisini kaybetmeden sadece dataDir'deki dizini oldugu gibi yeni yere kopyalayip, yeni dizinden ise devam etmek mumkun. Dikkat, kopyalanan yeni yerdeki erisim haklari mysql kullanicisina olmali. Tabii ondan once sudo service mysql stop ile servisi durdurmayi unutmayin.

MySQLdb, Pandas

Ubuntu uzerinde kurmak icin

sudo pip install pip --upgrade

sudo easy_install -U distribute

sudo apt-get build-dep python-mysqldb

sudo pip install MySQL-python


Ornek kod

import MySQLdb, os, sys

conn= MySQLdb.connect(host='makina',
                      port=3306,user='user', passwd='sifre',
                      db='test')


Bir Pandas dataframe'i alarak veri tabanina yazmak muthis kolay:

pd.io.sql.write_frame(df, "tablo1", conn, flavor='mysql')

Ustteki ifade df icindeki dataframe'i alip veri tiplerini ayarlayip Mysql'de tablo yaratacak ve veriyi tabloya ekleyecektir. Eger tablo mevcut ise ikinci isletim hata verebilir, tablo yokedilip tekrar bastan yaratilsin istersek,

pd.io.sql.write_frame(df, "tablo1", conn, flavor='mysql', if_exists='replace')

Eger dataframe verisi mevcut tabloya "eklensin" istiyorsak,

pd.io.sql.write_frame(df, "tablo1", conn, flavor='mysql', if_exists='append')

Basit bir SQL (DDL usulu, mesela bir DELETE komutu)

sql = "delete from tablo where kolon1 = %d and kolon2 = %d" % (arg1,arg2)
conn.cursor().execute(sql)
conn.commit()