Wednesday, April 29, 2009

Google AppEngine ve Java

Google'in uygulamalari barindiran servisi AppEngine ilk once Python destegi ile cikmisti, yeni bir dil daha eklendi: Java. AppEngine EC2 aksine, sadece "anahtar teslim bos makina" degil, bir programlama altyapisi da sunuyor; yani kodunuz onlarin altyapisina gore yazilmak zorunda. Secilen teknolojilerin arasinda JDO goruyoruz! Iyi degil!

AppEgine yontemi bizim icin kisitlayici metot. Muhakkak, bu tur bir servisin de musterisi olacaktir, ki var, fakat barindirma alaninda biz daha fazla esneklik taraftariyiz. Eger Google'in basina bir sey gelirse (zor ama), kodu alip aninda baska bir barindirma ortamina gecirebilmeyi umariz, Google'in kullandigi yazilim dis bir sistemde de kurulabilir, ama bu efor, tesvik edilen bir yonde olmadigi icin, zorlayici olacaktir.

DJ Patil

Buyuk veri setleri analizi hakkinda ilginc bir video: Konusan DJ Patil adinda Hint asilli Amerikan bir bilim adami. Nonlineer matematik, hava tahmini (climate prediction) dunyasindan geliyor, ve Web verisi analizi isine girmis. Su anda LinkedIn sirketinde calisiyor ve (dogal olarak) Hadoop kullanmakta. Patil, daha once hukumet icin calisarak buyuk veri setlerinden terorist bulma isinde de ugrasmis. Devletlerin guvenlik birimleri buyuk veri setleri ile dogal olarak ilgileniyorlar; gecende Google ve Yahoo sirketleri ortaklasa olarak bir devlet birimi olan NSA icin koca bir Hadoop kumesi kurdular. Patil'in sektorun gidisati hakkinda ilginc yorumlari var.

Tuesday, April 28, 2009

Matplotlib

Bilimsel hesaplamada Matlab yerine Python cabasinin son basamagi veri ve fonksiyon grafikleme icin Matplotlib olacak. Bu kutuphane islemek icin Numpy'a gereksinim duyuyor. Kurmak icin sitesinden kaynaklari indirdik, ve actiktan sonra dizinde daha onceki gibi
sudo python setup.py build
sudo python setup.py install
Ornek program olarak
import numpy as np
import matplotlib.pyplot as plt

ax = plt.subplot(111)

t = np.arange(0.0, 5.0, 0.01)
s = np.cos(2*np.pi*t)
line, = plt.plot(t, s, lw=2)

plt.annotate('local max', xy=(2, 1), xytext=(3, 1.5),
arrowprops=dict(facecolor='black', shrink=0.05),
)

plt.ylim(-2,2)
plt.show()
Ustteki sozdizimin Matlab kullanimina oldukca benzedigini dikkatinizi cekerim; Bu sayede Matlab kullanicilarinin yazilimlarina gecisini rahatlatmayi ummuslar herhalde. Sonuc altta:

Git, Emacs, Python: Dosyalarin Eski Hali

Python ile Emacs eklentisi yazilmasini saglayan Pymacs uzerinde yazilan bir Git yardimci programi alttadir. Herhangi bir dosya uzerindeyken M-x githist-do-show-version yazip (menuye baglanabilir) sorulan soruya bir rakam ile cevap verilince o rakam kadar Git icindeki tarihte geriye gidilip, dosyanin o versiyondaki hali cikartilarak ayri bir Emacs buffer olarak gosterilmekte. Isletilen komut
git show master~[rakam]:noktagit/seviyesinden/baslayan/dizin/ismi/Dosya.java
Kurmak icin Python kodu surada, site-lisp altina kopyalanmali, ve .emacs degisikligi:
(pymacs-load "/usr/share/emacs/22.2/site-lisp/githist")

(defun githist-do-show-version(num)
(interactive "nKac commit oncesine gidelim: ")
(githist-show-version num)
)
Ingilizce blog'daki haber:

Monday, April 27, 2009

Scipy

Matlab yerine pur acik yazilim ve Python temelli arayisimiz baglaminda surada sunulan listeden devam ediyoruz.

Numpy kurduktan sonra Scipy kurmak icin resmi sitesine gidelim. Ben Sourceforge sitelerinden kaynaklari indirdim. Indirip actiktan sonra o dizinde
sudo python setup.py install
uygulayin. Ornek kod olarak Fast Fourier Transform yapan bir ornek:
from scipy import *
x=r_[1:4]
h1=zeros(15); h1[0]=1
h2=zeros(15); h2[6]=1
h3=zeros(15); h3[12]=1
print convolve(h1+h2+h3,x)
Sonuc
[ 1.  2.  3.  0.  0.  0.  1.  2.  3.  0.  0.  0.  1.  2.  3.  0.  0.]
olarak geri gelmeli.

Scipy'i derlerken arka planda Fortran kodlarinin, optimizasyon, diferansiyel denklem cozme amacli yazilmis C rutinlerinin derlendigini, Lapack gibi bilimsel cevrelerde cok iyi bilinen isimlerin gectigini goreceksiniz. Bu projenin hic sakasi yok. Ciddi bir bilimsel hesaplama araci olmaya yeminli gozukuyorlar.

Sunday, April 26, 2009

Cok Cekirdekli Islemciler

Mahout sitesinde bir makalenin islemciler ile alakali bolumunde guzel bir saptama:

"Mikroislemcilerde frekans bazli olcekleme yapmak, yani islemcinin saat hizini daha yukselterek daha yuksek performans elde etmek guc kaynagi kullanimi sinirlarina carpmaya basladi. Islemcinin boyutu kuculdukce guc sizmasi (power leakage) yasaniyor. Diger taraftan Moore kanununa gore islemcilerin yogunlugu her nesilde ikiye katlanacaktir. O zaman frekansi sabit tutarak ama her cipteki islemci cekirdegi ikiye katlayarak hala dusuk guc kullaniminda devam edebiliriz ve islemci gucunu ikiye katlamis oluruz. Bu durum, mikrocip endustrisini cok cekirdekli mimarilere itmistir".

Yani soylenmek istenen tek islemcinin transistor yogunlugu ile oynayarak artik daha fazla hiz elde edemiyoruz, bazi sinirlara toslamaya basladik. O zaman cok cekirdekli mimari, ayni hizda ama paralel calisan ek cekirdekler koyarak hizlanmayi saglayacaktir.

Bunun programcilar icin getirdikleri faydalar / sorunlar nelerdir? Programcilar daha paralel kodlama baglaminda dusunmeye alismali, programlama dilleri bu servisleri daha rahat saglayabilmeli. Referans verilen makale paralelizasyon fikrini yapay ogrenim konularina uygulamaya calisiyor mesela. Yelpazenin diger ucunda ise, daha fazla paralel calisan "makinalarin" sayesinde devasa boyutlarda veri isleyebilme konulari var. Aslinda bu iki trend birbiriyle yakinda alakali. Hem tekil makinalarin fiyati ucuzlarken, hem de tekil makinalarin icindeki paralel cekirdeklerin sayisi artiyor. Yelpazenin her noktasinda paralelizasyona dogru bir gidisat yasaniyor.

Bu konu hakkinda hemen bir sey yapilmasi gerekli demiyoruz; sadece akilda tutulmasi gereken bir konu.

Wednesday, April 22, 2009

Kimlik Uzerinden Db Yuk Dagilimi

Anahtar-deger tabanlarinin, ozellikle Amazon Dynamo modelini takip edenlerin, kimlik (id) degerine bakarak yuk dagilimini yaptigini anlatmistik. Bunu nasil yapiyorlar? Nasil yapmak mantikli olurdu? Oyle bir yonlendirici fonksiyon bulalim ki, bu fonsiyon rasgele ama ayni deger icin "hep ayni sekilde rasgele" bir nod'a yonlendirsin. Yonlendirme icin db kumesine sormamiz gerekmesin, cunku db'ye ne kadar az gidersek, performansta o kadar kazanc saglariz.

O zaman matematikteki "mod" fonksiyonunu kullanabiliriz. Elimizdeki herhangi bir ID degerine elimizdeki db makina sayisiyla mod bolumu yapariz, sonuc yonlendirilecegimiz DB nod kimligi olur. Diyelim elimizde 4352345234 degeri var, ve 5 tane db makinasi var. 4352345234 mod 5 = 4.

Demek ki 4 no'lu makinaya gidecegiz.

Dikkat edilirse, mod bolumu ayni sayilar icin hep ayni degeri verir. 4. makinaya yazdigimiz degeri baska makinada aramis olmayiz yani. Ayrica mod hep ayni seviyede, dengeli (uniform) bir dagilim yaparak yukun hep ayni makinalara gitmesine de engel olur. Ve en onemlisi mod bolumunun nod sayisindan fazla bir sayi dondurmesi mumkun degildir.

Not 1: Yari-rasgele (pseudorandom) sayi ureteclerinin hep mod fonksiyonunu kullandigi ilginc bir ek ayrintidir.

Not 2: Biz sistemimizde db'ye gidis/gelisi azaltmak icin yeni objeler icin ID uretimini bile DB'ye yaptirmayacagiz; kimligi Java UUID() objesini kullanarak urettirecegiz.

Tuesday, April 21, 2009

Git ile Baslangic

Git ile kaynak kod idaresine baslamak cok kolay. Depoya cevirilecek bir dizine girilir ve alttakiler komut satirinda isletilir.
git init
git add .
git commit -m "ilk commit burada"
Gorsel olarak Git kullanmak icin Gitk var. Emacs uzerinden Git komutlari kullanabilmek icin git-emacs paketi oldukca iyi; tanidik C-x v v komutlari bulunabilir, yorumlar editor icinden girilebiliyor, vs.

Git sisteminin neler yapabildigini ogrenmek icin Git Magic e-kitabini da tavsiye ederim.

Git her kullanicinin kendi deposunu merkez alarak "yerel" calisabilmesini saglar; mesela dallanma, birlestirme gibi hicbir islem icin network'teki bir "merkezi" servise bagli olmaniz gerekli degildir. Git'teki ana kavram "klonlama", "cekmek" ve "itmek" kavramlaridir, ki bu islemlerin hepsi de ayni depodan baslayan ama uzerlerinde ayri calisilan bagimsiz depolari temel alirlar. Iki programci, sadece birbirlerine gercekten kod vermek istedigi zaman, network uzerinden birbirine kod itip, ceker.

Bizim ilk Git kullanisimiz yedekleme amacliydi, ayrica iki makinada ayni kod uzerinde calisiyor olmamiz bir sekilde idare edilmeliydi. Isin ilginc tarafi, bahsedilen turden kullanimlar icin Git'in mentalitesinden hic disari cikmiyorsunuz. Yedeklemede, yedek olan depo sanki uzerinde hicbir programcinin calismadigi bir "klon" haline geliyor, ayri makinada uzerinde calisilan ayni kod ise (aslinda ayni olan) sanki iki programcinin iki ayri klon uzerinde calisiyor olmasi haline geliyor.

Basit yedekleme ile baslayalim: Bir dizini Gitlestirdikten sonra, yedek icin onu baska bir dizine klonluyoruz:
git clone /dizin/ismi/
Eger ssh uzerinden baska bir makinaya yedekliyorsak, once uzaktaki makinada /dizin/ismi diye bir dizin yaratip o dizin altinda "git init" islettikten sonra lokal makinada sunu isletebiliriz:
git push ssh://kullanici@makina/dizin/ismi master
Bunu islettikten sonra uzaktaki makinadaki dizinin bos oldugunu gorebilirsiniz; o dizin altinda "git checkout master" islettikten sonra dosyalar gorunur olacaktir.

Kendi kopyamiz uzerinde calisiyoruz, istedigimiz kadar commit ediyoruz, vs. Sonra klona (yani yedege) farklari gondermek istiyorsak, o zaman yine ayni komutu benzer sekilde isletiyoruz.
git push ssh://kullanici@makina/dizin/ismi

Uzaktaki makinada guncellenme gerceklestirilmistir; fakat o makinada da en son fiziki dosyalara bakmak isterseniz, o zaman "git reset --hard" komutunu vermeyi unutmayin. Bu komut Git'e "en son commit noktasina gitmesini" soyleyen bir komuttur, en son commit noktasi da push ettiginiz nokta olduguna gore fiziki dosyalar o noktadaki hale donusecektir.

Diyelim ki kendi kod bazimiza bir sey oldu, silindi, vs. Derde gerek yok; Yedeklenmis klon, klonlandigi (ve guncellendigi) andan itibaren tum commit tarihini, her seyi iceren asil bir depodur, o zaman bu depoyu kendimize geri klonlayarak kaldigimiz yerden devam edebilirdik.

Iki makinada farkli klonlarda calisma durumunda ise, klonlari senkronize etmek isteyen kendine kodu "ceker" ve cakismalari cozerek kendi deposuna commit eder, sonra git push ile bu senkronize edilmis hali ikinci klona gonderir.

Onemli bir faktor: Git cok hizli calismaktadir. Linus Torvalds Git'i kernel kodunu idare edebilmek icin yazdi, ve bu kodun ne boyutlarda oldugu bilinen bir sey. Bu gereklilikler isiginda Git hizli isleyecek sekilde tasarlanmis.

Github

Github sitesi "sosyal kodlama" sloganiyla yola cikmis bir sitedir. Bir Git kod deposu, hem yerel hem Github'da tutulur, tabii Git'in "kisiye ozel" ruhuna uygun olarak, birisi Github'da gordugu bir "programcinin projesinde" degisiklik yapmak isterse, bunu o depoyu o "programcinin hesabindan kendi hesabina" klonlayarak yapar. Sonra, tabii ki, kendi hesabindan bir de kendi lokal makinasina klonlama yapar. Lokal kopyada calismalarina baslar.

Mesela; biz Voldemort projesiyle ilgileniyoruz ve bu projeyi ijuma adli arkadastan klonladik.

Bizim kendi baslattigimiz proje pyjde Github uzerinde, oradan isteyen klonlabilir. Bunu yaparak aslinda Github'i hem bir yedekleme noktasi, hem de baskalari ile kodu paylasma ortami olarak kullaniyoruz.

Yedeklemeden bahsedelim: Kendi yerel pyjde klonumuzda (ya da aslimizda) calisip commit ediyoruz. Kodu herkese gostermek ve/ya yedeklemek istedigimizde ise,
git push git@github.com:burakbayramli/pyjde.git
komutu yeterli oluyor. Ustteki url'in ne oldugunu Github size acik bir sekilde gosteriyor, karistirmaya hacet yok. Yanliz dikkat: kullanilmasi gereken "Your" Clone URL, oteki URL degil. Ayrica Github'a kod gonderebilmek icin ssh public anahtarinizi Github'a vermis olmaniz lazim. Ssh konusunu blog'da cok kez isledik (Kurumsal Java kitabinda da konuda bir bolum var). ssh-keygen -t rsa ile urettiginiz .ssh/id_rsa.pub dosyasi icindekileri Github'a verince is bitiyor, bir guven hatti olusuyor, ve sifresiz sekilde Github sanki kendi network'unuze dahil bir makinaymis gibi oraya kod gonderebiliyorsunuz. Ssh ayarlari ustteki kullanici@makina ornegi icin de gecerli tabii ki. Birden fazla makina uzerinde calisiyorsaniz o makinada anahtar uretimi yapip bu yeni anahtarin public olanini Github'a verince (Add Key ile) o makinadan da sifresiz olarak calisabilmeye basliyorsunuz.

Bir not daha: Anahtari proje bazinde degil, hesabiniz (account) bazinda tanimlayin. Butun projeleriniz ayni anahtari kullanabilsin yani. Bunun icin Github sayfanizda "Account Settings" menusunu secin, ve oradan "SSH Public Keys"'e gidin. Burada id_rsa.pub dosyanizin icindeki degerleri ekleyebileceginiz secenekler var. Birden fazla acik anahtar eklenebilir, eklenenler silinebilir, vs.

Bir suredir Git kullaniyorum, ve kesinlikle CVS ve Subversion'a donmek gibi bir istegim kalmadi. Gidisat dagitik calisabilen kod depolama sistemleri yonunde; bu sosyal network kavrami ile de birebir uyum icinde; Github'da, aynen Twitter'da oldugu gibi, birini "izlemeye" baslayabiliyorsunuz. Bir "news feed" ozelligi var ve Facebook'ta arkadas takip eder gibi projesini klonladiginiz ya da izlediginiz kisinin commit'leri news feed'inizde gozukuyor!

Github sadece acik yazilim projeleri icin degil, artik sirketler de kodlarini Github uzerine tutuyorlar. Bir admin sizi eklemezse bu projeleri goremiyorunuz yani ama bunun haricinde hersey normal bir Git projesi idaresi ile ayni.

Oracle Gunesi Gorunce

Oracle Sun'i satin aldi, sektorde calkalanmalar oldu. Konu pek cok programciyi ilgilendiriyor cunku acik yazilim olan MySQL Sun tarafindan alinmisti, simdi Oracle Sun'i alinca MySQL'i almis oldu. Bir de.. Java! Sun'a ait IT'nin en populer dili Oracle'a gecince ne olacak?

Sahsi gorusumuz, Oracle'in Java'nin acik kalmasinda cikari oldugudur, onu kapatmakla hicbir sey kazanamaz. Bu sebeple Java'nin durumunun degisecegini zannetmiyoruz. MySQL durumunda ise, sunu belirtmek lazim, ki bu butun GPL lisansi altindaki yazilimlar icin gecerli, bir kodu GPL altinda actiginizda, o kod aciktir. Nokta. Dogru: Oracle MySql'i kendi tabanina rakip gorup onu yoketme amaciyla MySQL'e "hic zaman harcamayarak" onu "ilgisizlikten oldurmeye" ugrasabilir, ama acik yazilimin guzel tarafi o ki, etrafta zaten populer MySQL'den dallanmis, budaklanmis alternatifler var. Drizzle bunlardan bir tanesi mesela.

Stallman GPL lisansini kursun gecirmez bir sekilde hazirlatmis ise, iste onu bu tur zamanlar icin yapti.

Sonuc? Java; Korkuya gerek yok. MySQL; Olebilir, ama Drizzle ile devam edersin.

Tabii biz durumu gozlemeye devam edecegiz; Oracle tepemizi attirirsa (!), Web kodlamasi icin de Python'a gecisi yapiveririz. Su anda bunu gerektirecek bir durum yok.

Isin Oracle DB kismi bizi zaten hic ilgilendirmiyor, cunku online veri islem amacli olarak iliskisel taban bile kullanmayacagiz, o tarafta anahtar-deger tabani Voldemort olacak. MySql'i sadece fulltext ozelligi icin her app server'da "biraz daha akilli bir dosya sistemi" olarak kullaniyorduk, MySql'in "basina bir sey" gelirse, bu ozellik icin Drizzle hemen kullanilabilir.

Isin isletim sistem tarafi bizi hic ilgilendirmiyor, orada EC2 uzerinde Ubuntu Server kullaniyoruz, Solaris degil.

Bizim, genel itibariyle, altyapi yazilimi olarak kodu kapali olan hicbir urunu kullanmama yaklasimimiz devam edecek; ve bizim gibi pek cok yazilimcinin varligi Oracle/Sun birlesmesinin etkilerinin az olacaginin da garantisi bir bakima.

Monday, April 20, 2009

Stallman ve Tasarim

GNU hareketinin kurucusu Richard Stallman'dan veciz bir soz:

"Emacs programi, her noktayi dikkatle planmayi dikte eden tur bir surecle ortaya cikamazdi. O tur surecler sadece onceden ne olduklari ve niye istenildigi cok iyi anlasilmis hedeflere erismek icin kullanilirlar. Emacs'i yazmadan once ne ben ne de bir baskasi ucuncu partiler tarafindan eklenebilen, buyutulebilen bir gorsel editor hayal edebiliyordu, ne de bu tur eklenebilen bir yazilimin faydalarini, onu ilk elden tecrubeleyince kadar, bilebiliyordu. Emacs mevcut olabilmisse, bu, sonu bile gozukmeyen bir yolda ufak iyilestirmeleri yapmakta kendimi ozgur hissetmem sayesinde olmustur".

Thursday, April 16, 2009

@Out ve @Scope

Seam programlamasinda oturum uzerinde veri saklamak zararli degildir, hatta bu tur tasarimlar Seam yaraticisi tarafindan cesaretlendirilmektedir. Ne de olsa, modern Web mimarisi, yapiskan oturum kavramina sahiptir, yuk dagiticisi (HAProxy, Apache) bir kere bir oturumu bir makinaya yonlendirdiginde o oturum altindaki tum diger istekleri ayni makinaya gondermesi gerektigini bilir. Boylece ayni app server icinde Java objeleri rahatca paylasilabilir.

Oturum bazli objeleri islem yapan Session Bean'lere enjekte ederek veriyoruz, de-enjekte ederek dis dunya ile paylasiyoruz. Eger tipik bir kullanimda bir Person objesi bir aksiyona veriliyor, orada islem gorup sonra disari veriliyorsa,
@In @Out
Person person;
gibi bir sekilde tanimlanir. Simdi dikkat; gelen ayni objenin disari gitmesini istiyorsak, o zaman bu objeyi class bazinda SESSION (oturum) olarak tanimlamaliyiz. Yani soyle;
@Name("person")
@Scope(SESSION)
public class Person implements Serializable {
...
}

Sunday, April 12, 2009

gksudo

Eger app server programini sudo olarak isletiyorsak, o zaman server'in sayfalarimiza tekabul eden "gecici dosyalari" (server/default/tmp altinda) root kullaniya ait olarak uretilecektir. Biz hizli gelistirme amacli olarak pagecopy.py adli bir Python script'i ile bu gecici dizinlere parasutle xhtml dosyalari atiyorduk, boylece server baslatmaya gerek kalmiyordu.

Ama IDE'niz normal bir kullanici altinda basladigi icin, o kullanici tarafindan root'a ait dosyalarin ustune yazarken hata mesaji gelir. Cozum: Python script'i root olarak isletmek. Fakat puf nokta: Script'i sudo ile isletirsek sifre sorma IDE icinde gerceklesecek, buna text girisi yapmak mumkun olmayabilir. O zaman sudo yerine gksudo kullanilacak ki IDE disinda bir GUI penceresi acilsin, sifre oradan alinsin.

Bu sifre bir kere alininca IDE acik oldugu surece bir daha alinmasina gerek yoktur. Build.xml altta:
<target name="send">
<exec executable="gksudo">
<arg line="python"/>
<arg line="src/script/pagecopy.py"/>
</exec>
</target>

Yerel Makinada FB Connect Testleri

Yerel makinanizda FB Connect uygulamalari test edebilmek icin birkac ufak numara yeterli. Su yazidaki kodlari kullanalim. Once FB admin sayfasinda uygulamamizin Callback URL ve Connect URL'i olarak (mesela) http://bizimsiteismi.com girelim. Sonra yerel makinamizda (bizde Ubuntu) ustteki adresi 127.0.0.1'e map etmek gerekecek. Bunu yaparak FB baglanti kodlarini 'kandirmayi' umuyoruz; boylece FB adresi olan gercek bir makinaya baglandigini zannederken yerel makinaya baglaniyor olacak.

Hemen /etc/hosts dosyasina giriyoruz ve
127.0.0.1      bizimsiteismi.com
satirini giriyoruz. Sonra JBoss kurulum dizinine gidiyoruz, ve surada anlatilan degisiklikleri yapiyoruz ki, JBoss 8080 yerine 80 adresinde baslasin. JBoss sudo erisimi olmayan bir kullanici altindaysa, bu degisikligi yaptiktan sonra erisim hatasi alabilirsiniz, cunku Unix'te belli bir port degerinin altindakilere erisim icin root olmak gerekir; o zaman JBoss'u sudo olarak baslatmaniz gerekecek.

Sonra, Seam uygulamamizda META-INF/application.xml dosyasina girip context-root ayarini /uygulamaismi gibi bir degerden sadece / degerine set ediyoruz, boylece tarayicimiza http://bizimsiteismi.com girdigimizde direk ana sayfamizi yuklensin.

Bu kadar. Eger xd_receiver.htm dosyasini ust seviye dizininize koymayi unutmadiysaniz, daha once paylasmis oldugumuz test FB kodlarinin sayfasini tarayici ile ziyaret ettiginizde arkadaslarinizin listesini FQL ile alabiliyor olmaniz lazim. Statik IP adresi olan bir makinaya hic gerek yok.

Saturday, April 11, 2009

Hadoop

Anlik islem yapan (online) veri tabanlarinda anahtar-deger kavramina bir gidis oldugundan bahsettik; Aynen bu gidiste oldugu gibi, arka planda (offline) veri isleyen, analitik tabanlarda da benzer bir gidisat goruluyor. Google, Yahoo ve Facebook gibi sirketler devasa boyutlarda veriyi analiz etmek icin artik SQL, RDBMS kullanmiyorlar. Hadoop adli, yine anahtar-deger teknigini kullanan bir urunu kullaniyorlar.

Hadoop'un temelindeki teknik "esle/indirge (map/reduce)" adindaki bir tekniktir. Bu teknik Apache tarafindan open source ortama getirildi, ve Hadoop bu sekilde dunyaya geldi. Teknolojinin cikis noktasi Google; bu sirketin Web'den cektigi terabaytlarca veriyi analiz etmesi gerektigi icin, esle/indirge teknolojisini gelistirdiler, gelistirmeye mecbur oldular.

Esle/indirge nedir? Online tabanlarda anahtar degeri belli bir makinaya yonlendirmek icin kullaniliyor, bunu isledik. Esle/indirge tabanlarinda ise, anahtar degeri esle surecinde her nod uzerindeki veriye bakilarak bir "ozet" cikarmak icin kullaniliyor. Indirge surecinde ise her ayri nod'daki anahtar-deger ciftleri alinarak uyusan anahtarlar bir daha birlestiriliyor. Bu son birlesim bize nihai sonucu veriyor.

Hadoop, yatay olarak olceklenebilen bir teknoloji, bu sebeple kumedeki her makina kendi verisine sahip, yani tum islem o makinaya yerel. Ayni online dunyada oldugu gibi (mesela Voldemort) her nod kendi verisini cokusten kurtulmak amaciyla kumede birkac diger bilgisayara yedek olarak gonderebilmekte. Hadoop'ta degisik olan bir "idare edici" yani "gorev verici" makinanin olmasi. Burada bir mahsur yok; Esle/indirge arka planda calisan bir teknoloji oldugu icin dagitici konduktor sistem, eger iyi tasarlanmissa, bir hassas nokta haline gelmez. Isin en agir kismi zaten kumedeki islemci nodlar tarafindan ustlenmekte. Hadoop'ta yapilacak islemler tipik olarak bir "Job" olarak yaziliyor. Job'inizi yaziyorsunuz, ve Hadoop kumenize veriyorsunuz.

Bir ornek dusunelim: Elimizde koca bir dosya var, bu dosyada her satirda bir meyve ismi, ve o meyve satin alindiginda ne kadar para odenmis oldugu yazili olsun (alttaki koca bir dosya degil ama oldugunu dusunelim). Amacimiz her meyve icin toplam ne kadar harcandigini bulmak.

armut 10
portakal 3
incir 9
armut 9
armut 10
incir 3
mandalin 2
erik 29

Burada anahtar degerleri meyve isimleri olacak. Diyelim ki Hadoop kumemizde 2 nod var, ve ustteki dosyayi Hadoop'a verdik.

Hadoop bu dosyayi iki esit parcaya bolecektir (anahtar degerlerine hic bakmadan, burasi online'dan farkli), ve diyelim ki bolunme tam ortadan yapildi:

armut 10
portakal 3
incir 9
armut 9
----
armut 10
incir 3
mandalin 2
incir 29

Her nod, kendi icinde "esle" yaparken, benzer anahtar degerlerini ayni toplama yazacak. Bolum 1) armut = 19, portakal = 3, incir = 9. Bolum 2) armut 10, incir = 32, mandalin = 2.

Her bolumun isi boylece bitiyor, yani esle sahfasi sona eriyor. Bundan sonra "indirge" kisminda her bolumdeki anahtarlar bir de kendi aralarinda toplaniyorlar. Boylece armut = 29, portakal = 3, incir = 41, mandalin = 2. Bu en son sonuc. Bu son derece basitlestirilmis bir ornektir, fakat isin ozunu anlatabildik zannediyorum.

Aktarilan bilgilere gore, sasirtici derecede cok sayidaki analiz islemi, ustteki esle/indirge mentalitesine uyarlanabilmektedir.

Haberdar olunmasi gereken muthis orneklerden biri, makina ogrenimi algoritmalarinin ayni esle/indirge sistemine uyarlanabilmis olmasidir. Mahout projesi bunu open source ortamina tasimaya aday oldu. Rapor edilen sonuclara gore eklenen her mikroislemci kor'u (Hadoop nod'u gibi) esle/indirge ile kodlanmis makina ogrenimi algoritmasini bir o kadar hizlandirmaktadir. Yani performans kazinimi "lineer" sekilde artabilmektedir. Her eklenen kor bir o kadar hizlanma getirmektedir.

Bir diger haber: Amazon sirketinin EC2 servisini biliyoruz. EC2'nin en son servisi, hazir pisirilmis bir Hadoop kumesi servisi vermeye baslamasi. Amazon bu Hadoop sistemini universitelere ogretim amacli olarak ucretsiz olarak ta sunmakta.

Anahtar-deger yaklasiminin basarisinin sebebi onun kavramsal basitliginde yatiyor olmali. Bu sebeple cok rahat bir sekilde yatay sekilde dagitilabilen veri yapilariyla islem yapmamiza izin veriyor.

Hadoop projesi uyelerinden Christophe Bisciglia ile yapilan bir roportajin ses kaydi surada bulunabilir.

Monday, April 6, 2009

Pymacs

Lisp surekli kullandigim dillerden biri degil; sadece uzun aralarla Emacs editorumu kisisellestirmek icin kullaniyorum ve uzun sure gectikten bazi Lisp numaralarini tekrar ogrenmem gerekiyor. Bir araci birden yerde fazla kullanabilme meraklisi oldugumuz icin Lisp'ten mumkun oldugu kadar uzak durmaya karar verdik. Bu kararda onemli bir faktor, bir editor uzantisi icin okkali kodlama yapmamiz gerektigi idi... Peki bu is hangi dilde yapilacakti?

Bilimsel hesaplama icin zaten Python kullanmaya karar vermistik. Acaba Python'u Emacs'i uzatmak/kisisellestirmek icin kullanamaz miyiz?

Editor uzantisi kodlamanin agir siklet kismi icin de Perl kullanmayi dusunuyorduk, cunku bir suru dosya/dizin gezme/isleme gerekecekti, fakat bu kullanimda Perl yerine de Python kullanabilirdik. Bir tasla iki kus.

Biraz arama sonucunda Emacs'i Python ile uzatmami saglayacak bir araci buldum: Pymacs. Pymacs, tum Emacs lisp fonksiyonlarina bir Python script'i icinden ve tum Python modullerine de Emacs icinden erisebilmenize izin veriyor. Kurmak icin ya apt-get ile ya da kaynagi indirip python setup.py install ile kurabilirsiniz. Tarifleri takip edin, oldukca kolay.

Hemen bir Emacs uzantisi yazalim, mesela pymacstest.py adinda bir program yazalim; bu programi /usr/share/emacs/22.2/site-lisp/ altinda diger EL dosyalari ile birlikte tuttugunuzu varsayalim. O zaman .emacs icinden

(pymacs-load "/usr/share/emacs/22.2/site-lisp/pymacstest")

cagrisi yuklemek icin yeterli. Bu kod icinde neler olsun?

from Pymacs import lisp

def test():
    lisp.message("i am here")


Gordugunuz uzere lisp objesi uzerinde Emacs metotlari var; lisp.message cagrisi elisp icindeki (message "..") cagrisini yapiyor. pymacstest.test cagrisini yapmak artik cocuk oyuncagi, Pymacs isimlendirme kurallarina gore, dosya ismi + "-" + metot ismi kullanarak bu cagri Lisp tarafindan yapilabiliyor. Metot ismi demek ki pymacstest-test olacak.

Hizli gelistirme icin bazi numaralar; Python kodu degistigi zaman modulu tekrar yuklettirmek icin *Pymacs* isimli buffer'i oldurmek, sonra modulu tekrar yuklemek. Bizim .emacs dosyamiz su anda soyle (baska modul ve metot isimleriyle):

(defun reload-pyjde()
(interactive)
(if (buffer-live-p (get-buffer "*Pymacs*" ))
   (kill-buffer (get-buffer
         "*Pymacs*")))
(pymacs-load "/usr/share/emacs/22.2/site-lisp/pyjde")
)

(defun test-me()
(interactive)
(pyjde-test)
)

(global-set-key [f5] 'test-me)
(global-set-key [f11] 'reload-pyjde)
(reload-pyjde)


Boylece gelistirme sirasinda pyjde.py dosyasi degistikce F11 tusu ile kodu tekrar yukletip F5 ile cagriyi yapabiliyoruz. Metot test-me() daha sonra baska yerlere map edecek, bu tusa gerek kalmayacak fakat durumu anladiniz saniyorum.

Boylece alet cantamizdaki Lisp, Perl'den ayni anda kurtulduk, ayrica hesapsal isler icin Python kullanacagiz - iki tool gitti, yerine uc is yapan tek tool geldi.

Bazi komutlar:

Uzerinde oldugumuz nokta bir blok icinde, bu bloga tekabul eden tum metni istiyoruz,

b = lisp.search_forward("[BITIS]")
e = lisp.search_backward("[BASLA]")
content = lisp.buffer_substring(b, e)


Burada Emacs LISP fonksiyonlarindan ikisini kullanmis olduk.

Herhangi bir noktada *Messages* icinde ve Emacs alt boslugunda gozukebilecek bir metin basmak icin

lisp.message("mesaj")

Icinde oldugumuz Emacs buffer'in ismi

lisp.buffer_name()

Icinde oldugumuz dosyanin ismi

lisp.buffer_file_name()

Diyelim ki oldugumuz noktaya bir suru islemden sonra donmek istiyoruz

remember_where = lisp.point()
...

lisp.goto_char(remember_where)

Friday, April 3, 2009

The Case for Emacs

Harika bir yazi.

Wednesday, April 1, 2009

Yorum Mimarisi

Bir site dusunelim; insanlar herkes tarafindan okunabilecek sorular soruyorlar, o sorularin altinda cevaplar oluyor. Ana sorular bir anahtar-deger tabanindaki bir listede depolanacak demek ki... bu baglamda ilk aklimiza gelen cozum, "sorular" adinda bir anahtar yaratarak herkesin bu anahtar altindaki listeyi alarak, ona yeni "soru objelerini" eklemesidir. Son sorulari gormek isteyen ayni sekilde bu bilinen isimden objeye erisir. Bir anahtar-deger tabaninda "sorular" anahtari tek bir taban bolumune (database shard) yani makinaya gider.

Fakat bu durumda verinin yatay bolunme fikri ihlal edilmis olur. Pek cok app server ayni makinaya hucum eder, cakismalar baslar, yavaslik basgosterir.

Cozumumuzu iyilestirmek mumkun mu?

Highscalability.com sitesindeki bir yazidaki fikirlerden hareket edelim: Cok guzel bir ornek paylasilmis; bu ornek "bolunmus sayac (sharded counter)" ornegidir. Sistemin bir toplam sayisini global bir sayac uzerinden idare etmesi gerekmektedir, burada ilk akla gelen "sayac" adinda bir anahtari herkesin guncellemeye ugrasmasidir. Cok kullanicili bir ortamda bu yapi, tek makinadaki tek objeye dogru saldiran baglanicilarin varligidir ve bunu sonucu kitlenme olusacaktir.

Cozum ilginc: Bir degil, pek cok sayac yarat. Sayac1, sayac2, sayac3 gibi.. Bu sayaclar ayri objeler, ve buyuk bir ihtimal ayri taban bolumleri / makinalar uzerinde gideceklerdir, o zaman sayaci arttirmak isteyen herhangi bir kullanici "rasgele" bir sekilde bu sayaclardan birini secer ve degerini arttirir. Genel toplam alinmak istediginde ne olur? O zaman okuyucu tum sayaclari okur, tum sayaclardan gelen sayilari birbirine toplar, ve global toplam elde edilmis olur!

Bu sayede hem guncelleme islemi dagitik hale gelir, hala dogru toplam elde edilir, hem de okuma islemi daha ucuz bir operasyon oldugu icin bir sey kaybedilmis olmaz.

Yazinin dagitik anahtar-deger tabanlariyla sistem tasarlayanlara tavsiyeleri soyle ozetlenebilir: 1) mimarinizi yazimlari olcekleyecek sekilde hazirlayin 2) yazimlardaki cakismalari azaltacak sekilde tasarlayin 3) yazimlari paralelize edebildigimiz kadar paralellestirin 4) Okumanin ucuz oldugunu unutmayin.

Simdi bu fikri yorum altayapisina uygulayalim:

Son yorumlar listesi bir degil pek cok olacak. Tabii ki bu pek cok listelerin anahtarlari sistem tarafindan "onceden bilinen (well-known)" isimler olacak. Yeni bir soru sormak isteyen app server, rasgele sekilde bu anahtarlar arasindan birini sececek, o listeye erisecek ve eklemeyi ona yapacak.

Kullanici "son sorulari" gormek istediginde ne yapacak? Tum listeleri alacak, listeyi birlestirecek, uzerinde siralama (sort) yapacak, ve sayfa sayfa bu final listeyi kullaniciya sunacak.

Yazimlar dagitilmis olacak. Tek kaynaga dogru yarisma kavrami ortadan kaybolacak.

Voldemort forumunda ilgili bazi yorumlar: