Apache Zookeeper Kurulumu
Merhaba arkadaşlar, yine uzun bir aradan sonra yazı yazma fırsatı bulmanın verdiği mutlulukla, girizgahta fazla vakit kaybetmeden, Apache Zookeeper Kurulumu yazısına geçiyoruz.
Bu yazıda Apache Zookeper’ a (tecrübe ve dilimiz döndüğünce) değinecek, sonrasında Zookeeper kurulumu ve Zookeeper cluster kurulumu yapıp Zookeeper’ ın konfigürasyon ve yönetimiyle alakalı temel bazı noktalara değinerek yazıyı sonlandıracağız.
Zookeeper Nedir?
Zookeeper, dağıtık yapıda olan servislerin koordine edilmesi için geliştirilmiş -kendisi de dağıtık yapıda çalışan- bir uygulamadır. Yaygın olarak kullanılan ve Zookeeper’ ın sitesinde uygulama örnekleri bulunan bazı servisler için aşağıdaki listeye göz atabiliriz. Tabi ki Zookeeper’ ın kullanım alanları bunlarla sınırlamak doğru olmaz.
- İki aşamalı commit, Two-phase commit protocol (2PC); Tek bir veritabanı üzerinde yapılan transaction işleminin birden çok kaynak üzerinde yapılmasına olanak sağlayan bir özellik/standart.
- Locks / Shared Locks; Bir nesneyi kullanıma tamamen kapatmak olarak tanımlayabileceğimiz lock özelliğine, veritabanlarının satır seviyesinde kilitleme (row level lock) örnek olarak verilebilir. Shared lock içinse; sadece okuma veya sadece yazma kilidi gibi örnekler verilebilir.
- Queues; Aslında kilit ve izleme (lock ve watch) implementasyonları içeren birçok yazılımda olduğu gibi Zookeeper üzerinde de mesaj kuyruğu oluşturmak mümkün.
- Barriers / Double Barriers; Kilit özelliğinin aksine bariyer (barrier) kullanımında, adından da anlaşılacağı üzere, hiç bir işlemin yapılmamasını için engel konulmasıdır. Yani kilit özelliğinde aynı anda bir işlem ya da istemci (client) çalışabiliyorken, bariyer kullanıldığında tüm işlem veya istemciler bekletiliyor.
- Lider seçimi, Leader Election; Günümüz uygulamalarında halen tercih edilmekle birlikte artık yetersiz kalan master-slave yapısının yerine master-free yapı kurulmasını sağlayan, otomatik lider (master) seçimine imkan veren bir özelliktir. Bu sayede hem sisteminizin tek bir noktaya bağımlılığı (SPOF, single point of failure) ortadan kalkıyor hem de, lider (master) değişimi gibi bir zaman kaybı (down time) ve operasyona ihtiyaç duyulmamış oluyor.
- Konfigürasyon yönetimi; Özellikle Apache Solr’ ın da kullandığı bir yöntem olan bu pratik, dağıtık yapıda çalışan servislerinizin konfigürasyonlarını tek bir noktadan ve çok hızlı şekilde yönetmenizi sağlıyor.
Zookeeper Kurulumu
Zookeeper ve Solr’ ı çoğunlukla JDK ile çalıştırmayı tercih ettiğimizden JDK ve Zookeeper dosyalarını (bu yazıda kurulumla alakalı yönlendirmelerde yardımcı olacağından zookeepers adlı bir dizine) indirelim. Sunucu üzerinde gui yoksa ve Oracle JDK dağıtımını kullanacaksanız Download JDK on Linux linki faydalı olabilir. Ayrıca Zookeeper’ a özel bir JVM/JDK kullanacağınıza dair parametre göndermezseniz otomatik olarak sistemde kurulu olan JVM’i algılayacaktır. Bu konuya Apache Solr ve Tomcat Kurulumu yazısında değindiğimizden çok fazla üzerinde durmuyoruz.
Aşağıda Mac OS için kısaca indirme aşamaları bulunuyor. Çok üzerinde durmuyoruz çünkü isterseniz siteden tarayıcı aracılığıyla ya da dilediğiniz şekilde indirip edinebilirsiniz.
# zookepers klasoru olustur mkdir zookeepers # zookeepers klasorune gir (calisilan calisma dizinini degistir) cd zookeepers # JDK'yi indir wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u51-b16/jre-8u51-macosx-x64.tar.gz # Zookeeper'i indir wget http://www.eu.apache.org/dist/zookeeper/zookeeper-3.4.6/zookeeper-3.4.6.tar.gz # jdk'yi arsivden cikar tar xvzf jre-8u51-macosx-x64.tar.gz # zookeeper' i arsivden cikar tar xvzf zookeeper-3.4.6.tar.gz
Bu işlemler sonrasında klasörümüz şu şekilde olmalı
-rw-r--r-- 56217343 jre-8u51-macosx-x64.tar.gz drwxr-xr-x 102 jre1.8.0_51.jre drwxr-xr-x 748 zookeeper-3.4.6 -rw-r--r-- 17699306 zookeeper-3.4.6.tar.gz
Tek bilgisayarda 3 farklı Zookeeper kopyasını aynı anda çalıştırmak istediğimizden Zookeper klasöründen 3 kopya oluşturacağız. Bunu sadece test amaçlı kullanmayı öneriyoruz. Gerçek (production) ortamda 3 ayrı sunucu üzerine kurmaya alternatif olarak tek bir sunucuya böyle bir kurulumu önermiyoruz. Zookeeper için tek bir sunucu kaynağımız varsa şu amaçlarla aynı sunucuya kurmak yerinde olabilir; Sektörün acı gerçekleri gereği Zookeeper üzerinde gerçek ortamda konfigürasyon denemeleri, Zookeeper jre’inde parametere denemeleri, Zookeper servisinin bir şekilde durma ihtimali vb.
# zookeeper birinci kopyamiz cp -r zookeeper-3.4.6 zookeeper1 # zookeeper ikinci kopyamiz cp -r zookeeper-3.4.6 zookeeper2 # zookeeper ucuncu kopyamiz cp -r zookeeper-3.4.6 zookeeper3
Son haliyle Zookeepers klasörümüz:
-rw-r--r-- 56217343 jre-8u51-macosx-x64.tar.gz drwxr-xr-x 102 jre1.8.0_51.jre drwxr-xr-x 748 zookeeper-3.4.6 -rw-r--r-- 17699306 zookeeper-3.4.6.tar.gz drwxr-xr-x 748 zookeeper1 drwxr-xr-x 748 zookeeper2 drwxr-xr-x 748 zookeeper3
Bu elle (manuel) indirme kurma yönteminin en büyük dezavantajı sistem yeniden başlatıldığında hiçbir servisin otomatik olarak başlamayacağıdır.
Zookeeper Konfigürasyonu
Zookeeper’i indirdikten sonra artık konfigürasyon kısmına geçebiliriz. Tek bir kopya çalıştırmadan direkt kümeleme (clustering) olarak konfigüre edip çalıştıracağız.
Öncelikle (yine tek sunucu üzerinde üç kopya çalıştırmamız nedeniyle) data dizinini ayrı bir klasöre yönlendireceğiz ki üç Zookeeper da varsayılan kurulumla gelen /tmp/zookeper dizini kullanmasın. Bunun için Zookeeper klasörleri altında data klasörü oluşturuyoruz.
mkdir zookeeper1/data mkdir zookeeper2/data mkdir zookeeper3/data
Sonraki adımda ise sunuculara idlerini veriyoruz.Tüm sunuculara (Zookeeper’ı ayrı ayrı sunucular üzerine kurmuş olsak bile) 1 nolu id vermemeye dikkat edin.
echo "1" > zookeeper1/data/myid echo "2" > zookeeper2/data/myid echo "3" > zookeeper3/data/myid
Bu adımda ise Zookeper ile gelen varsayılan konfigürasyon dosyasını (Zookeeper tarafından okunabilmesi için zoo.cfg adıyla) kopyalıyoruz.
cp zookeeper1/conf/zoo_sample.cfg zookeeper1/conf/zoo.cfg cp zookeeper2/conf/zoo_sample.cfg zookeeper2/conf/zoo.cfg cp zookeeper3/conf/zoo_sample.cfg zookeeper3/conf/zoo.cfg
zookeeper1 için zoo.conf dosyasınya yapılması/eklenmesi gereken ek konfigürasyonlar:
clientPort=2171 dataDir=/Users/mustafakirimli/Desktop/zookeepers/zookeeper1/data/ server.1=localhost:3070:4070 server.2=localhost:3071:4071 server.3=localhost:3072:4072
server2 için zoo.conf dosyasınya yapılması/eklenmesi gereken ek konfigürasyonlar:
clientPort=2172 dataDir=/Users/mustafakirimli/Desktop/zookeepers/zookeeper2/data/ server.1=localhost:3070:4070 server.2=localhost:3071:4071 server.3=localhost:3072:4072
server3 için zoo.conf dosyasınya yapılması/eklenmesi gereken ek konfigürasyonlar:
clientPort=2173 dataDir=/Users/mustafakirimli/Desktop/zookeepers/zookeeper3/data/ server.1=localhost:3070:4070 server.2=localhost:3071:4071 server.3=localhost:3072:4072
Eğer ayrı ayrı sunuculara kurulum yapacaksak yukarıdaki gibi ayrı portlar kullanmak yerine tüm sunuculara aynı direktifleri verebiliriz. Yani tüm sunucularda Zookeper erişim portu 2171, Zookeeper slave (takipçi) portu 3070 ve Zookeeper seçim (election) portu 4070 olabilir. Buradaki slave yapısı klasik master-slave’ den biraz farklı çalışmakta. Bir lider (leader) bulunmakta ve herhangi bir Zookeeper sunucusuna gelen istekler senkron olarak diğer sunuculara iletilmektedir.
Sonraki yazı konularından biri olan Solr Cloud Kurulumu’ nda da göreceğimiz gibi, Zookeeper’ ın kendi lideri dışında özellikle Solr sharding kullanırken bağımsız seçimler (election) yapıp bir sunucu içinde farklı liderler de ayarlandığını göreceğiz. Bu konuyu açma nedenimiz Zookeeper’ ın kümeleme (clustering) için kullandığı lider seçimi implementasyonu uygulamalarımız tarafından da implemente edilebilir ve Zookeeper’ ın liderinden bağımsız hareket edebilir.
Zookeeper’ı Ayrı JVM/JRE ile Çalıştırma (opsyionel)
Daha önce de değindiğimiz bir konu olan java uygulamalarını sistem varsayılanı haricinde bir jre ile çalıştırmak istiyorsak bunu Zookeeper’ a basit bir konfigürasyon ile belirtebiliriz. Yine buradaki java.env dosyası normal kurulumda bulunmaz, biz elle eklediğimizde Zookeeper JVM konfigürasyonu olarak bu dosyayı okur.
echo "JAVA_HOME=/Users/mustafakirimli/Desktop/zookeepers/jre1.8.0_51.jre/Contents/Home/" > zookeeper1/conf/java.env echo "JAVA_HOME=/Users/mustafakirimli/Desktop/zookeepers/jre1.8.0_51.jre/Contents/Home/" > zookeeper2/conf/java.env echo "JAVA_HOME=/Users/mustafakirimli/Desktop/zookeepers/jre1.8.0_51.jre/Contents/Home/" > zookeeper3/conf/java.env
Zookeeper Log Konfigürasyonu (opsiyonel)
Daha önce Zookeeper kullandıysanız sunucunun hemen her yerinde zookeeper.out log dosyası görebilirsiniz. Bunun nedeni ZOOKEEPER_HOME/bin/zkEnv.sh dosyasının eğer aksi belirtilmediyse logları şu an çalışılan klasöre (cwd, current working directory) yönlendirmesidir. Örneğin Zookeeper servisini başlatırken /var klasöründe iseniz zookeeper.out dosyaları burada (/var/zookeeper.out olarak) oluşur. Bir sonraki başlatma işleminizde / dizininde iseniz burada (/zookeeper.out olarak) oluşur vs. derken karmaşık hale gelebilir.
Kendi içinde halletmesi yerine bir kaç satır konfigürasyon yaparak yönlendirmeyi istediğimiz klasöre yapabiliyor oluruz.
# opsiyonel olarak zookeeper.out loglarini istediginiz klasore yonlendirebilirsiniz # oncelikle log klasorlerini olusturalim sudo mkdir /var/log/zookeeper1 sudo mkdir /var/log/zookeeper2 sudo mkdir /var/log/zookeeper3 # Zookeeper servisini hangi kullanici ile başlayacaksak o kullaniciya klasor sahipligini verelim sudo chown mustafakirimli:staff /var/log/zookeeper* # Ve Zookeeper' a loglari yonlendirecegi yeri soylemesi icin zookeeper-env.sh dosyasina konfigurasyon girelim # not: bu dosya standart kurulumda bulunmaz, biz elle eklersek Zookeeper kontrol edecek, yoksa pass gececektir echo "ZOO_LOG_DIR=/var/log/zookeeper1" > zookeeper1/conf/zookeeper-env.sh echo "ZOO_LOG_DIR=/var/log/zookeeper2" > zookeeper2/conf/zookeeper-env.sh echo "ZOO_LOG_DIR=/var/log/zookeeper3" > zookeeper3/conf/zookeeper-env.sh
Zookeepe’ı Çalıştırma
Kurulum ve konfigürasyon aşamaları bittiğine göre artık Zookeeper servislerimizi çalıştırabiliriz. Herhangi bir sırayla aşağıdaki komutları çalıştırdığımızda Zookeeper servisleri başlamış olacaktır.
./zookeeper1/bin/zkServer.sh start ./zookeeper2/bin/zkServer.sh start ./zookeeper3/bin/zkServer.sh start
Durdurmak için de yine aynı komuta stop parametresini göndermek yeterli olacaktır.
./zookeeper1/bin/zkServer.sh stop ./zookeeper2/bin/zkServer.sh stop ./zookeeper3/bin/zkServer.sh stop
Zookeeper’ı İzleme (Monitoring)
Zookeeper servisinin çalışıp çalışmadığını ve şu an hangi modda olduğunu öğrenmek için sunucu üzerinden zkServer.sh dosyasını veya sunucu dışından netcat (nc) komutunu kullanabilirsinizi.
./zookeeper1/bin/zkServer.sh status
JMX enabled by default Using config: /Users/mustafakirimli/Desktop/zookeepers/zookeeper1/bin/../conf/zoo.cfg Mode: follower
echo stats | nc localhost 2171
Clients: /0:0:0:0:0:0:0:1:61147[0](queued=0,recved=1,sent=0) Latency min/avg/max: 0/0/0 Received: 3 Sent: 2 Connections: 1 Outstanding: 0 Zxid: 0x300000001 Mode: follower Node count: 5
Bunların dışında netcat (nc) ile gönderebileceğiniz 4 harf komutlarını Zookeper’ın sitesinde yer alan The Four Letter Words bölümünden inceleyebilirsiniz.
Zookeeper Konsolunu Kullanmak
Zookeeper’ın konsol arabirimine erişmek için (cli) aşağıdaki komutu kullanabilirsiniz. Konsola giriş yaptıktan sonra burada Zookeeper üzerinde depolanan verileri kolaylıkla görebilirsiniz. Zookeeper verileri kolay anlaşılabilmesi için hiyerarşik yapıda (dosya/klasör standartında) depoluyor. Örneğin konsola iken “ls /” komutu ile Zookeper’in root dizininde yer alan dosya ve klasörleri listeleyebilirsiniz. Create ile klasor (node) oluşturabilir, set ile klasore veri yazabilirsiniz.
Kafa karıştırmaması gereken nokta her klasor (node) hem veri hem de alt klasor (node) barındırabiliyor. get komutu ile klasor (node) verisini okurken, ls komutu ile alt klasorleri (node) listeleyebilirsiniz.
./zookeeper1/bin/zkCli.sh -server localhost:2171 [zk: localhost:2171(CONNECTED) 14] ls / [zookeeper] [zk: localhost:2171(CONNECTED) 15] create /servers Sunucular Created /servers [zk: localhost:2171(CONNECTED) 16] create /servers/asia Asya Created /servers/asia [zk: localhost:2171(CONNECTED) 17] create /servers/europe Avrupa Created /servers/europe [zk: localhost:2171(CONNECTED) 18] ls / [servers, zookeeper] [zk: localhost:2171(CONNECTED) 19] ls /servers [europe, asia] [zk: localhost:2171(CONNECTED) 20] ls /servers/europe [] [zk: localhost:2171(CONNECTED) 21] ls /servers/asia [] [zk: localhost:2171(CONNECTED) 22] get /servers Sunucular cZxid = 0x30000001f ctime = Sat Aug 08 14:38:07 EEST 2015 mZxid = 0x30000001f mtime = Sat Aug 08 14:38:07 EEST 2015 pZxid = 0x300000021 cversion = 2 dataVersion = 0 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 9 numChildren = 2 [zk: localhost:2171(CONNECTED) 23] get /servers/asia Asya cZxid = 0x300000020 ctime = Sat Aug 08 14:38:18 EEST 2015 mZxid = 0x300000020 mtime = Sat Aug 08 14:38:18 EEST 2015 pZxid = 0x300000020 cversion = 0 dataVersion = 0 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 4 numChildren = 0
Zookeeper’ ın N/2+1 Limiti
Zookeeper’ ı birden çok sunucu üzerine küme (cluster) olarak kurup çalışmak için bazı kısıtlamalar veya dikkat etmeniz gereken noktalar mevcut. Kümelemeyi salt çoğunluk yöntemi (quorum based) ile yönetmesinden dolayı, n/2+1 sunucu yeter sayısına ulaşmadığında seçim yapamamakta ve yanıt (hizmet) verememektedir. Bu sebepledir ki Zookeeper hizmeti kurulu makina sayısının yarısı çalışır durumda olmalıdır. Örneğin 5 sunucu üzerinde Zookeeper kurulu ise bu sunuculardan birinci ve ikinci sunucu durduğunda Zookeeper hizmeti çalışmaya devam eder, ancak üçüncü sunucu da durduğunda yani çalışan sunucu sayısı iki olursa Zookeeper hizmeti duracaktır.
Bu örnekle formülü aslında AŞAĞI_YUVARLA(n/2)+1 olarak yazmamızın daha doğru olacağını belirtmek gerekir. Türkçe olunca anlama güçlüğü çeken meslektaşlarımız için İngilizce halini de şöylece yazıyor olalım; ROUND(n/2)+1