<?xml version="1.0"?>
<rss version="2.0" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:yt="http://gdata.youtube.com/schemas/2007" xmlns:atom="http://www.w3.org/2005/Atom">
   <channel>
      <title>MetGlobal BlogRoll</title>
      <description>Pipes Output</description>
      <link>http://pipes.yahoo.com/pipes/pipe.info?_id=9c6e817418d50db1e040acabade5823c</link>
      <atom:link rel="next" href="http://pipes.yahoo.com/pipes/pipe.run?_id=9c6e817418d50db1e040acabade5823c&amp;_render=rss&amp;page=2"/>
      <pubDate>Thu, 01 Oct 2015 18:14:53 +0000</pubDate>
      <generator>http://pipes.yahoo.com/pipes/</generator>
      <item>
         <title>Apache Zookeeper Kurulumu</title>
         <link>http://blog.mustafakirimli.com/apache-zookeeper-kurulumu/1731</link>
         <description>Merhaba arkadaşlar, yine uzun bir</description>
         <guid isPermaLink="false">http://blog.mustafakirimli.com/?p=1731</guid>
         <pubDate>Sat, 08 Aug 2015 13:24:17 +0000</pubDate>
         <content:encoded><![CDATA[<p style="text-align:justify;">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.</p><p><span id="more-1731"></span></p><p style="text-align:justify;">Bu yazıda Apache Zookeper&#8217; a (tecrübe ve dilimiz döndüğünce) değinecek, sonrasında Zookeeper kurulumu ve Zookeeper cluster kurulumu yapıp Zookeeper&#8217; ın konfigürasyon ve yönetimiyle alakalı temel bazı noktalara değinerek yazıyı sonlandıracağız.</p><h2>Zookeeper Nedir?</h2><p style="text-align:justify;">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&#8217; ın sitesinde uygulama örnekleri bulunan bazı servisler için aşağıdaki listeye göz atabiliriz. Tabi ki Zookeeper&#8217; ın kullanım alanları bunlarla sınırlamak doğru olmaz.</p><ul><li style="text-align:justify;"><strong>İki aşamalı commit, <a rel="nofollow" title="Two-phase Commit Protocol" target="_blank" href="https://en.wikipedia.org/wiki/Two-phase_commit_protocol">Two-phase commit protocol</a> (2PC</strong>); Tek bir veritabanı üzerinde yapılan transaction işleminin birden çok kaynak üzerinde yapılmasına olanak sağlayan bir özellik/standart.</li><li style="text-align:justify;"><strong>Locks / Shared Locks</strong>; 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.</li><li style="text-align:justify;"><strong>Queues</strong>; 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.</li><li style="text-align:justify;"><strong>Barriers / Double Barriers</strong>; 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.</li><li style="text-align:justify;"><strong>Lider seçimi, <a rel="nofollow" title="Leader Election" target="_blank" href="https://en.wikipedia.org/wiki/Leader_election">Leader Election</a></strong>; 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, <a rel="nofollow" title="Single point of failure" target="_blank" href="https://en.wikipedia.org/wiki/Single_point_of_failure">single point of failure</a>) ortadan kalkıyor hem de, lider (master) değişimi gibi bir zaman kaybı (down time) ve operasyona ihtiyaç duyulmamış oluyor.</li><li style="text-align:justify;"><strong>Konfigürasyon yönetimi</strong>; Özellikle Apache Solr&#8217; ı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.</li></ul><h2>Zookeeper Kurulumu</h2><p>Zookeeper ve Solr&#8217; ı ç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 <a rel="nofollow" title="Download JDK on Linux" target="_blank" href="http://stackoverflow.com/questions/10268583/how-to-automate-download-and-installation-of-java-jdk-on-linux">Download JDK on Linux</a> linki faydalı olabilir. Ayrıca Zookeeper&#8217; a özel bir JVM/JDK kullanacağınıza dair parametre göndermezseniz otomatik olarak sistemde kurulu olan JVM&#8217;i algılayacaktır. Bu konuya <a rel="nofollow" title="Apache Solr ve Tomcat Kurulumu" target="_blank" href="http://blog.mustafakirimli.com/apache-solr-ve-tomcat-kurulumu/1689">Apache Solr ve Tomcat Kurulumu</a> yazısında değindiğimizden çok fazla üzerinde durmuyoruz.</p><p>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.</p><pre class="brush:shell"># 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</pre><p>Bu işlemler sonrasında klasörümüz şu şekilde olmalı</p><pre class="brush:shell">-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</pre><p>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&#8217;inde parametere denemeleri, Zookeper servisinin bir şekilde durma ihtimali vb.</p><pre class="brush:shell"># 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</pre><p>Son haliyle Zookeepers klasörümüz:</p><pre class="brush:shell">-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</pre><p>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.</p><h2>Zookeeper Konfigürasyonu</h2><p>Zookeeper&#8217;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.</p><p>Ö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.</p><pre class="brush:shell">mkdir zookeeper1/data
mkdir zookeeper2/data
mkdir zookeeper3/data</pre><p>Sonraki adımda ise sunuculara idlerini veriyoruz.Tüm sunuculara (Zookeeper&#8217;ı ayrı ayrı sunucular üzerine kurmuş olsak bile) 1 nolu id vermemeye dikkat edin.</p><pre class="brush:shell">echo "1" &gt; zookeeper1/data/myid
echo "2" &gt; zookeeper2/data/myid
echo "3" &gt; zookeeper3/data/myid</pre><p>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.</p><pre class="brush:shell">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</pre><p><strong>zookeeper1 için zoo.conf dosyasınya yapılması/eklenmesi gereken ek konfigürasyonlar:</strong></p><pre class="brush:shell">clientPort=2171
dataDir=/Users/mustafakirimli/Desktop/zookeepers/zookeeper1/data/
server.1=localhost:3070:4070
server.2=localhost:3071:4071
server.3=localhost:3072:4072</pre><p><strong>server2 için zoo.conf dosyasınya yapılması/eklenmesi gereken ek konfigürasyonlar:</strong></p><pre class="brush:shell">clientPort=2172
dataDir=/Users/mustafakirimli/Desktop/zookeepers/zookeeper2/data/
server.1=localhost:3070:4070
server.2=localhost:3071:4071
server.3=localhost:3072:4072</pre><p><strong>server3 için zoo.conf dosyasınya yapılması/eklenmesi gereken ek konfigürasyonlar:</strong></p><pre class="brush:shell">clientPort=2173
dataDir=/Users/mustafakirimli/Desktop/zookeepers/zookeeper3/data/
server.1=localhost:3070:4070
server.2=localhost:3071:4071
server.3=localhost:3072:4072</pre><p>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&#8217; den biraz farklı çalışmakta. Bir lider (leader) bulunmakta ve herhangi bir Zookeeper sunucusuna gelen istekler senkron olarak diğer sunuculara iletilmektedir.</p><p>Sonraki yazı konularından biri olan Solr Cloud Kurulumu&#8217; nda da göreceğimiz gibi, Zookeeper&#8217; ı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&#8217; ın kümeleme (clustering) için kullandığı lider seçimi implementasyonu uygulamalarımız tarafından da implemente edilebilir ve Zookeeper&#8217; ın liderinden bağımsız hareket edebilir.</p><h2>Zookeeper&#8217;ı Ayrı JVM/JRE ile Çalıştırma (opsyionel)</h2><p>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&#8217; 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.</p><pre class="brush:shell">echo "JAVA_HOME=/Users/mustafakirimli/Desktop/zookeepers/jre1.8.0_51.jre/Contents/Home/" &gt; zookeeper1/conf/java.env
echo "JAVA_HOME=/Users/mustafakirimli/Desktop/zookeepers/jre1.8.0_51.jre/Contents/Home/" &gt; zookeeper2/conf/java.env
echo "JAVA_HOME=/Users/mustafakirimli/Desktop/zookeepers/jre1.8.0_51.jre/Contents/Home/" &gt; zookeeper3/conf/java.env</pre><h2>Zookeeper Log Konfigürasyonu (opsiyonel)</h2><p>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.</p><p><span style="text-decoration:underline;">Kendi içinde halletmesi</span> yerine bir kaç satır konfigürasyon yaparak yönlendirmeyi istediğimiz klasöre yapabiliyor oluruz.</p><pre class="brush:shell"># 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" &gt; zookeeper1/conf/zookeeper-env.sh
echo "ZOO_LOG_DIR=/var/log/zookeeper2" &gt; zookeeper2/conf/zookeeper-env.sh
echo "ZOO_LOG_DIR=/var/log/zookeeper3" &gt; zookeeper3/conf/zookeeper-env.sh</pre><h2>Zookeepe&#8217;ı Çalıştırma</h2><p>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.</p><pre class="brush:shell">./zookeeper1/bin/zkServer.sh start
./zookeeper2/bin/zkServer.sh start
./zookeeper3/bin/zkServer.sh start</pre><p>Durdurmak için de yine aynı komuta stop parametresini göndermek yeterli olacaktır.</p><pre class="brush:shell">./zookeeper1/bin/zkServer.sh stop
./zookeeper2/bin/zkServer.sh stop
./zookeeper3/bin/zkServer.sh stop</pre><h2>Zookeeper&#8217;ı İzleme (Monitoring)</h2><p>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.</p><pre class="brush:shell">./zookeeper1/bin/zkServer.sh status</pre><pre class="brush:plain">JMX enabled by default
Using config: /Users/mustafakirimli/Desktop/zookeepers/zookeeper1/bin/../conf/zoo.cfg
Mode: follower</pre><pre class="brush:shell">echo stats | nc localhost 2171</pre><pre class="brush:plain">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</pre><p>Bunların dışında netcat (nc) ile gönderebileceğiniz 4 harf komutlarını Zookeper&#8217;ın sitesinde yer alan <a rel="nofollow" title="The Four Letter Words" target="_blank" href="http://zookeeper.apache.org/doc/r3.1.2/zookeeperAdmin.html#sc_zkCommands">The Four Letter Words</a> bölümünden inceleyebilirsiniz.</p><h2>Zookeeper Konsolunu Kullanmak</h2><p>Zookeeper&#8217;ı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 &#8220;ls /&#8221; komutu ile Zookeper&#8217;in root dizininde yer alan dosya ve klasörleri listeleyebilirsiniz. Create ile klasor (node) oluşturabilir, set ile klasore veri yazabilirsiniz.</p><p>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.</p><pre>./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</pre><h2>Zookeeper&#8217; ın N/2+1 Limiti</h2><p style="text-align:justify;">Zookeeper&#8217; ı 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.</p><p style="text-align:justify;">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</p><h2 style="text-align:justify;">Kaynak</h2><ul><li><a rel="nofollow" title="Zookeeper" target="_blank" href="http://zookeeper.apache.org/">http://zookeeper.apache.org/</a></li><li><a rel="nofollow" title="Two-phase Commit Protocol" target="_blank" href="https://en.wikipedia.org/wiki/Two-phase_commit_protocol">https://en.wikipedia.org/wiki/Two-phase_commit_protocol</a></li><li><a rel="nofollow" title="Leader Election" target="_blank" href="https://en.wikipedia.org/wiki/Leader_election">https://en.wikipedia.org/wiki/Leader_election</a></li><li><a rel="nofollow" title="Single point of failure" target="_blank" href="https://en.wikipedia.org/wiki/Single_point_of_failure">https://en.wikipedia.org/wiki/Single_point_of_failure</a></li><li><a rel="nofollow" title="How to Automate Installation of Java" target="_blank" href="http://stackoverflow.com/questions/10268583/how-to-automate-download-and-installation-of-java-jdk-on-linux">http://stackoverflow.com/questions/10268583/how-to-automate-download-and-installation-of-java-jdk-on-linux</a></li></ul>]]></content:encoded>
         <category>Genel</category>
      </item>
      <item>
         <title>Apache Solr Replikasyon – Genel Bakış</title>
         <link>http://blog.mustafakirimli.com/apache-solr-replikasyon-genel-bakis/1713</link>
         <description>Merhaba arkadaşlar, bu yazımızda bir</description>
         <guid isPermaLink="false">http://blog.mustafakirimli.com/?p=1713</guid>
         <pubDate>Thu, 03 Apr 2014 14:36:17 +0000</pubDate>
         <content:encoded><![CDATA[<p>Merhaba arkadaşlar, bu yazımızda bir önceki <a rel="nofollow" title="Apache Solr Replikasyon Kurulumu" target="_blank" href="http://blog.mustafakirimli.com/apache-solr-replikasyon-kurulumu/1698">Apache Solr Replikasyon Kurulumu</a> başlıklı yazıda değindiğimiz kurulumları diyagramlarla inceleyeceğiz.</p><p><span id="more-1713"></span></p><p>Apache Solr replikasyon kullanımına dair bu son yazımızda, daha önce incelemeye çalıştığımız başlıkları hem görselleştirerek işleyecek hem de kurulum anlatmak yerine replikasyonu kendi içinde tarştımaya açacağız.</p><h2 class="clear">Master Slave Replikasyon (1-n)</h2><p style="text-align:center;"><a rel="nofollow" target="_blank" href="http://blog.mustafakirimli.com/wp-content/uploads/2014/03/solr-replication-1n-sunucular.png"><img class="aligncenter  wp-image-1720" title="solr-replication-1n-sunucular" src="http://blog.mustafakirimli.com/wp-content/uploads/2014/03/solr-replication-1n-sunucular.png" alt="solr replication 1-n sunucular" width="616" height="336"/></a>Bu kurulumda tüm sunucular master Solr sunucusuna bağlanıyor. Buradaki en büyük sıkıntı slave sunucu sayınız arttıkça master sunucuya gelen trafiğin darboğaz oluşturma ihtimalininde artmasıdır. İllaki bu kurulumu tercih edeceksek slave sunucuları aralık/sıklık (interval) ile değil oluşturduğunuz görev/kuyruklamalarla dakika aralığında senkronize etmeniz olacaktır. Örneğin, verilerin her 10 dakikada bir güncellenmesini istiyorsak ve 10 sunucumuz varsa her bir sunucuyu 1-2-3-..-9-10 dakikalarında güncelleme işlemine tabi tutmamız gerekir. Daha açık bir örnekle, birinci sunucunun saat 8 &#8216;deki senkronizasyon ayarları şu şekilde olmalı; 08:01, 08:11, 08:21, 08:31, 08:41, 08:51 &#8230;  Tabi ki unutulmaması gereken nokta, verilerin tüm sunucularda aynı anda güncellenme zorunluluğu bulunması farklı zamanlarla yapacağınız senkronizasyonlarda sorun çıkaracaktır.</p><p style="text-align:center;"><a rel="nofollow" target="_blank" href="http://blog.mustafakirimli.com/wp-content/uploads/2014/03/solr-replication-1n-dosyalar.png"><img class="aligncenter  wp-image-1719" title="solr-replication-1n-dosyalar" src="http://blog.mustafakirimli.com/wp-content/uploads/2014/03/solr-replication-1n-dosyalar.png" alt="solr replication 1-n dosyalar" width="640" height="329"/></a>Sunucular master sunucudan data çektiği gibi aynı şekilde <strong>solrconfig_slave.xml</strong> dosyasını çekiyor ve <strong>solrconfig.xml</strong> olarak kullanıyor. Replikasyona dahil edilmiş diğer dosyaları da olduğu gibi aktarıyor. Master sunucuda bulunan solrconfig.xml &#8216;i kullanmama nedenimiz o dosya içerisinde master sunucu konfigürasyonu bulunuyor olmasıdır. Gelen <strong>solrconfig_slave.xml</strong> dosyası içerisinde master&#8217;ın hangi sunucu olduğu da yer aldığından, slave sunucu senkronizasyon bilgilerine sahip olmuş oluyor.</p><h2>Tek Repeater İle Replikasyon (1-1-n)</h2><p style="text-align:center;"><a rel="nofollow" target="_blank" href="http://blog.mustafakirimli.com/wp-content/uploads/2014/03/solr-replication-11n-sunucular.png"><img class="aligncenter  wp-image-1717" title="solr-replication-11n-sunucular" src="http://blog.mustafakirimli.com/wp-content/uploads/2014/03/solr-replication-11n-sunucular.png" alt="solr replication 1-1-n sunucular" width="616" height="336"/></a>Bu konfigürasyon bir master sunucu, bir repeater sunucu ve istenilen sayıda slave sunucu (1-1-n) oluşacak şekilde çalışıyor. Bir önceki kuruluma göre (1-n) avantajı master network trafiğini master sunucu üzerinden alıp bu görevi repeater&#8217;a aktarmaktır. Böylece master sunucuyu uygulamadan gelen update vd. işlemleri işlerken darboğaz oluşması gibi sorunlardan uzak tutulmuş oluruz.</p><p style="text-align:center;"><a rel="nofollow" target="_blank" href="http://blog.mustafakirimli.com/wp-content/uploads/2014/03/solr-replication-11n-dosyalar1.png"><img class="aligncenter  wp-image-1718" title="solr-replication-11n-dosyalar" src="http://blog.mustafakirimli.com/wp-content/uploads/2014/03/solr-replication-11n-dosyalar1.png" alt="solr replication 1-1-n dosyalar" width="616" height="316"/></a>Bu kurulumun dosya replikasyonunda ise master sunucudan repeater&#8217;a giden iki solrconfig dosyası bulunuyor. Biri <strong>solrconfig_repeater.xml</strong> dosyası, repeater sunucu bu dosyayı <strong>solrconfig.xml</strong> olarak kullanıyor. İkinci dosya ise <strong>solrconfig_slave.xml</strong>, repeater bu dosyayı alıp aynen saklıyor ve slave sunuculara gönderiyor. Slave sunucular solrconfig_slave.xml dosyasını solrconfig.xml olarak kullanıyor.</p><h2>Çoklu Repeater İle Replikasyon (1-n-n)</h2><p style="text-align:center;"><a rel="nofollow" target="_blank" href="http://blog.mustafakirimli.com/wp-content/uploads/2014/03/solr-replication-1nn-sunucular.png"><img class="wp-image-1714 aligncenter" title="solr-replication-1nn-sunucular" src="http://blog.mustafakirimli.com/wp-content/uploads/2014/03/solr-replication-1nn-sunucular.png" alt="solr replication 1-n-n sunucular" width="616" height="336"/></a>Bu kurulum ise bir master sunucu, istenilen sayıda repeater sunucu ve istenilen sayıda slave sunucudan (1-n-n) oluşuyor. Kurulumun çoklu repeater temelinde yapılmış olması ölçeklendirme konusunda kolaylık sağlayacaktır. Burada lokasyon bazlı, CDN &#8216;e benzer yapıda, repeater kullanımını anlatmaya çalıştık. Tabi ki farklı şemalar çıkarmak mümkün, amacımız sadece çalışma mantığını anlatmaya çalışmak. Bu kurulum (1-n-n) örneğinde de repeater veya slave sayımız artarsa yukarıda bahsettiğimiz gibi farklı zamanlarda senkronizasyon yapabiliriz. Master-slave, replikasyon vd. yöntemleri bir kenara bırakıp ölçeklendirme ile alakalı konuşacak olursak; 10&#8242; lu sunucu sayılarıyla arama motorlarının mimarisini açıklamaya kalkmayacağız ama güncel verilerin arama sonuçlarında farklılık göstermesi, yük dengeleyicinin yönlendirmesine göre sorgunuzun farklı sunucularda işlenmesi nedeniyle, sonuçların değişkenlik göstermesi buna benzer nedenlerdendir.</p><p style="text-align:center;"><a rel="nofollow" target="_blank" href="http://blog.mustafakirimli.com/wp-content/uploads/2014/03/solr-replication-1nn-dosyalar.png"><img class="aligncenter  wp-image-1715" title="solr-replication-1nn-dosyalar" src="http://blog.mustafakirimli.com/wp-content/uploads/2014/03/solr-replication-1nn-dosyalar.png" alt="solr replication 1-n-n dosyalar" width="616" height="329"/></a>Bu kurulumun (1-n-n) konfigürasyon dosyaları replikasyonu ise hemen hemen bir öncekine benzemekte. Ayrıldığı tek nokta tüm konfigürasyonu master sunucu üzerinden yönetirken herhangi bir slave sunucunun hangi repeater sunucuya bağlanacağını belirleme zorunluğumuzdur. Bunun için her repeater sunucu üzerinde <strong>solrcore.properties_slave</strong> dosyası oluşturup repeater seviyesinden sonra bu dosyayı da replikasyona dahil etmemiz gerekir. Slave sunucuya yapılan replikasyon sonrasında bu dosya <strong>solrcore.properties</strong>olarak, solrconfig.xml dosyasında bu şekilde tanımlamıştık, kaydedilecek ve slave sunucu üzerinde bulunan solrconfig.xml dosyası <code>${solr.core.master_url}</code> değişkenini bu dosyadan okuyup hangi repeater sunucuya bağlanacağını anlamış olur.</p><h2>Sonuç</h2><p>Bir önceki yazıda anlattığımız replikasyon ve repeater kullanımına bu yazıda şemalarla yer verip biraz daha netleşmesini amaçladık. Tek başına yük devretme (fail-over), daha gelişmiş merkezi konfigürasyon yönetimi, çoklu master yapısı vd. özellikleri içeren cloud ile yarışamıyor olsa da kısmen cloud&#8217;un da replikasyon kullanıyor olması dolayısıyla incelemiş olduk.</p><h2>Kaynak</h2><p>Yazıdaki şemaları <a rel="nofollow" target="_blank" href="http://www.digikey.com/schemeit">http://www.digikey.com/schemeit</a> aracını kullanarak oluşturduk. Teşekkürü borç biliriz.</p><p>Kullanılan şemaların düzenlemeye açık haline aşağıdaki adreslerden ulaşabilirsiniz. İyi niyetli kullanıcıları tenzih ederek amacı dışında kullanılmamasını rica ediyoruz</p><p><a rel="nofollow" target="_blank" href="http://www.digikey.com/schemeit/#q8h">http://www.digikey.com/schemeit/#q8h</a> (1-n)<br /> <a rel="nofollow" target="_blank" href="http://www.digikey.com/schemeit/#q8g">http://www.digikey.com/schemeit/#q8g</a> (1-1-n)<br /> <a rel="nofollow" target="_blank" href="http://www.digikey.com/schemeit/#q8b">http://www.digikey.com/schemeit/#q8b</a> (1-n-n)</p>]]></content:encoded>
      </item>
      <item>
         <title>Apache Solr Replikasyon Kurulumu</title>
         <link>http://blog.mustafakirimli.com/apache-solr-replikasyon-kurulumu/1698</link>
         <description>Merhaba arkadaşlar, bu yazımızda Apache</description>
         <guid isPermaLink="false">http://blog.mustafakirimli.com/?p=1698</guid>
         <pubDate>Sun, 16 Mar 2014 23:21:14 +0000</pubDate>
         <content:encoded><![CDATA[<p>Merhaba arkadaşlar, bu yazımızda Apache Solr ile replikasyon ve tekrarlayıcı (repeater) kurulumunu inceleyip uygulamaya çalışacağız.</p><p><span id="more-1698"></span></p><p>Bilenleri tenzih ederek replikasyon nedir diye değinecek olursak; Datanın bir kaynaktan diğerine aynen, değiştirmeden ve parçalara ayırmadan, kopyalanması diyebiliriz. Buna, benzer çalışma mantığı olan disk aynalama (disk mirroring) standardı RAID 1&#8242; i  örnek olarak gösterebiliriz. Tabi ki bazı RAID denetçileri parçalı okuma yapabiliyor ama konumuzun bu olmaması ve &#8220;RAID 1&#8242;e benzer&#8221; dememiz nedeniyle daha fazla üzerinde durmuyoruz. Tekrarlayıcıları ise network darboğazı (network bottleneck) oluşmaması için ana (master) sunucuya yardım eden sunucular olarak düşünebiliriz. Solr &#8216;a bulut (cloud) özelliği eklendikten sonra tek başına pek tercih edilmiyor olsa da fikir vermesi açısından ve pratik yapmak için replikasyonu -en azından- denemek yararlı olabilir. Yazının devamında ana sunucuyu master, takipçi sunucuyu slave, tekrarlayıcıyı da repeater olarak adlandıracağız.</p><h2 class="clear">Apache Solr Replikasyonu Nasıl Çalışır?</h2><p>Solr&#8217; ı replikasyon ile kulanırken bir master sunucu ve buna bağlı n tane slave sunucu kurarak çalıştırabiliriz. Slave sunucu sayısının çok olması ve/veya slave sunucuların master sunucuya yaptığı istekler network üzerinde darboğaz oluşturmaması için bazı slave sunucuları repeater olarak kullanabiliriz. Tüm bu iletişimi HTTP üzerinden ve Solr RequestHandler &#8216;larıyla  (RequestHandler konusunu daha sonra işleyeceğiz) yapar.</p><p><a rel="nofollow" target="_blank" href="http://blog.mustafakirimli.com/wp-content/uploads/2014/03/apache-solr-replication-monitor.png"><img class="size-medium wp-image-1703  alignleft border" style="margin-top:6px;margin-bottom:6px;" title="apache-solr-replication-monitor" src="http://blog.mustafakirimli.com/wp-content/uploads/2014/03/apache-solr-replication-monitor-300x136.png" alt="Apache Solr Replikasyon Monit&#xf6;r&#xfc;" width="300" height="136"/></a></p><p>Solr, replikasyon yaparken master sunucudan öncelikle değişiklik listesini alır, daha sonra bu dosyaları geçici (tmp) dizinine indirmeye başlar ve tüm değişiklikler indirilene kadar indexlerde herhangi bir değişiklik yapmayıp sistemin çalışmaya devam etmesini sağlar. Replikasyon işleminin yarıda kesilmesi durumunda slave sunucu üzerinde tek kaybımız güncel verinin henüz uygulanmamış olması olur, bunun dışında gelen isteklere cevap vermeye ve çalışmasına normal olarak devam eder. Replikasyon işlemi kaldığı yerden devam edip indirilme tamamlandığında indexlere değişiklikleri uygular (yandaki resimde örnek replikasyon monitör görüntüsü mevcut).</p><p><a rel="nofollow" target="_blank" href="http://blog.mustafakirimli.com/wp-content/uploads/2014/03/master-slave-replication.png"><img class="alignright size-full wp-image-1704 border" style="margin-top:6px;margin-bottom:6px;" title="master-slave-replication" src="http://blog.mustafakirimli.com/wp-content/uploads/2014/03/master-slave-replication.png" alt="Master/Slave replikasyon" width="159" height="235"/></a>Replikasyon kullanımı bize aynı anda tüm konfigürasyonları tek merkezden yönetme imkanı da sağlamış olur. Master sunucu üzerinde yaptığımız değişiklikler tüm slave sunucular tarafından çekilerek uygulanır. Böylece tüm slave sunucularda tek tek konfigürasyon ayarlamaya çalışmak zorunda kalmayız. Burada isteğimiz dosyaları replikasyona ekleyebilme esnekliği bırakılması güzel bir özellik olarak göze çarpıyor. Ayrıca replikasyon sonrasında (aşağıda bahsedeceğiz) dosyayı salve sunucularda yeniden adlandırabilme (rename) imkanımız da mevcut.</p><p>Burada dikkat edilmesi gereken nokta Solr&#8217; ı master/slave replikasyon yöntemi ile kullanırken okuma dışındaki değişiklik yaratan sorguların (update, delete vd.) tamamının master sunucuya gelmesi gerektiğidir. Slave sunuculara güncelleme sorgusu gelmesi durumunda hiçbir problem çıkmamakla birlikte o değişiklik/ekleme&#8217; nin sadece o sunucuda görüneceği ve replikasyon işlemi yapıldığı anda master sunucudaki kayıtlar dışındaki değişikliklerin kaybolacağını bilmemiz gerekir. Ayrıca slave sunucuya güncelleme yaratan komutlar geldiğinde bir sonraki replikasyon işlemini master&#8217;dan tüm datayı yeniden çekeceği için uzatmış olursunuz.</p><p>Eğer replikasyon ile birlikte konfigürasyon yönetimini de (önerilen budur) aktif ettiyseniz slave sunucuların konfigürasyonunda replikasyona dahil edilmiş bir dosyada değişiklik yaptığınızda replikasyon işlemi sonrasında yaptığınız değişiklikler kaybolup master sunucudaki konfigürasyonlar geçerli olacaktır.</p><h2>Replikasyon Ayarlarımız</h2><table class="myTable1" style="float:right;width:auto !important;margin:3px 0 0 10px;"><tbody><tr><td>localhost</td><td>8081</td><td>8006</td><td>true</td><td>/var/www/solr/replication/master</td></tr><tr><td>localhost</td><td>8082</td><td>8007</td><td>false</td><td>/var/www/solr/replication/slave1</td></tr><tr><td>localhost</td><td>8083</td><td>8008</td><td>false</td><td>/var/www/solr/replication/slave2</td></tr></tbody></table><p title="Apache Solr ve Tomcat Kurulumu">Replikasyon konfigürasyonuna geçmeden neler yapmak istediğimizi çalışırken minimum kağıda veya tahtaya çizdiğimiz gibi tablo halinde listeleyelim. Üç ayrı kurulum yapıp biri master diğer ikisi slave sunucu olacak şekilde aşağıdaki değerleri kullanacağız. Tabloya başlıkları, dizgide takıntılı olmam nedeniyle göze hoş gelmediği gerekçesiyle eklemedim. Başlıklar &#8220;Sunucu Adı, Apache Portu, Apache Shutdown Portu, Master, Dizin Yolu&#8221; oluşuyor. Replikasyona özel ayarlara geçmeden yandaki tabloya göre yaptığımız kurulumların yapılıp (<a rel="nofollow" title="Apache Solr ve Tomcat Kurulumu" target="_blank" href="http://blog.mustafakirimli.com/apache-solr-ve-tomcat-kurulumu/1689">Apache Solr ve Tomcat Kurulumu</a> yazısında olduğu gibi) ayrı ayrı çalıştığına emin olalım. Bunun için http://localhost:8081/solr http://localhost:8082/solr http://localhost:8083/solr adreslerinden Solr paneline erişebiliyor olmamız gerekiyor.</p><p>Eğer farklı sunucularda kurulum yapacaksanız tabi ki portlar aynı olabilir (hatta aynı olması önerilir). Her bir kurulum setine aynı portları verip diğer kurulumlardan ayırabiliriz. Mesela x sitesi için üç ayrı sunucuda 8081, y sitesi için de üç ayrı sunucuda 8082 portlarına kurulum yapmak gibi. Aynı şekilde dizinler de tüm sunucularda aynı yolda bulunması iyi olacaktır.</p><h2>Apache Solr Replikasyon Master Sunucu Ayarları</h2><p>Master (8081) sunucumuzda <strong>solr_home/collection1/conf/solrconfig.xml</strong> dosyasında <code>&lt;requestHandler name="/replication" class="solr.ReplicationHandler" &gt;</code> ile başlayan direktif içinde aşağıdaki değişiklikleri yapalım. Şimdilik sadece master ayarlarının yorumlarını kaldırıp aktifleştirdik.</p><pre class="brush:xml">  &lt;requestHandler name="/replication" &gt;
    &lt;!--
       To enable simple master/slave replication, uncomment one of the 
       sections below, depending on whether this solr instance should be
       the "master" or a "slave".  If this instance is a "slave" you will
       also need to fill in the masterUrl to point to a real machine.
    --&gt;
    &lt;lst name="master"&gt;
        &lt;str name="replicateAfter"&gt;commit&lt;/str&gt;
        &lt;str name="replicateAfter"&gt;startup&lt;/str&gt;
        &lt;str name="confFiles"&gt;schema.xml,stopwords.txt&lt;/str&gt;
    &lt;/lst&gt;
    &lt;!-- 
       &lt;lst name="slave"&gt;
         &lt;str name="masterUrl"&gt;http://your-master-hostname:8983/solr&lt;/str&gt;
         &lt;str name="pollInterval"&gt;00:00:60&lt;/str&gt;
       &lt;/lst&gt;
    --&gt;
  &lt;/requestHandler&gt;</pre><p>Burada <strong>replicateAfter</strong> direktifi hangi durum/olay sonrası verilerin replikasyona dahil edileceğini belirliyor. Alabileceği parametreler startup, commit ve optimize. En efektif olanı <strong>commit</strong> gibi duruyor. Optimize yüksek boyutlu indexlerde çok zaman aldığından replikasyon maliyeti artabilir. Tabi ki çok fazla dosya transfer olmaması gibi artı yanı da var. Bu sebeple duruma göre direktifi ayarlamak gerekiyor. Konfigürasyona verdiğiniz direktifteki ilgili olay gerçekleştiğinde master sunucu üzerinde <strong>replicable</strong> index versiyonu güncellenir ve böylece slave sunucular kendi index versiyonlarından güncel bir veri olduğunu farkedip replikasyon işlemi (bir sonraki başlıkta bulunan direktifler doğrultusunda) yaparlar.</p><h2 class="clear">Apache Solr Replikasyon Slave Sunucu Ayarları</h2><p>Slave sunucularımızda (8082 ve 8083) <strong>solr_home/collection1/conf/solrconfig.xml</strong> dosyasında <code>&lt;requestHandler name="/replication" class="solr.ReplicationHandler" &gt;</code> ile başlayan direktif içinde aşağıdaki değişiklikleri yapalım. Şimdilik sadece slave ayarlarının yorumlarını kaldırıp aktifleştirdik ve master sunucumuzun adresini verdik.</p><pre class="brush:xml">   &lt;requestHandler name="/replication" &gt;
    &lt;!--
       To enable simple master/slave replication, uncomment one of the
       sections below, depending on whether this solr instance should be
       the "master" or a "slave".  If this instance is a "slave" you will
       also need to fill in the masterUrl to point to a real machine.
    --&gt;
    &lt;!--
       &lt;lst name="master"&gt;
         &lt;str name="replicateAfter"&gt;commit&lt;/str&gt;
         &lt;str name="replicateAfter"&gt;startup&lt;/str&gt;
         &lt;str name="confFiles"&gt;schema.xml,stopwords.txt&lt;/str&gt;
       &lt;/lst&gt;
    --&gt;
    &lt;lst name="slave"&gt;
       &lt;str name="masterUrl"&gt;http://localhost:8081/solr/collection1/replication&lt;/str&gt;
       &lt;str name="pollInterval"&gt;00:00:60&lt;/str&gt;
    &lt;/lst&gt;
  &lt;/requestHandler&gt;</pre><p>Tüm direktifleri tek tek işlemeyeceğiz ama <strong>pollInterval</strong> &#8216;in otomatik replikasyon işleminin ne sıklıkla yapılacağını (HH:mm:ss) bildirdiğini ve bu direktifi vermezseniz replikasyonu sadece ilgili komutu (urli) elle tetikleyerek gerçekleştirebileceğimizi bilmekte yarar var. Son olarak <strong>pollInterval</strong> direktifi -interval kelimesinden de anlaşılacağı üzere- zaman değil aralık/sıklık komutu alır. Yani 01:00:00 komutu saat 1&#8242;de değil her saat başı çalış anlamına gelmektedir.<br /> <a rel="nofollow" target="_blank" href="http://blog.mustafakirimli.com/wp-content/uploads/2014/03/apache-solr-replication.png"><img class="alignright  wp-image-1705 border" style="margin-top:6px;margin-bottom:6px;" title="apache-solr-replication" src="http://blog.mustafakirimli.com/wp-content/uploads/2014/03/apache-solr-replication-300x128.png" alt="apache solr replication" width="300" height="128"/></a>Slave sunucularda bu değişikliği yapıp Solr&#8217;ı tekrar başlattığımızda ve http://localhost:8082/solr/#/collection1/replication http://localhost:8083/solr/#/collection1/replication adreslerine girdiğimizde yandaki resimde olduğu gibi replikasyon hakkında bilgi ve bazı komutları görebiliyor olacağız. Burada yer alan bilgiler solrconfig.xml içindeki direktiflerin yanı sıra master sunucudaki direktifleri de yansıtıyor. Master sunucuda replikasyonun aktif olup olmadığı (<strong>Settings Master: replication enable</strong>), master sunucuda hangi konfigürasyon dosyalarının replikasyona dahil olduğu (<strong>Settings Master: confFiles</strong>), master sunucu değişiklikleri hangi durumda replikasyona hazır hale getireceği (<strong>Settings Master: replicateAfter</strong>)</p><p>Bunun yanı sıra master ve slave sunucudaki index replikasyon durumlarını da versiyon numaralarıyla verir.<strong> </strong>Master sunucuda indexin hangi versiyonda olduğu (<strong>Index Master Searching</strong>). Master sunucuda replikasyona dahil edilen (replikasyon yapılabilir veriler) index versiyon numarası (<strong>Index Master Replicable</strong>). Slave sunucudaki index versiyonu, bu bilgi master&#8217;dan son değişiklikler alınırken kullanılıyor (<strong>Index Slave Searching</strong>)</p><p>Bu bölümle alakalı son olarak &#8220;<strong>replicate now</strong>&#8221; butonunun adından da anlaşılacağı üzere &#8220;replikasyonu şu an gerçekleştir&#8221; komutunu verdiğini (http://localhost:8082/solr/collection1/replication?command=fetchindex&amp;wt=json urlini çağırarak) söyleyelim.</p><h2>solrconfig.xml Dosyasını Replikasyona Ekleme</h2><p>Slave sunucularda konfigürasyonları teker teker değiştirmek istemiyorsak (mesela pollInterval değerlerini değiştirmek istiyor olabiliriz) master sunucu üzerinde slave sunucularda kullanılmak üzere <strong>solrconfig_slave.xml</strong> adında dosya oluşturup (slave sunucu için yaptığımız konfigürasyonları içeren dosyanın aynısı olabilir) aşağıdaki direktifleri master sunucu (8081) üzerinde <strong>solr_home/collection1/conf/solrconfig.xml</strong> dosyasına yukarıda master konfigürasyonu kısmında anlattığımız gibi vermemiz yeterli olacaktır.</p><pre class="brush:xml">&lt;str name="confFiles"&gt;schema.xml,stopwords.txt,solrconfig_slave.xml:solrconfig.xml&lt;/str&gt;</pre><div id="attachment_1706" class="wp-caption alignleft" style="width:310px;"><a rel="nofollow" target="_blank" href="http://blog.mustafakirimli.com/wp-content/uploads/2014/03/apache-solr-slave-config-files.png"><img class="size-medium wp-image-1706 border" style="margin-top:6px;margin-bottom:6px;" title="apache-solr-slave-config-files" src="http://blog.mustafakirimli.com/wp-content/uploads/2014/03/apache-solr-slave-config-files-300x132.png" alt="apache solr slave config files" width="300" height="132"/></a><p class="wp-caption-text">Slave sunucu replikasyon monitör görüntüsü</p></div><p>Bu direktif slave makinelerce <strong>solrconfig_slave.xml</strong> dosyasını master sunucudan indir ve <strong>solrconfig.xml</strong> olarak kaydet olarak yorumlanır. Böylelikle slave sunucuların solrconfig.xml dosyasını master sunucudan güncellemiş oluruz. Yandaki resim master sunucudan solrconfig.xml dosyasını alan bir slave sunucunun replikasyon monitörü görüntüsüdür.</p><p>Dosyaların replikasyona dahil edilmesinde şöyle ilginç bir durum olduğunu bilmenizi isterim; dosyaların sunuculara gitmesi için replikasyonu tetikleyen bir işlem oluşması, commit veya optimize gibi, gerekiyor. Diğer bir ifadeyle; konfigürasyon dosyasında yapılan değişiklikler replikasyonu tetiklemiyor.</p><h2 class="clear">Apache Solr Replikasyon Repeator Sunucu Ayarları</h2><p>Yukarıdaki 3 sunucu kurulumuna 10 sunucu daha ekleyip; 1 master, 2 repeater ve her bir repeater&#8217;a bağlı 5&#8242;şer sunucu (1,2,5) oluşturacaksak şu adımları izlememiz gerekir. Kurulum örneğini 13 sunucu üzerinden verme nedenim (1,1,n) kurulum konfigürasyonu ile (1,n,n) konfigürasyonunun çok farklı olması. Mesela 1,1,n kurulumunda repeater sunucusunda da herhangi bir dosya değiştirme zorunluluğunuzun olmaması gibi.</p><p><span style="text-decoration:underline;">Bu kısım hakkında kusura bakmamanızı rica ediyorum, zira ayrı bir yazı başlığı gibi gelmesi ve kısa yoldan anlatamıyor olmam nedeniyle sadece kurulum adımlarını ve gereki konfigürasyonları yazıp bitirmek istiyorum.</span></p><h3><strong>Master sunucu üzerinde yapılacaklar;</strong></h3><p><span style="text-decoration:underline;"><strong>solrconfig.xml:</strong></span></p><pre class="brush:xml">...
&lt;lst name="master"&gt;
  &lt;str name="replicateAfter"&gt;startup,commit&lt;/str&gt;
  &lt;str name="confFiles"&gt;schema.xml,stopwords.txt,solrconfig_repeater.xml:solrconfig.xml,solrconfig_slave.xml&lt;/str&gt;
&lt;/lst&gt;
...</pre><p>Yukarıdaki ayarlar, repeater sunucusu master&#8217;dan replikasyon yaparken solrconfig_repeater.xml dosyasını kendine solrconfig.xml olarak kopyalacak ve içerisinde de master url&#8217;i olmasından dolayı master&#8217;a otomatik olarak bağlanacak (bir önceki başlıkta işlediğimiz gibi). Repeater sunucusu solrconfig_slave.xml dosyasını olduğu gibi alıp bir işlem yapmayacak.</p><p><span style="text-decoration:underline;"><strong>solrconfig_repeater.xml:</strong></span></p><pre class="brush:xml">...
&lt;lst name="master"&gt;
  &lt;str name="replicateAfter"&gt;commit&lt;/str&gt;
  &lt;str name="confFiles"&gt;schema.xml,stopwords.txt,elevate.xml,solrconfig_slave.xml:solrconfig.xml,solrcore.properties_slave:solrcore.properties&lt;/str&gt;
  &lt;str name="commitReserveDuration"&gt;00:00:10&lt;/str&gt;
&lt;/lst&gt;
&lt;lst name="slave"&gt;
  &lt;str name="masterUrl"&gt;http://localhost:8081/solr/collection1/replication&lt;/str&gt;
  &lt;str name="pollInterval"&gt;00:10:00&lt;/str&gt;
&lt;/lst&gt;
...</pre><p>Yukarıdaki ayarlar repeater sunucusunda solrconfig.xml dosyası olarak görünecek ve herhangi bir slave sunucu repeater&#8217;a replikasyon için bağlandığında <strong>solrconfig_slave.xml</strong> dosyasını kendine <strong>solrconfig.xml</strong> dosyası olarak kaydedecek. Ayrıca <strong>solrcore.properties_slave</strong> dosyasını da <strong>solrcore.properties</strong> olarak kaydedecek.</p><p><span style="text-decoration:underline;"><strong>solrconfig_slave.xml:</strong></span></p><pre class="brush:xml">...
&lt;lst name="slave"&gt;
  &lt;str name="masterUrl"&gt;${solr.core.master_url}&lt;/str&gt;
  &lt;str name="pollInterval"&gt;00:10:00&lt;/str&gt;
&lt;/lst&gt;
...</pre><p>Repeater sunucudan alınan ve solrconfig.xml olarak kaydedilen solrconfig_slave.xml dosyası master_url olarak <strong>solr.core.master_url</strong> değişkeninden gelen değeri okuyacak.</p><h3><strong>Repeater sunucular üzerinde yapılacaklar;</strong></h3><p>solr_home/collection1/conf/solrcore.properties dosyası içine her repeater sunucusunun replikasyon url&#8217;ini yazalım. Mesela 8082 sunucumuz repeater ise aşağıdaki örnek uygun olacak;</p><pre class="brush:shell">master_url=http://localhost:8082/solr/collection1/replication</pre><h3><strong>Slave sunucular üzerinde yapılacaklar;</strong></h3><p><strong></strong>Eklediğimiz herhangi bir slave sunucuyu ilk kurulumda istediğimiz bir repeater&#8217;a bağlamamız yeterli olacaktır. Diğer tüm konfigürasyonları repeater sunucudan devralacaktır. Repeater&#8217;a slave&#8217;i bağlama işlemini yazının başlarında anlattığımız yöntemle kolaylıkla yapabilirsiniz.</p><p><strong>Repeater başlığı</strong> içinde yer alan tüm adımlar için bir defaya mahsus bir üst sunucuya slave olarak bağlanmanız gerekiyor, sonrasında tüm konfigürasyonlar ve veriler bir üst sunucudan gelmeye başlayacaktır. Tek istisna repeater sunucusu üzerinde master_url&#8217;i verdiğimiz solrcore.properties dosyasını oluşturmamız gerekmesi.</p><h2>Sonuç</h2><p>Konfigürasyonları replikasyona dahil ederken tabi ki tüm dosyaları replikasyona eklememiz çok daha mantıklı olacaktır. Yazıda çok fazla karmaşık olmaması açısından önemli 1-2 dosya üzerinden anlatma yolunu seçtim.</p><p><a rel="nofollow" target="_blank" href="http://blog.mustafakirimli.com/wp-content/uploads/2014/03/apache-solr-replication-master-down.png"><img class="alignright size-medium wp-image-1709" title="apache-solr-replication-master-down" src="http://blog.mustafakirimli.com/wp-content/uploads/2014/03/apache-solr-replication-master-down-300x128.png" alt="apache solr replication master down" width="300" height="128"/></a>Solr replikasyonuyla deneysel kullanım dışında ilgilenmediğim için yanılıyor olabilme ihtimaliyle  beraber, master sunucusunu kapatırsanız ya da bir şekilde cevap veremez duruma gelirse slave sunucularda hiçbir problem çıkmıyor. Yandaki ekra görüntüsünde görüleceği üzere sadece <strong>invalid_master</strong> hatası alırsınız.</p><p>Sonuç olarak kendi tecrübelerime dayanarak replikasyon yönetmine yorum yapmam gerekirse en büyük eksikliğinin tek sunucuya güncelleme sorgusu gönderme zorunluluğunuzun olması diyebilirim. Bir sonraki yazıda inceleyeceğimiz bulut yönteminde herhangi bir sunucuya güncelleme isteği gönderebiliyorsunuz.</p><h2>Kaynaklar</h2><p><a rel="nofollow" title="Replication" target="_blank" href="http://en.wikipedia.org/wiki/Replication_%28computing%29">Replication</a><br /> <a rel="nofollow" title="Disk Mirroring" target="_blank" href="http://en.wikipedia.org/wiki/Disk_mirroring">Disk Mirroring</a><br /> <a rel="nofollow" title="RAID 1" target="_blank" href="http://en.wikipedia.org/wiki/Raid_1#RAID_1">RAID 1</a><br /> <a rel="nofollow" title="Index Replication" target="_blank" href="https://cwiki.apache.org/confluence/display/solr/Index+Replication">Solr Index Replication</a><br /> <a rel="nofollow" title="Solr Replication" target="_blank" href="https://wiki.apache.org/solr/SolrReplication">Solr Replication</a></p>]]></content:encoded>
      </item>
      <item>
         <title>Apache Solr ve Tomcat Kurulumu</title>
         <link>http://blog.mustafakirimli.com/apache-solr-ve-tomcat-kurulumu/1689</link>
         <description>Merhaba arkadaşlar, Arama Sunucuları yazısıyla</description>
         <guid isPermaLink="false">http://blog.mustafakirimli.com/?p=1689</guid>
         <pubDate>Mon, 10 Mar 2014 18:45:52 +0000</pubDate>
         <content:encoded><![CDATA[<p>Merhaba arkadaşlar, <a rel="nofollow" title="Arama Sunucular&#x000131;" target="_blank" href="http://blog.mustafakirimli.com/arama-sunuculari/1691">Arama Sunucuları</a> yazısıyla başladığımız yazı dizisini Solr üzerinden detaylı kullanım ve konfigürasyon örnekleriyle devam ettireceğiz.</p><p title="Software Distribution"><span id="more-1689"></span></p><p>Bu yazıda klasikleşen haliyle öncelikle kurulumundan başlayacağız. Ama bu defa apt, brew, port gibi paket yöneticileriyle* değil binary dağıtımlarıyla** gerekli tüm yazılımları bir klasörde çalışabilecek şekilde kuracağız.</p><h3 class="clear">Solr İçin Gerekli Yazılımlar</h3><p>Solr, Java ile geliştirilen bir yazılım olduğundan çalışırken -en az- Java Sanal Makine (Java Virtual Machine, JRE)&#8217;sine ihtiyaç duyar. En az dedik çünkü debugging yapacaksak ve bazı karakter seti sorunlarından kurtulmamız için Java Geliştirme Kiti (Java Development Kit, JDK) kurmamız gerekir. Bunun dışında Solr&#8217; ı çalıştırabilmek için dahili olarak gelen Jetty Web Sunucunu*** kullanabiliriz. Biz Tomcat ile kullanımını inceleyip kurulumu biraz detaylandıracağız. Ayrıca hemen her bilgisayarda kurulu olan JRE &#8216;yi kullanmak yerine sadece kurduğumuz Solr&#8217; ın kullanacağı JRE konfigüre edeceğiz. Bir nevi (tam olmasa da) virtual environment (sanal ortam?) yapmaya çalışacağız. Böylece Solr&#8217; ı istediğimiz herhangi bir Java sürümü ile ve tüm dosyaları tek klasörde toplayarak çalıştırabilecek hale geleceğiz. Bu aynı zamanda Solr üzerinde denemeler yapmak için de iyi bir yöntem. Ayrıca, replika**** ve cloud özellikleri için farklı kurulumlar yapıp kendi bilgisayarımızda bunları rahatlıkla denemiş oluruz. Bu ayrıca -çok nadir görülse de- sistem JRE güncellemelerinden olumsuz etkilenmemizin önüne geçer.</p><p>Toparlayacak olursak; Apache Tomcat,  Apache Solr, JRE (Java Runtime Environment) yazılımlarına ihtiyacımız olacak. Root dizinde (isterseniz masaüstü ya da tmp dizini de olabilir) solr4 adında bir klasör oluşturup ilgili yazılımları bu klasöre indireceğiz. Şu an yayında olan stabil sürümleri sırasyıla indirip sıkıştırılmış dosyaları açalım/çıkaralım ; <a rel="nofollow" title="Apache Solr 4.7.0" target="_blank" href="http://www.eu.apache.org/dist/lucene/solr/4.7.0/solr-4.7.0.zip">Apache Solr 4.7.0</a>,  <a rel="nofollow" title="Apache Tomcat 8.0.3" target="_blank" href="http://www.eu.apache.org/dist/tomcat/tomcat-8/v8.0.3/bin/apache-tomcat-8.0.3.zip">Apache Tomcat 8.0.3</a>, <a rel="nofollow" title="JRE" target="_blank" href="http://www.oracle.com/technetwork/java/javase/downloads/1880261">JRE</a> ya da <a rel="nofollow" title="JDK" target="_blank" href="http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html">JDK</a> (JDK kurulumu bu yazı kapsamında değil)</p><p>Yukarıdaki adımları uygulayıp arşiv/zip dosyalarını sildiğimizde /solr4/ klasörü şu klasörleri barındıracak;</p><ul><li>apache-tomcat-8.0.3/</li><li>jre1.7.0_51/</li><li>solr-4.7.0/</li></ul><h3>Tomcat ve JRE/JDK Kurulumu</h3><p>Bizim örneğimizdeki versiyon ile belirtecek olursak, apache-tomcat-8.0.3/conf/server.xml dosyasını açıp <em>&lt;Connector port=&#8221;8080&#8243; protocol=&#8221;HTTP/1.1&#8243;</em> yazan bölümü tomcat için hangi portu kullanmak istiyorsak port özelliğini buna göre değiştirelim. Varsayılan dışında bir kurulum yapmaya çalıştığımız için portu <em>8082</em> olarak set ediyoruz. Değişiklik sonrası ilgili satır <em>&lt;Connector port=&#8221;8082&#8243; protocol=&#8221;HTTP/1.1&#8243;</em> görünümünde olacak.</p><p>Bir başka Tomcat ayarı ise yine aynı dosyada (apache-tomcat-8.0.3/conf/server.xml) Tomcat kapatma portunu (shutdown port) değiştirmek olacak. Bunu değiştirmezsek aynı anda çalışan birden fazla Tomcat kullanırken bir Tomcat&#8217; i kapatmanız diğer Tomcat&#8217;lerin de durmasına neden olacaktır. İlgili ayar apache-tomcat-8.0.3/conf/server.xml dosyasındaki <em>&lt;Server port=&#8221;8005&#8243; shutdown=&#8221;SHUTDOWN&#8221;&gt;</em> kısmında bulunan port özelliği değiştirmek olacaktır. Biz 8006 olarak set ettik. Değişiklik sonrasında şu şekilde görünecek; <em>&lt;Server port=&#8221;8006&#8243; shutdown=&#8221;SHUTDOWN&#8221;&gt;</em></p><p>Tomcat&#8217; i kendi indirdiğimiz JRE versiyonuyla çalıştırabilmek için <em>apache-tomcat-8.0.3/bin/setenv.sh</em> dosyasını oluşturup içine &#8220;<em>JRE_HOME=/solr4/jre1.7.0_51</em>&#8221; yazmamız yeterli. Bu dosyayı oluşturmazsak Tomcat sistemin varsayılan JRE veya JDK path değişkenlerini okuyacaktır. Konsoldan yapmak için  <em>echo &#8220;JRE_HOME=/tmp/solr4/jre1.7.0_51&#8243; &gt; /solr4/apache-tomcat-8.0.3/bin/setenv.sh</em></p><p>Mac kullanıcıları JRE ayarı için <em>JRE_HOME=/solr4/jre1.7.0_51/Contents/Home</em> şeklinde ayarlamaları gerekmekte.</p><p>JDK ile çalıştırmak isterseniz JAVA_HOME değişkenini ayarlamanız gerekiyor. Catalina, JRE_HOME ayarlanmamışsa JAVA_HOME değişkenini okuduğunu söylüyor (apache-tomcat-8.0.3/bin/catalina.sh dosyasındaki direktifleri okumanız faydalı olabilir).</p><p><a rel="nofollow" target="_blank" href="http://blog.mustafakirimli.com/wp-content/uploads/2014/03/apache-tomcat-welcome-page.png"><img class="alignright size-medium wp-image-1699" style="margin-top:5px;margin-bottom:5px;" title="Apache Tomcat Welcome Page" src="http://blog.mustafakirimli.com/wp-content/uploads/2014/03/apache-tomcat-welcome-page-300x183.png" alt="Apache Tomcat Welcome Page" width="300" height="183"/></a>Bu ayarı yaptıktan sonra tomcat sunucusu kendi halinde çalışabiliyor olacak. Tomcat sunucusunu Catalina servlet konteyner (servlet container) ayar klasörü oluşması için  başlatıp durduracağız. Bunu yapmak için apache-tomcat-8.0.3/bin/ klasörü altında bulunan .sh uzantılı dosyalara çalıştırma izni vermemiz (<em>chmod +x ./apache-tomcat-8.0.3/bin/*.sh</em>) gerekiyor. Daha sonra Tomcat&#8217;i çalıştırmak için <em>./apache-tomcat-8.0.3/bin/startup.sh</em> durdurmak içinse <em>./apache-tomcat-8.0.3/bin/shutdown.sh </em>komutlarını kullanıyoruz. Tomcat düzgün çalışıyorsa yukarıdaki kurulum ayarlarıyla erişmek için http://localhost:8082 adresine girdiğimizde yandaki resmi görebiliyor olmalıyız.</p><h3>Solr Kurulumu</h3><p>Solr kurulumuna Solr ile gelen kütüphaneleri Apache lib klasörüne kopyalayarak başlayabiliriz. <em>solr-4.7.0/example/lib/ext/</em> içindeki tüm dosyaları <em>apache-tomcat-8.0.3/lib/</em> klasörü içine kopyalayalım.</p><p>Solr data ve konfigürasyon dosyalarını tutacak bir klasör oluşturuyoruz. Klasör adı <em>solr_home</em> olsun. Bu klasörü oluşturduktan sonra /solr4/ klasörü şu şekilde görünecek.</p><ul><li>apache-tomcat-8.0.3/</li><li>jre1.7.0_51/</li><li>solr-4.7.0/</li><li>solr_home/</li></ul><p>Sonrasında Solr ile gelen örnek uygulamayı (<em>solr-4.7.0/example/solr/</em> dizini içindeki her şeyi) solr_home dizinine kopyalayalım. Bu örnek uygulama Solr &#8216;a ait bir çok özelliğin konfigürasyonu bulundurduğu için yeni başlayanlar için çok faydalı olacaktır.</p><p>Bu konfigürasyonla Solr&#8217; ın kütüphaneleri bulabilmesi için <em>solr_home/collection1/conf/solrconfig.xml</em> dosyası içinde <em>&lt;lib dir=&#8221;../../../</em> yazan kısmı <em>&lt;lib dir=&#8221;../../solr-4.7.0/</em> olarak değiştirelim.</p><p>Şimdi de Solr uygulamasını Tomcat&#8217; e tanımlamaya (böylece Tomcat çalışırken deploy olmasını sağlamaya) çalışalım. Bunun için <em>apache-tomcat-8.0.3/conf/Catalina/localhost/ solr.xml</em> klasörü içinde <em>solr.xml</em> dosyası oluşturup içinde aşağıdaki konfigürasyonu yazalım;</p><pre class="brush:shell">&lt;?xml version="1.0" encoding="UTF-8" ?&gt;
&lt;Context 
    docBase="/solr4/solr-4.7.0/example/webapps/solr.war"
    allowlinking="true"
    crosscontext="true"
    debug="0"
    antiResourceLocking="false"
    privileged="true"&gt;
  &lt;Environment name="solr/home" override="true" type="java.lang.String" value="/solr4/solr_home" /&gt;
&lt;/Context&gt;</pre><p>Son olarak Solr uygulama ayarını da yapalım. Bunun için solr_home dizini içinde <em>solr.xml</em> dosyası oluşturalım ve içine aşağıdaki konfigürasyonu yazalım. Burada hostPort özelliğine Solr &#8216;ın kullanacağı portu yazıyoruz.</p><pre class="brush:shell">&lt;?xml version="1.0" encoding="UTF-8" ?&gt;
&lt;solr persistent="true"&gt;
  &lt;cores adminPath="/admin/cores" host="${host:}" hostPort="8082" hostContext="${hostContext:}"&gt;
    &lt;core config="solrconfig.xml" name="collection1" instanceDir="collection1" schema="schema.xml" dataDir="data"/&gt;
  &lt;/cores&gt;
&lt;/solr&gt;</pre><p><a rel="nofollow" target="_blank" href="http://blog.mustafakirimli.com/wp-content/uploads/2014/03/apache-solr4-homepage.png"><img class="size-medium wp-image-1700 alignleft" style="margin-top:5px;margin-bottom:5px;" title="apache-solr4-homepage" src="http://blog.mustafakirimli.com/wp-content/uploads/2014/03/apache-solr4-homepage-300x137.png" alt="Apache Solr4 Homepage" width="300" height="137"/></a>Yukarıdaki işlemleri tamamladıktan sonra http://localhost:8082/solr adresine girdiğimizde yandaki resimde bulunan Solr yönetim arayüzü önümüze geliyor olması gerekiyor. Solr yönetim paneli anasayfasında Solr versiyonunu (solr-spec), Lucene versiyonunu (lucene-spec), JVM başlığı altında Java versiyonunu (Runtime), yine JVM başlığı altında Catalina pathlerini görebilirsiniz (Args). Bu bilgiler yukarıdaki kurulumu düzgün gerçekleştirip gerçekleştiremediğimizin doğrulaması olacak. Yandaki resimde /tmp klasörü altına kurulmuş bir Solr &#8216;ın yönetim paneli anasayfası görünmekte. Diğer direktifleri görmek/doğrulamak için http://localhost:8082/solr/#/~java-propertis adresini kullanabilirsiniz.</p><h3>Solr Kurulum Scripti</h3><p>Bu işlemleri konsoldan yapmak isterseniz gerekli komutlar aşağıdaki gibidir (kullanmadan önce sisteminizin yedeğini almanız önerilir). Ayrıca bir sonraki yazıda replika kurarken, daha sonra cloud kurulumunda shardening***** ile birlikte replika kurarken (4 ayrı server kurulumunu simüle edeceğiz) bu kod bize biraz yardımcı olacak.</p><pre class="brush:shell">############ kurulum icin basit ayarlar, istedigimiz sekilde degistirebiliriz ###########
export SOLR_DIR='solr4'      # tum uygulama, konfigurasyon ve datalarin olacagi klasor
export SOLR_PORT='8082'      # solr'i kullanmak istedigimiz port
export TOMCAT_MPORT='8006'   # tomcat yonetim portu
export SOLR_VER='4.7.0'      # kullanmak istedigimiz solr versionu
export TOMCAT_VER='8.0.3'    # kullanmak istedigimiz tomcat versionu 
export SOLR_HOME='solr_home' # solr'a ait data ve konfigurasyonlarin bulunacagi klasor 
if [ -d "/Applications/" ]
then
  export JRE_URL='http://download.oracle.com/otn-pub/java/jdk/7u51-b13/jre-7u51-macosx-x64.tar.gz'  # MacOS x64
else
  export JRE_URL='http://download.oracle.com/otn-pub/java/jdk/7u51-b13/jre-7u51-linux-x64.tar.gz' # linux x64
fi
############ kurulum icin basit ayarlar, istedigimiz sekilde degistirebiliriz ###########

mkdir $SOLR_DIR # solr klasorunu olustur
cd $SOLR_DIR    # solr klasorune gir

# solr klasorunu diger islemler icin degiskene set et
export MYHOME=`pwd` #echo $MYHOME 

# ilgili solr, tomcat ve jre versiyonunu indir
wget "http://www.eu.apache.org/dist/lucene/solr/$SOLR_VER/solr-$SOLR_VER.zip"
wget "http://www.eu.apache.org/dist/tomcat/tomcat-`echo $TOMCAT_VER |cut -d'.' -f1`/v$TOMCAT_VER/bin/apache-tomcat-$TOMCAT_VER.zip"
wget -O jre.tar.gz --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com" $JRE_URL jre.tar.gz

# indirilen zipli solr ve tomcat dosyalarini ac ve zipli dosyalari sil
unzip "apache-tomcat-$TOMCAT_VER.zip" &amp;&amp; unzip "solr-$SOLR_VER.zip"
rm "apache-tomcat-$TOMCAT_VER.zip" &amp;&amp; rm "solr-$SOLR_VER.zip"

# jre' yi arsivden cikart ve arsiv dosyasini sil
tar -xzvf jre.tar.gz &amp;&amp; rm jre.tar.gz

# cikarlina jre klasorunu jre olarak yeniden adlandir
for file in jre*.jre; do mv "$file" "jre"; done

# sistem varsayilan JRE 'si yerine indirdigimiz jre'yi kullan
if [ -d "/Applications/" ]
then
  echo "JRE_HOME=$MYHOME/jre/Contents/Home" &gt;  apache-tomcat-$TOMCAT_VER/bin/setenv.sh # MacOS x64
else
  echo "JRE_HOME=$MYHOME/jre" &gt;  apache-tomcat-$TOMCAT_VER/bin/setenv.sh # linux x64
fi

# tomcat portunu istenilen portla degistir
sed -i.bak 's%%%g' apache-tomcat-$TOMCAT_VER/conf/server.xml

# tomcat/bin klasoru icindeki .sh uzantili dosyalara calistirma izni ver
chmod +x ./apache-tomcat-$TOMCAT_VER/bin/*.sh

./apache-tomcat-$TOMCAT_VER/bin/startup.sh # tomcat'i baslat
sleep 8 # tomcat'in hazir olmasi icin bir sure bekle (8 saniye)
./apache-tomcat-$TOMCAT_VER/bin/shutdown.sh # tomcat'i durdur

# solr ile gelen kutuphaneleri tomcat/lib klasorune kopyala
cp solr-$SOLR_VER/example/lib/ext/* apache-tomcat-$TOMCAT_VER/lib/

mkdir $SOLR_HOME # solr home klasorunu olustur

# solr ile gelen ornek solr uygulamasini solr home dizinine kopyala
cp -r solr-$SOLR_VER/example/solr/* $SOLR_HOME/

# solr'in basvuracagi kutuphane yolunu guncelle
sed -i.bak 's%

' &gt; apache-tomcat-$TOMCAT_VER/conf/Catalina/localhost/solr.xml

# solr'i tek core ile calisacak sekilde konfigure et
echo '

' &gt; $SOLR_HOME/solr.xml

 # tomcat'i baslat
./apache-tomcat-$TOMCAT_VER/bin/startup.sh</pre><h3>Sonuç:</h3><p>Kurulum işlemi biraz kafa karıştırıyor gibi görünüyor olabilir, ayrıca paket yöneticilerini kullanarak tek komut ile yüklemeyi çok kolay gerçekleştirebilirsiz de. Bunu seçmeme nedenlerime gelince;</p><ul><li>Bilgisayardan anladığımı zannetsem de Ubuntu üzerinde bir çok JRE/JDK kurulu olmasına rağmen varsayılan JRE 1.6 &#8216;ya ayarlı olduğundan sürekli hata almam. .bash_profile vd. dosyaları, sembolik linkleri tek tek karıştırıp doğrusu set etmem gerekiyor muhtemelen ya da bilgisayarcı çağırmam gerekiyor <img src='http://blog.mustafakirimli.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley'/></li><li>Son uygulama sürümleri için işletim sisteminizi yükseltme zorunluluğu veya paket yöneticinizin sürümünü kullanmak zorunda kalmam,</li><li>Tek bilgisayarda aynı anda birden çok kopya/örnek (instance) çalıştırmayı veya farklı Solr/Tomcat kombinasyonlarını test etmeyi istemem,</li><li>Windows kullananlar için biraz daha platform bağımsız bir anlatım olmasını istemem (en azından hangi dosyalara path ve direktifler eklendiği anlaşılabiliyor)</li></ul><p>Eğer kurulum yaptığım klasörü taşıdığımda da Solr çalışmaya devam etsin derseniz <a rel="nofollow" title="Apache Solr Setup With Relative Path" target="_blank" href="https://gist.github.com/mustafakirimli/9430373">https://gist.github.com/mustafakirimli/9430373</a> adresindeki relative path ile konfigüre edilmiş kurulum scriptini kullanabilirsiniz.</p><h3>Kaynak:</h3><p><a rel="nofollow" title="Solr Install" target="_blank" href="https://wiki.apache.org/solr/SolrInstall">https://wiki.apache.org/solr/SolrInstall</a><br /> <a rel="nofollow" title="Solr Setup Script" target="_blank" href="https://gist.github.com/mustafakirimli/9416138">https://gist.github.com/mustafakirimli/9416138</a><br /> <a rel="nofollow" title="Apache Solr Setup With Relative Path" target="_blank" href="https://gist.github.com/mustafakirimli/9430373">https://gist.github.com/mustafakirimli/9430373</a> (relative path ile)<br /> <a rel="nofollow" title="Apache Tomcat Catalina" target="_blank" href="http://en.wikipedia.org/wiki/Apache_Tomcat#Catalina">http://en.wikipedia.org/wiki/Apache_Tomcat#Catalina</a></p><p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br /> * <a rel="nofollow" title="List of software package management systems" target="_blank" href="http://en.wikipedia.org/wiki/List_of_software_package_management_systems">Paket Yöneticileri</a><br /> ** <a rel="nofollow" title="Software Distribution" target="_blank" href="http://en.wikipedia.org/wiki/Software_distribution">Yazılım Dağıtımı</a><br /> *** <a rel="nofollow" title="Jetty Web Server" target="_blank" href="http://en.wikipedia.org/wiki/Jetty_%28web_server%29">Jetty Web Sunucusu</a><br /> **** <a rel="nofollow" title="Replication" target="_blank" href="http://en.wikipedia.org/wiki/Replication_%28computing%29">Replika</a><br /> ***** <a rel="nofollow" title="Shard" target="_blank" href="http://en.wikipedia.org/wiki/Shard_%28database_architecture%29">Shard</a></p>]]></content:encoded>
      </item>
      <item>
         <title>Arama Sunucuları</title>
         <link>http://blog.mustafakirimli.com/arama-sunuculari/1691</link>
         <description>Merhaba arkadaşlar, kısa süre önce</description>
         <guid isPermaLink="false">http://blog.mustafakirimli.com/?p=1691</guid>
         <pubDate>Fri, 07 Mar 2014 17:30:28 +0000</pubDate>
         <content:encoded><![CDATA[<p>Merhaba arkadaşlar, kısa süre önce naçizane sosyal medya üzerinden duyurduğum Solr hakkında yazı dizisi hazırlama haberini hayata geçiriyorum.</p><p><span id="more-1691"></span></p><p>Zamanım oldukça Solr hakkında öğrendiğim/uyguladığım birçok bilgi/yöntemi buradan paylaşmaya çalışacağım. Basit kurulumundan başlayıp (bu yazı hazır, önümüzdeki hafta yayında olacak), replica kurulum, cloud kurulum gibi adımlarla devam edip, daha sonra detaylı konfigürasyon yazıları (solr.xml, solrconfig.xml, schema.xml, zoo.cfg vd.) yayınlayıp örnek senaryolar üzerinden Solr optimizasyon konularını içeren yazıları da paylaşıp yazı dizisini tamamlamayı düşünüyorum.</p><h3 class="clear">Neden Arama Sunucusu* (otomatik tamamlama &#8211; auto complete)</h3><p>Bu yazı tabi ki arama sunucusu kullanmayı düşünenler için ama yine de -tam cevabı olamasa da- kendi tecrübelerime dayanarak ifade etmeye çalışayım. Genellikle kullanıcı arama sorgularını veritabanı üzerinde <em>LIKE</em> kullanarak işleriz, text alanlarda da <em>MATCH() AGAINST</em> ile fulltext search yaparız. Hatta bazen <em>SOUNDEX</em> de kullandığımız olmuştur ve bunu basit bir eşleme işi için kullandığımı da söylemeden geçemeyeceğim.</p><p>Özellikle gelişmiş e-ticaret sistem ve/veya sitelerini teknik açıdan incelerseniz (Magento iyi bir örnek) sadece arama yapmak değil kullanıcı anlamaya ve yardımcı olmaya yönelik birçok optimizasyon yapıldığını rahatlıkla görebilirsiniz. Mesela arama kelimeleri için <strong><em>eşanlamlı</em></strong> sözcük listesi kullanılır. Kullanıcı sorgusu öncelikle bu kelimelerin olduğu tabloda taranır ve değiştirilerek yukarıdaki arama yöntemi ile devam edilir. Mesela kullanıcı <em>Karnıbahar</em> araması yaptığında biz bunu<em> Karnabahar</em> olarak değiştirip (<strong>düzeltme</strong>) aramayı bu şekilde sürdürürüz. Kullanıcı <em>TV</em> araması yaptığında <em>Televizyon</em> olarak yine bu tablo yardımıyla değiştiririz (<strong>eşanlamlı sözcük</strong>).</p><p>Bunun yanı sıra yine Magento üzerinde bir örneğini görebileceğiniz bazı performans ve optimizasyonlar görebiliriz. Buna en iyi örnek Magento catalogsearch_fulltext tablosudur. Bu tabloda ürün özelliklerinden aranmasını istediğiniz özellik değerleri yatay halde tek satırda tutulur. Çünkü özellikle biraz gelişmiş sistemler bile yönetim panelinde esneklik sağlamak için verilerin önemli bir kısmı düşey olarak tutulur. Hâl böyle olunca bunları tek bir tabloya alıp otomatik tamamlama (auto complete) sorgularını hızlandırmamız gerekir. Bu tablonun bir nedeni de (en azından MySQL &#8216;de) InnoDB arama motoru kullanan tabloda fulltext search index kullanamıyor olmanızdır.</p><p>Ayrıca arama kelimelerini dil işleyen bir sınıf/sistem üzerinden geçirip çekim ve yapım eklerini atarak aramaya devam etmek istiyor da olabiliriz.</p><h3>Neden Arama Sunucusu (filtreleme/faceted search-navigation**)</h3><p>İnternet üzerinde portallarda ve e-ticaret sitelerinde sıklıkla karşılaştığımız bir özellik olan filtreleme artık vazgeçilmez hale geldi. Ve IT olarak bu isteğe çözüm üretmek gibi bir yükümlülüğümüz var. Bu cümleden sonra iç içe yazılmış AND / OR sorguları gözümüzün önünde hemen canlandı sanki. Hele bir de çoklu seçim özelliği ile ürün sayıları eklenince kafalarımız biraz daha karışmaya başlıyor.</p><p>Kullanıcı A markalı ürünleri görmek istediğinde ekranda sadece A markalı ürünleri gösteriyorken bir başka marka da seçebilmesi için (seçimi/filtreyi genişletme, çoklu seçim) diğer markaları da göstermemiz gerekir. Bunun üzerine bir başka özelllik ile de (renk, fiyat vd) filtre yapmak istediğinde -bir çok projede- ürün listesindeki ürünleri ayrı, filtreleri ayrı sorgularla çekmek zorunda kalırız.</p><p>Bir başka en iyi örnek ise; kullanıcı <em>Android Telefon</em> araması yapıp ucuzdan pahalıya doğru sıraladığında önce direkt eşleşenleri kendi içlerinde sıralamak sonrasında tek tek eşleşenleri kendi içlerinde sıralamak gerekir. Bu arama da Telefon kelimesiyle eşleşen ama ucuz olan bir telefonun <em>Android Telefon</em> ile direkt eşleşen telefonlardan önce çıkmaması gerekir. <em>ORDER BY FUNC(x) DESC, ORDER BY FUNC(x) DESC ..</em> sorgusundan bahsediyoruz aslında. Bu, arama sunucularının sıralamadaki en basit özelliğidir, bunun için bile MySQL sunucumuzu filesort &#8216;a zorlamış oluyoruz (yanılmıyorsam).</p><h3>Hangi Arama Sunucusu</h3><p>Piyasada yaygın olarak kullanılan Apache Solr ve ElasticSearch var. İkisi de lucene tabanlı olup bazı özellik farkları bulunmakta. Biz Apache Solr ile devam edeceğiz. Özellik karşılaştırması için güzel bir site de mevcut. <a rel="nofollow" title="Solr vs ElasticSearch" target="_blank" href="http://solr-vs-elasticsearch.com/">Solr vs ElasticSearch</a> adresinden ulaşabilirsiniz.</p><p>Adresini şu an hatırlamadığım bir başka sitede okuma işlemlerinde Solr, yazma işlemlerinde ise ElasticSearch &#8216;ün hızlı olduğunu okumuştum. Karar vermeden önce kendi testlerinizi yapmanızı öneririm.</p><h3>Kaynak ve Ekstra Bilgi</h3><p><a rel="nofollow" title="Search Engine Indexing" target="_blank" href="http://en.wikipedia.org/wiki/Search_engine_indexing">Search Engine Indexing</a><br /> <a rel="nofollow" title="Faceted Search" target="_blank" href="http://en.wikipedia.org/wiki/Faceted_search">Faceted Search</a><br /> <a rel="nofollow" title="Inverted Index" target="_blank" href="http://en.wikipedia.org/wiki/Inverted_index">Inverted Index</a><br /> <a rel="nofollow" title="N-gram" target="_blank" href="http://en.wikipedia.org/wiki/N-gram">N-gram</a><br /> <a rel="nofollow" title="Apache Lucene" target="_blank" href="http://lucene.apache.org/core/">Apache Lucene</a><br /> <a rel="nofollow" title="Apache Solr" target="_blank" href="https://lucene.apache.org/solr/"> Apache Solr</a><br /> <a rel="nofollow" title="Elasticsearch" target="_blank" href="http://www.elasticsearch.org/">Elasticsearch</a><br /> &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br /> * Arama moturu olarak da adlandırılmasıyla birlikte hem Google, Yahoo, Bing gibi sitelerle karıştırılmaması hem de arama algoritması, indexleme yazılımı gibi isimleri olması nedeniyle &#8220;<strong>Arama Sunucusu</strong>&#8221; olarak anıyoruz<br /> ** Türkçe karşılığını bulamadığım için kusura bakmayın, ayrıca Magento bunu layered navigation adıyla anıyor</p>]]></content:encoded>
      </item>
      <item>
         <title>Mesaj Kuyruklama (Messaging Queue)</title>
         <link>http://blog.mustafakirimli.com/mesaj-kuyruklama-messaging-queue/1683</link>
         <description>Aylar sonra tekrar merhaba arkadaşlar,</description>
         <guid isPermaLink="false">http://blog.mustafakirimli.com/?p=1683</guid>
         <pubDate>Sat, 01 Mar 2014 12:44:39 +0000</pubDate>
         <content:encoded><![CDATA[<p>Aylar sonra tekrar merhaba arkadaşlar, Blogdan uzaktan kaldığım süre içerisinde cevaplayamadığım konu kaldıysa lütfen kusuruma bakmayın deyip hızlıca yazıya giriş yapmak istiyorum.</p><p><span id="more-1683"></span></p><p>Bu yazıda, aslında birçok blog ve etkinlikte gerek yakinen tanıdığım/çalıştığım arkadaşlarımın gerekse sektörde bulunan tecrübeli meslektaşlarımın değindiği mesaj kuyruklama (messaging queue) konusuna bir de biz göz atacağız.</p><h3 class="clear">Mesaj (İş) Kuyruklamaya Neden İhtiyaç Duyarız</h3><p>Birçok projede kullanıcıyla direkt bağlantısı olsun ya da olmasın çalıştırılması/yürütülmesi zaman alan bazı işlemler gerçekleştiriyoruz. Buna, sık telaffuz edilen kullanıcı kayıt (register) olduğunda email gönderilmesi örneğini verebileceğimiz gibi, kullanıcının istediği raporu hazırlama, yüklenen bir imajı farklı ebatlarda boyutlandırma, alınan sipariş/satış/rezervasyon gibi bilgilerin kullandığımız diğer yazılımlara aktarımı vb. örnekler de vermemiz mümkün.</p><p>Ayrıca sadece çalışması/yürütülmesi zaman alan işlemler değil; belirli aralıklarla çalışması gereken betikler ve üzerinde bir takım iş mantığı yürütüldükten sonra işleme alınması gereken  işlemler de gerekli olabilir.</p><h3>Mesaj Kuyruklamayı Geleneksel Yöntemlerle Nasıl Çözeriz</h3><p>Yukarıda saydığımız bu ve bu gibi işlemleri kullanıcıyı bekletmeden çalıştırmak için bir dizi önlemler/geliştirmeler almamız elbette mümkün. Bunlardan İlk akla geleni ve bizim de tecrübe ettiğimiz asenkron işlemi simüle etme yöntemidir. Bu yöntemde zamanlanmış görevler (linux için cron) kullanılarak yapılacak işler ilgili tablolardan zaman aralığı vd. bilgilere göre taranıp işlenir (son 5 dakika içindeki yeni kayıtları işlemek gibi). Bir diğer simüle yöntemi ise, bir önceki paragrafta yer alan işlemler (kayıt, sipariş/satış/rezervasyon vd) tamamlandığında bir kaynağa (dosya, sql, no-sql, memory) işlenmesi gereken iş olduğu bildirilip işleme devam edilir ve yine zamanlanmış görevler yardımıyla bunlar işlenir.</p><p>Bu yöntem ilk başlarda tabi ki kolay ve uygun görülebilir ama projenizin ikinci yılında 25 adet zamanlanmış göreviniz olduğunda gerek yönetim gerekse işletim maliyetleri açısından işiniz zora girmeye başlayabilir. Tek dezavantaj tabiki bu değildir aşağıdaki soru(n)ları da cevapsız bırakmayacak bir yazılım geliştirmeniz kaçınılmaz olacaktır;</p><ul><li>Yürütülme esnasında hata oluşursa tekrar denenmesi gerekir (tekrar deneme, retry)</li><li>Bazı işler belirli önceliğe göre çalışması gerekebilir (önceliklendirme, priority)</li><li>Bir işin önceliği düşük olsa bile uzun süre kuyrukta kalmaması gerekir (yaşlandırma, aging)</li><li>İşlerin kısa sürede işleme alınması gerekir (sık aralıklarla çalışan cron)</li><li>İki ayrı zamanlanmış görev (cron) aynı iş üzerinde çakışmaması gerekir</li><li>X kaynağı aktarım yaparken bizden HTTP yetkilendirmesi istiyor</li><li>Kuyrukları tek makinede işlemek yeterli olmuyor iki makine işlesin (ölçeklendirme, scaling)</li></ul><p><strong>İlk madde için;</strong> Hata durumunda diğer işlerin yürütülmesi sorun değilken diğer bir işte kesinlikle sonrakilerinde işlenmemesi gerekiyor olabilir.</p><p><strong>Bunlardan özellikle son iki madde</strong> gerçekten çok önemli bir sorun teşkil ediyor. Zamanlanmış görevi uzun aralıklarla çalıştırırsanız (1-2 saat gibi) bu süre zarfında 3 tane iş olsa dahi işlenmeyecek, ama sık çalıştırırsanız ve yoğun iş kuyruğu oluşursa iki ayrı zamanlanmış görev aynı işi yapmaya başlayacak. Bunun önüne geçmek için zamanlanmış görev dosyasının sadece bir defa çalışması için &#8220;file lock&#8221; kullanacaksınız ama zamanlanmış görev dosyası hata fırlatırsa ve kilidi kaldıramazsa başka bir zamanlanmış görev çalışamayacak. Hatta bir defasında veritabanında tuttuğumuz iş (kuyruk) tablosuna <strong>is_locked</strong> alanı açtığımızı ve zamanlanmış görev çalışırken ilgili satırı işlemeden önce kilitlediğini itiraf etmem de iyi olacaktır.</p><p>Son madde için de -kendi kuyruklama yazılımımızı geliştirmeye çalıştığımız için- elbette bizim bir çözüm bulmamız gerekiyor; tek sayıları bir makine çift sayıları ayrı bir makine işlesin (maksimum iki makine tabi ki), random bir iş seçsin, random bir makineye atılsın, saniye bazında aralıklarla çoklu makine çalışsın vs. gibi.</p><p>Yukarıda yazılanların hepsinin tecrübe ile sabit olduğunu ve paragraf sayısını artırmanın da bir o kadar mümkün olduğunu bilmenizi isterim.</p><p>Ve elbette bunları yapmak bir şekilde mümkün görünüyor da olabilir, ama projemizin asıl amacı iş kuyruklamak ve bunları yönetmek değilse bırakalım bunu ilgili bileşen yapsın. Buna şöyle bakabiliriz; piyasada halihazırda onlarca veritabanı sunucusu var ve çoğunlukla açık kaynak ve biz kendi veritabanı sunucumuzu yazmak yerine -çoğunlukla- bunlardan birini kullanıyoruız.</p><h3>Mesaj Kuyruklamayı Yeni Nesil* Yöntemlerle Nasıl Çözeriz</h3><p>Yazının girişinde de bahsettiğim gibi kuyruklamanın nasıl kullanılacağına dair çokça döküman olması, yazının asıl amacı &#8220;nasıl kullanırız&#8221; yerine &#8220;<strong>neden kullanmalıyız</strong>&#8221; sorusuna cevap aramak olması ve  saatlerce zaman harcanmasına rağmen kod örneklerinin eksikliği, yetersiz bulmam vd. nedenlerle taslak olarak kalan 26 adet yazı sebebiyle bu kısmı çok uzun tutmayacağım.</p><p>Kısaca değinecek olursak; ihtiyacımız olan özelliklerin hemen hepsini karşılayan çözümler/yazılımlar mevcut. Bunlardan birini seçerek başlamak ve proje geliştirme sürecinde iş kuyruklamayı da göz önünde bulundurmak iyi olacaktır. Sonrasında ilgili yerlerde mesaj kuyruklama yazılımına işi -varsa nevi ile birlikte bildirmek- ve listener (consumer) aracılığıyla kuyruğa gelen işleri işlemek olacaktır.</p><p>Yazıyı, &#8220;neden kullanmalıyız&#8221; sorusuna cevap arama kapsamında tutup burada noktalamak istiyorum. Kesin olmamakla birlikte mesaj kuyruklama bileşen/yazılımlarının bize sayfadığı faydaları bir başka yazıda tartışabiliriz diye düşünüyorum.</p><p>Herkese keyifli çalışmalar,</p><p>* Yeni nesil diye adlandırıyor olmakla birlikte mesaj kuyruklamanın aslında hiç de yeni olmayan bir bileşen olduğunu bilmenizi isterim.</p>]]></content:encoded>
      </item>
      <item>
         <title>Django İle Hasta Takip Yazılımı Yapmak – Django Kurulum</title>
         <link>http://yazilim.soysal.biz/django-ile-hasta-takip-yazilimi-yapmak-django-kurulum/</link>
         <description>Bu yazı dizisinin indeksine şu sayfadan ulaşabilirsiniz. Django kurmadan önce virtualenvironment ile &amp;#8220;sanal geliştirme ortamı&amp;#8221; kurmalıyız. İstediğiniz herhangi bir dizine kurabilirsiniz. Benim seçtiğim dizin : ~/project/ Bu dizine virtualenv hastatakip komutu ile yeni virtual environment ortamı oluşturuyoruz. Bu komut sonrasında dizine aşağıdaki dosyalar oluşmalı. bin/ include/ lib/ local/ Kurmuş olduğumuz &amp;#8220;virtual environment&amp;#8221;ı aktif etmek için. [&amp;#8230;]</description>
         <guid isPermaLink="false">http://yazilim.soysal.biz/?p=495</guid>
         <pubDate>Wed, 19 Feb 2014 07:42:04 +0000</pubDate>
         <content:encoded><![CDATA[<p><img class="alignleft size-medium wp-image-500" style="margin:5px;" alt="Django ile hasta takip uygulamas&#x000131;" src="http://yazilim.soysal.biz/wp-content/uploads/2014/01/hasta-takibi-300x195.jpg" width="300" height="195"/>Bu yazı dizisinin indeksine <a rel="nofollow" title="Django &#x000130;le Hasta Takip Yaz&#x000131;l&#x000131;m&#x000131; Yapmak &#x002013; Giri&#x00015f;" target="_blank" href="http://yazilim.soysal.biz/django-ile-hasta-takip-yazilimi-yapmak-giris/">şu sayfadan</a> ulaşabilirsiniz.</p>
<p>Django kurmadan önce virtualenvironment ile &#8220;sanal geliştirme ortamı&#8221; kurmalıyız. İstediğiniz herhangi bir dizine kurabilirsiniz. Benim seçtiğim dizin :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">~<span style="color:#339933;">/</span>project<span style="color:#339933;">/</span></pre></td></tr></table></div>

<p>Bu dizine</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">virtualenv hastatakip</pre></td></tr></table></div>

<p>komutu ile yeni virtual environment ortamı oluşturuyoruz. Bu komut sonrasında dizine aşağıdaki dosyalar oluşmalı.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">bin<span style="color:#339933;">/</span>
<span style="color:#b1b100;">include</span><span style="color:#339933;">/</span>
lib<span style="color:#339933;">/</span>
local<span style="color:#339933;">/</span></pre></td></tr></table></div>

<p>Kurmuş olduğumuz &#8220;virtual environment&#8221;ı aktif etmek için.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">source ~<span style="color:#339933;">/</span>project<span style="color:#339933;">/</span>hastatakip<span style="color:#339933;">/</span>bin<span style="color:#339933;">/</span>activate</pre></td></tr></table></div>

<p>komutu çalıştırılmalı.  Virtual environment aktif edildikten sonra Django kurulumu yapabiliriz.  Djangoyu kurmak için</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">pip install django</pre></td></tr></table></div>

<p>komutunu yazıyoruz.  Böylece virtual environment altına django kurulumu yapmış olduk.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">cd ~<span style="color:#339933;">/</span>project<span style="color:#339933;">/</span>hastatakip<span style="color:#339933;">/</span>
django<span style="color:#339933;">-</span>admin<span style="color:#339933;">.</span>py startproject hastatakip</pre></td></tr></table></div>

<p>komutu ile yeni django kurulumu yapılır.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">cd hastatakip</pre></td></tr></table></div>

<p>komutu ile yeni oluşturulan django dizine geçtikten sonra</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">python manage<span style="color:#339933;">.</span>py runserver</pre></td></tr></table></div>

<p>komutu ile yeni projenizi çalıştırıyor olmanız gerekiyor. Hatasız çalıştığını varsayıyorum. O halde</p>
<p><a rel="nofollow" target="_blank" href="http://127.0.0.1:8000/">http://127.0.0.1:8000/</a> adresinde django projenizi görüntülüyor olmalısınız.</p>
<p>Django ile kurulmuş projenizde her defasında virtual environment&#8217;ı ve djangoyu çalıştırmak için uzun kodlar yazmanız zor olabilir. Bunun için şöyle küçük kısayollar işinizi kolaylaştıracaktır.</p>
<p>Aşağıdaki 3 satırı  ~/.bashrc dosyasına ekleyelim.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">alias hasta<span style="color:#339933;">=</span><span style="color:#0000ff;">'cd ~/project/hastatakip/hastatakip; source ~/project/hastatakip/bin/activate'</span>
alias hastarun<span style="color:#339933;">=</span><span style="color:#0000ff;">'cd ~/project/hastatakip/hastatakip; source ~/project/hastatakip/bin/activate; python manage.py runserver;'</span>
alias hastashell<span style="color:#339933;">=</span><span style="color:#0000ff;">'cd ~/project/hastatakip/hastatakip; source ~/project/hastatakip/bin/activate; python manage.py shell;'</span></pre></td></tr></table></div>


<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">source ~<span style="color:#339933;">/</span>bashrc</pre></td></tr></table></div>

<p>komutunu çalıştırdıktan sonra</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">hasta</pre></td></tr></table></div>

<p>komutu hastatakip projesi dizinine gidecek ve virtualenvironment&#8217;ı aktif edecek.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">hastarun</pre></td></tr></table></div>

<p>komutu hastatakip projesi dizinine gidecek ve virtualenvironment&#8217;ı aktif edecek ve djangoyu çalıştıracak.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">hastashell</pre></td></tr></table></div>

<p>komutu hastatakip projesi dizinine gidecek ve virtualenvironment&#8217;ı aktif edecek ve djangoyu shell&#8217;i çalıştıracak.</p>
<p>Artık <b>hastarun</b> diyerek projemizi</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">pip freeze</pre></td></tr></table></div>

<p>komutu yaklaşık ise şu sonucu veriyor olmalı.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">Django<span style="color:#339933;">==</span>1<span style="color:#339933;">.</span>6<span style="color:#339933;">.</span>1
argparse<span style="color:#339933;">==</span>1<span style="color:#339933;">.</span>2<span style="color:#339933;">.</span>1
wsgiref<span style="color:#339933;">==</span>0<span style="color:#339933;">.</span>1<span style="color:#339933;">.</span>2</pre></td></tr></table></div>]]></content:encoded>
      </item>
      <item>
         <title>Django İle Hasta Takip Yazılımı Yapmak – Platform</title>
         <link>http://yazilim.soysal.biz/django-ile-hasta-takip-yazilimi-yapmak-platform/</link>
         <description>Bu yazı dizisinin indeksine şu sayfadan ulaşabilirsiniz. Django ile bir arkadaşım için yazdığım hasta takip uygulaması Ubuntu 13.10 üzerinde geliştirdim. Ubuntu versiyonunuzu görmemin yollarını şu sayfadan öğrenebilirsiniz. Kod geliştirme için hiç IOS  kullanmadım ama Windows ile Linux kıyaslamasında Linux bir çok yönü ile açık ara önde bence. Linux tabanlı işletim sistemleri arasında ise Ubuntu tercih etmemin sebebi [&amp;#8230;]</description>
         <guid isPermaLink="false">http://yazilim.soysal.biz/?p=488</guid>
         <pubDate>Sat, 08 Feb 2014 08:41:57 +0000</pubDate>
         <content:encoded><![CDATA[<p><img class="alignleft size-medium wp-image-500" style="margin:5px;" alt="Django ile hasta takip uygulamas&#x000131;" src="http://yazilim.soysal.biz/wp-content/uploads/2014/01/hasta-takibi-300x195.jpg" width="300" height="195"/>Bu yazı dizisinin indeksine <a rel="nofollow" title="Django &#x000130;le Hasta Takip Yaz&#x000131;l&#x000131;m&#x000131; Yapmak &#x002013; Giri&#x00015f;" target="_blank" href="http://yazilim.soysal.biz/django-ile-hasta-takip-yazilimi-yapmak-giris/">şu sayfadan</a> ulaşabilirsiniz.</p>
<p>Django ile bir arkadaşım için yazdığım hasta takip uygulaması <a rel="nofollow" title="Ubuntu" target="_blank" href="http://www.ubuntu.com/">Ubuntu</a> 13.10 üzerinde geliştirdim. Ubuntu versiyonunuzu görmemin yollarını <a rel="nofollow" title="Ubuntu versiyonunu &#xf6;&#x00011f;renme" target="_blank" href="https://help.ubuntu.com/community/CheckingYourUbuntuVersion">şu sayfadan</a> öğrenebilirsiniz. Kod geliştirme için hiç IOS  kullanmadım ama Windows ile Linux kıyaslamasında Linux bir çok yönü ile açık ara önde bence. Linux tabanlı işletim sistemleri arasında ise Ubuntu tercih etmemin sebebi ise uygulama kütüphanesinin uyumluluğu ve stabiletesi diyebiliriz ve ayrıca alışkanlık <img src="http://yazilim.soysal.biz/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley"/>  Diğer Linux Dağıtımları için <a rel="nofollow" title="Linux Da&#x00011f;&#x000131;t&#x000131;mlar&#x000131;" target="_blank" href="http://tr.wikipedia.org/wiki/Linux_da%C4%9F%C4%B1t%C4%B1mlar%C4%B1">şu sayfaya</a> göz atabilirsiniz.</p>
<p>Kod Editörü olarak <a rel="nofollow" title="Sublime Text" target="_blank" href="http://www.sublimetext.com/">Sublime Text</a> 2.0.2 kullandım. Sublime çok severek kullandığım bir uygulama değil. Hatta sublime için gerçek anlamda bir editör demek zor. Fakat kullanımındaki basitliği, hızı ve python için geliştirilmiş trial kullanılanabilen uygulamanın çok fazla olmaması Sublime&#8217;ı ön plana çıkarıyor.</p>
<p>Versiyon kontrol sistemi için ise <a rel="nofollow" title="Git Versiyon Kontrol Sistemi" target="_blank" href="http://git-scm.com/">git</a> kullandım. Linux işletim sistemi geliştiricisi  <a rel="nofollow" title="Linus Torvalds" target="_blank" href="http://tr.wikipedia.org/wiki/Linus_Torvalds">Linus Torvalds</a> tarafından 2005 yılında tasarlanan git versiyon kontrol sistemi, biz yazılımcıların hayatında gerçekten bir devrim oldu. git &#8216;in 1.8.3.2 versiyonu kurulu ubuntu üzerinde. Git reposu olarak ise ücretsiz özel repo vermesi sebebi ile <a rel="nofollow" title="BitBucket" target="_blank" href="http://www.bitbucket.org">bitbutket</a> kullandım.</p>
<p><a rel="nofollow" title="Python Software" target="_blank" href="http://www.python.org/">Python</a> kütüphanelerinin stabilitesini kontol etmek için virtualenvironment ve <a rel="nofollow" title="Python Pip" target="_blank" href="https://pypi.python.org/pypi/pip">pip</a> kullandım.  Virtualenvironment kurduktan ve aktif ettikten sonra pip ile kurduğumuz her paket o sanal ortama özgü olur. Virtual environment hakkında Cihan Okyay&#8217;ın <a rel="nofollow" title="Virtualenv nedir?" target="_blank" href="http://linux59.blogspot.com/2011/09/virtualenv-nedir-yenir-mi.html">şu yazısını</a> okuyabilirsiniz. <a rel="nofollow" title="Python Pip Nedir?" target="_blank" href="http://yazilim.soysal.biz/python-pip-nedir/">Python pip</a> hakkında ise şöyle bir yazım var. Python 2.7.5 versiyonu kurulu bilgisayarımda.</p>
<p>Python ve django kurulumlarını bu yazı dizisinin içeriğine almadım. Başka makalelerden bulunabilir.  O nedenle bu yazıyı burda noktalıyorum. Nokta.</p>]]></content:encoded>
      </item>
      <item>
         <title>Django İle Hasta Takip Yazılımı Yapmak – Giriş</title>
         <link>http://yazilim.soysal.biz/django-ile-hasta-takip-yazilimi-yapmak-giris/</link>
         <description>Uzun zaman önce diş hekimi bir arkadaşıma basit ama onun bütün hasta takip yükünü alacak kadar da detaylı bir yazılım geliştirme sözü verdim. O çoktan bu işin olacağından ümidini yitirdi ama gördüğünüz gibi ben yitirmedim Yazmaya başladım bile hatta. Yazdıkça da, burada paylaşacağım. Yazının uzun olacağını düşünerek, isimlendirerek bölümlere ayırdım  : Bölüm 1 : Django İle Hasta [&amp;#8230;]</description>
         <guid isPermaLink="false">http://yazilim.soysal.biz/?p=486</guid>
         <pubDate>Sat, 08 Feb 2014 08:36:47 +0000</pubDate>
         <content:encoded><![CDATA[<p><img class="alignleft size-medium wp-image-500" style="margin:5px;" alt="Django ile hasta takip uygulamas&#x000131;" src="http://yazilim.soysal.biz/wp-content/uploads/2014/01/hasta-takibi-300x195.jpg" width="300" height="195"/>Uzun zaman önce diş hekimi bir arkadaşıma basit ama onun bütün hasta takip yükünü alacak kadar da detaylı bir yazılım geliştirme sözü verdim. O çoktan bu işin olacağından ümidini yitirdi ama gördüğünüz gibi ben yitirmedim <img src="http://yazilim.soysal.biz/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley"/> </p>
<p>Yazmaya başladım bile hatta. Yazdıkça da, burada paylaşacağım.</p>
<p>Yazının uzun olacağını düşünerek, isimlendirerek bölümlere ayırdım  :</p>
<p><a rel="nofollow" title="Django &#x000130;le Hasta Takip Yaz&#x000131;l&#x000131;m&#x000131; Yapmak &#x002013; Platform" target="_blank" href="http://yazilim.soysal.biz/django-ile-hasta-takip-yazilimi-yapmak-platform/">Bölüm 1 : Django İle Hasta Takip Yazılımı Yapmak &#8211; Platform</a></p>
<p><a rel="nofollow" title="Django &#x000130;le Hasta Takip Yaz&#x000131;l&#x000131;m&#x000131; Yapmak &#x002013; Django Kurulum" target="_blank" href="http://yazilim.soysal.biz/django-ile-hasta-takip-yazilimi-yapmak-django-kurulum/">Bölüm 2 : Django İle Hasta Takip Yazılımı Yapmak – Django Kurulum</a></p>]]></content:encoded>
      </item>
      <item>
         <title>Python Pip Nedir?</title>
         <link>http://yazilim.soysal.biz/python-pip-nedir/</link>
         <description>Aslında çok karmaşık bir konu değil ama bu konuda türkçe kaynak olmadığını görünce yazmak istedim. En kısa tanımı ile pip bir paket yönetim yazılımıdır. python ile yazılmış paketlerin yönetimini pip ile yapabilirsiniz. Diğer paket yönetim programları ( apt-get / aptitude &amp;#8230; ) dururken neden pip kullanayım ki sorusu geliyor tabi insanın aklına. pip &amp;#8216;in en [&amp;#8230;]</description>
         <guid isPermaLink="false">http://yazilim.soysal.biz/?p=477</guid>
         <pubDate>Sun, 05 Jan 2014 12:31:26 +0000</pubDate>
         <content:encoded><![CDATA[<p><img class="alignleft size-medium wp-image-479" style="margin:5px;" alt="Kedi ve Bebek foto&#x00011f;raf&#x000131;" src="http://yazilim.soysal.biz/wp-content/uploads/2014/01/kedi-ve-bebek-300x204.jpg" width="300" height="204"/></p>
<p>Aslında çok karmaşık bir konu değil ama bu konuda türkçe kaynak olmadığını görünce yazmak istedim.</p>
<p>En kısa tanımı ile <strong>pip</strong> bir paket yönetim yazılımıdır. python ile yazılmış paketlerin yönetimini pip ile yapabilirsiniz.</p>
<p>Diğer paket yönetim programları ( apt-get / aptitude &#8230; ) dururken neden pip kullanayım ki sorusu geliyor tabi insanın aklına. pip &#8216;in en önemli avantajı requirements dosyası ile birden çok paketin istenilen versiyonları ile kurulmasıdır.</p>
<p>Örneğin</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">sudo pip install <span style="color:#339933;">-</span>r requirements<span style="color:#339933;">.</span>txt</pre></td></tr></table></div>

<p>komutu ile requirements.txt dosyası ile verilen tüm paketler tek komut ile kurulabilir ve böylece paketler arası sürüm farklarından oluşabilecek olası problemlerin önüne geçilmiş olunur.</p>
<p>Örnek requirements.txt dosyamızın içeriği şu şekilde olabilir :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">Django<span style="color:#339933;">==</span><span style="color:#800080;">1.3</span>
Fabric<span style="color:#339933;">==</span>1<span style="color:#339933;">.</span>2<span style="color:#339933;">.</span>0
Jinja2<span style="color:#339933;">==</span>2<span style="color:#339933;">.</span>5<span style="color:#339933;">.</span>5
PyYAML<span style="color:#339933;">==</span><span style="color:#800080;">3.09</span>
Pygments<span style="color:#339933;">==</span><span style="color:#800080;">1.4</span>
SQLAlchemy<span style="color:#339933;">==</span>0<span style="color:#339933;">.</span>7<span style="color:#339933;">.</span>1
South<span style="color:#339933;">==</span>0<span style="color:#339933;">.</span>7<span style="color:#339933;">.</span>3</pre></td></tr></table></div>

<p>Böylece istediğimiz versiyonları içeren bir geliştirme ortamı oluşturabiliriz.</p>
<p>Eğer pip ile tek bir paket kurmak istersek</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">sudo pip install celery<span style="color:#339933;">==</span>3<span style="color:#339933;">.</span>1<span style="color:#339933;">.</span>7</pre></td></tr></table></div>

<p>veya celery paketinin son versiyonu için</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">sudo pip install celery</pre></td></tr></table></div>

<p>Ayrıca pip virtual-environment ile kullanıldığında tadından yenmez ama o başka bir yazının konusudur.</p>
<p>Kısaca pip budur. Aslında uzunca da budur.</p>
<p>Not: Fotoğrafın konu ile hiç alakası yok ama kedi ve bebek fotoğrafı her zaman ilgi çeker diye düşündüm. &#8220;Yazı bana birşey ifade etmiyor ama fotoğraf güzelmiş&#8221; diyecekler olur belkide. Zaten python pip&#8217;in logosu falanda yok <img src="http://yazilim.soysal.biz/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley"/> </p>]]></content:encoded>
         <category>Genel</category>
      </item>
   </channel>
</rss>
<!-- fe3.yql.bf1.yahoo.com compressed/chunked Thu Oct  1 18:14:47 UTC 2015 -->
