8. MongoDb – Replication

1. MongoDB Replication Konsepti

MongoDB, replikasyon işlemlerini replica set mekanizmasını kullanarak gerçekleştirir. Replica set, bir grup replikanın kendini ana nodela senkronize edebilmesini ve bir nodeun ortadan kaybolduğunda otomatik failover yapabilmesini sağlar. Ayrıca, MongoDB eski bir replikasyon yöntemi olan master-slave replikasyonunu da destekler.

Aslında, hem master-slave hem de replica set mekanizması aynı replikasyon temelini kullanır, ancak replica set, otomatik failover senaryosunu da destekleyerek daha güçlü bir çözüm sunar. Primary node herhangi bir nedenden ötürü düştüğünde, secondary nodelardan biri otomatik olarak primary rolünü üstlenir. Bu nedenle, replika set, master-slave yerine tercih edilir.

Replikasyon konseptinin temel amacı, redundantlığı sağlamak, failover işlemlerini kolaylaştırmak, bakımı kolaylaştırmak ve yük dengelemesini gerçekleştirmektir. Bu replikalar, aynı veri merkezinde veya coğrafi olarak dağılmış güvenli merkezlerde bulunabilir. Replikasyon işlemi asenkron olduğundan, herhangi bir gecikme veya nodelar arasındaki bağlantı kesintisi, primary nodeun performansını etkilemez.

Ancak önemli bir nokta şudur: Secondary nodelar asenkron olarak replike edilir ve son yazma işlemini gerçekleştireceğinin kesin bir garantisi yoktur. Yine de, replika setleri, immediate consistency gerektiren okumalar dışında oldukça verimli çalışır

Replication Kullanım Durumları ve Kısıtlamaları

Kullanım Durumları

  1. Redundancy : Replicated nodelar primary node ile sync kalır. Bu replikasyonlar aynı data centerda olabileceği gibi coğrafi olarak yaygın da olabilir. Çünkü replikasyon asynctir ve network latency veya nodelar arası partition problemi primary node’un performansını etkilemeyecektir. Bunun sonucunda dataların yedekleri oluşacağından Redundancy sağlanmış olacaktır.
  2. Failover : Sistemimizin highly available olmasını isteriz. Bu da redundant nodelar ve acil durum anında nodeların kendini switch edebilmesi ile yani otomatik failolverla mümkündür ki bunu mongoDBde replica sets otomatik yapmaktadır.
  3. Yüklü Operasyon Dağılımı : Sistemde yüklü operasyonları primary dışında secondarylere yönlendirip performans artırabiliriz. Ya da indexing işlemleri için secondary kullanıp primary ile switch edebiliriz.
  4. Read yükünü dağıtma : Read yükünün dağılımı için replikation kullanılabilir.

 Kısıtlar

  Ayrılmış donanım verilen yükü işleyemeyebilir. Bu noktada data working setler önemlidir. Working set mevcut ram’den yüksekse, readleri secondarylere göndermek performansı umduğunuz kadar attırmayacaktır. Performans diskin handle edebileceği saniye başına düşen I/O  operasyonu ile sınırlıdır (IOPS). Replikalardan okuma yapmak total IOPS’u yükseltir. Ancak 100’den 200 IOPS’a gitmek performans problemini çözemeyebilir. Bu noktada sharding iyi bir seçenek olabilir.

Writeların readlere oranı belli bir oranı geçerse ; Buradaki ana mantık primary, üzerindeki writeların hepsini secondarye de geçirmek zorundadır. Bu sebeple çok fazla read yükü olan bir secondary aslında writeları da işleyecektir. Bu da replication processini düşürebilir ve read performansı da düşebilir.

 Secondaryler primary nodelara async replika olur. Dolayısıyla, her zaman latest data döneceğinin garantisi yoktur.

Replika setler  immediate consistency gerektirmeyen read scalingler için idealdir. Ancak her durumda yardımcı olmazlar. Conditionlarınız değişirse sharding, augmented hardware ya da ikisinin kombinasyonları gibi yapılara dönmek gerekir.

MongoDb v2.1da maximum 12 server alabilir 7 si oy kullanabilir. MongoDb v3.0 da maximum 50 node olabilir 7si oy kullanabilir. Daha fazla ölceklenmeye ihtiyaç duyulduğu takdirde master-slave replikasyonuna dönülmesi gerekir. Ancak otomatik failoverdan feragat etmek istemiyorsanız bu sayıların güncel mongodb versiyonldaki karşılığı kadar ölçeklenebilirsiniz. Ya da sharded cluster.

Aşağıda replika setteki nodelara atanabilecek bazı özellikler mevcuttur.

  • arbiterOnly: Bu özellik, bir nodeun yalnızca oy kullanmak üzere tasarlandığını belirtir. Bu node, oy verirken veri replikasyonu yapmaz.
  • priority: Bu özellik, bir nodeun replika set içinde hangi önceliğe sahip olduğunu belirtir. Daha yüksek bir öncelik, bu nodeun primary olma olasılığını artırır.
  • buildIndexes: Bu özellik, bir nodeun replika setine eklenirken indeksleri otomatik olarak oluşturup oluşturmayacağını belirtir.
  • votes: Bu özellik, bir nodeun oy sayısını belirler. İstenen belli durumlarda bir node birden fazla oy kullanabilir. Oylar, bir nodeun primary seçilme olasılığını etkiler.
  • tags: Bu özellik , replika setindeki nodelara etiketler eklemeyi sağlar. Bu etiketler, belirli koşullarda yazma ve okuma işlemlerini yönlendirmek için kullanılabilir.
  • slaveDelay: Bu özellik, bir secondary nodeunun geriye doğru bir gecikme ile replike edilmesini sağlar. Bu, belirli bir süre boyunca verilerin geriden takip edilmesini sağlar, böylece belirli bir noktada veri durumunu geri getirebilir replikationı backup olarak da kullanabilirsiniz.
2. Replica Sets Konsepti

Replika setlerinde kurabileceğiniz minimum cluster, 3 node’dan oluşur. 3 nodelu bir replika sette, 1 node primary, 2 node secondary olabilir veya 1 node primary, 1 node secondary ve sadece oy kullanmak amacıyla olan bir arbiter nodelu da olabilir. Çünkü daha az node olduğunda, primary node çökerse seçim (election) için çoğunluğu elde edemeyiz. Bu cluster’da, primary yazmaları kabul eder. Eğer bir nedenden dolayı primary düşerse, yeni bir primary seçimi için replika setlerinde otomatik bir seçim (election) gerçekleşir. Ancak replika setlerinin çoğunluğu bir şekilde ulaşılamaz durumdaysa, replika seti primary seçemediği için yazmaları kabul etmez ve kalan tüm üyeler yalnızca okuma işlemlerini gerçekleştirebilir.

Normal şartlarda, MongoDB, secondary node’a sorgu atmayı engeller çünkü bu veri, primary’ye göre daha güncel olmayacaktır.Ancak isterseniz, bir slave’in konsoluna girip rs.slaveOk(); komutunu kullanarak bu özelliği etkinleştirebilirsiniz explisit olarak secondary node’dan okumalara izin verebilirsiniz.

Eğer secondary node bir nedenden dolayı devre dışı kalırsa, kalan nodelar kendi statelerinde devam eder ve işlemlerine devam eder. Sistem durumu değişiklik olmaz. Primary node’u devre dışı bırakırsanız bu durumda secondary node, primary’nin heartbeatini alamaz, primarynin çöktüğü anlar ve kendini primary olarak seçer. Election, yukarıda belirttiğimiz gibi, secondary nodeların çoğunun çalışır durumda olması ve birbirleriyle iletişim kurabilmeleri durumunda mümkündür. Eğer eski primary tekrar faaliyete geçerse, tekrar replika setine otomatik olarak secondary olarak katılır.

Primary, yazmaları kabul eden tek üyedir. Eğer secondary üyelerin çoğunluğu ulaşılamaz durumdaysa, primary yazmaları kabul etmez ve tüm kalan nodelar yalnızca okuma işlemlerini gerçekleştirebilir.

3. MongoDb Replication Nasıl Çalışır?

Replika setler oplog ve heartbeat denen 2 konsept ile çalışır. Oplog, Data replikasyonunu sağlayan yapıdır heartbeat ise Cluster healthini monitor eder ve failover i tetikler.

3.1 Oplog

Oplog, bir capped collection’dır ve veritabanındaki tüm değişiklikleri kaydeder. Bir write işlemi, primary nodea ulaştığında, bu işlemi yeniden oluşturmak için yeterli bilgi oplog’ta saklanır. Write işlemi secondary nodea ulaştığında, secondary node bunu kendi oplog’unda depolar. Her oplog time stampiyle kaydedilir ve secondary nodelar, bu time stampi kullanarak en son uyguladıkları girişi takip etmek için bunu kullanır.

Primary’e bir write yapıldığında oluşan süreç:

  1. Write, primary nodea ulaşır.
  2. Write, primary nodu tarafından işlenir.
  3. Write’i yeniden oluşturabilecek bilgiler, primary oplog’una yazılır.
  4. Secondary nodelar, primary oplog’unu replike eder ve write’ı kendi taraflarına alıp kendi oplog’larına yazarlar.

Secondary nodelar, kendini güncellemeden önce:

  1. Kendi oplog’unun time stampine bakar.
  2. Secondary, primary’nin oplog’undaki kendi oplog’unun time stampinden büyük olanları sorgular.
  3. Bu verileri alır, yazar ve oplog’u günceller.

Secondary nodelar, primary’nin oplog’undaki güncellemeleri ve yeni girişleri hemen alabilmek için “long polling” uygular. Yani secondary, primary’ye uzun süreli bir istek gönderir. Primary bir değişiklik aldığında, bekleyen isteklere yanıt verir ve bu sayede secondary’ler güncel olur.

Secondary, bir sebep dolayısıyla primary’nin gerisinde kaldığında, replication lag’ını görebilmek için secondary’nin oplog’u kullanılabilir.

3.2 Heartbeat and failover

Heartbeat, MongoDB’de election ve failover süreçlerini kolaylaştırır. Normal şartlarda, her replika set üyesi 2 saniyede bir birbirine ping atar ve sistem healthini garanti eder. rs.status() komutunu çalıştırdığınızda, her node’un son heartbeat’ini health ile beraber görebilirsiniz (1 health, 0 unresponsive demektir). Heartbeat, election ve failover süreçlerini kolaylaştırır. Normal şartlarda heartbeat sinyali primary node (hepsi) tarafından oluşturulur ve tüm secondary’ler tarafından alınır. Eğer bir secondary, belirli bir süre boyunca primary’den heartbeat sinyali alamazsa, kendi aralarında yeni bir primary election’ına başlarlar

Her replika set, yalnızca bir tane primary node olduğunu garanti etmelidir. Ancak bu yalnızca nodeların çoğunluğu ayaktayken mümkündür. Örneğin, 3 nodelu bir clusterda secondary node’unuz ölürse, nodeların çoğunluğu hala ayaktadır ve replika setin statüsü değişmez, sadece secondary tekrar ayağa kalkarsa sisteme dahil olur.

Eğer primary node ölürse ve yine nodeların çoğu ayakta ise, bir secondary otomatik olarak primary olarak atanır. Birden fazla secondary varsa, en güncel olanı primary olarak seçilecektir.

Ancak başka bir senaryo da mevcut. Diyelim ki 2 secondary birden sistemden çıktı. Primary hala ayakta ama nodeların çoğunluğu artık sisteme dahil değil. Bu durumda primary logunda şu gibi bir mesaj göreceksiniz:

[rsMgr] can't see a majority of the set, relinquishing primary
[rsMgr] replSet relinquishing primary state
[rsMgr] replSet SECONDARY
[rsMgr] replSet closing client sockets after relinquishing primary

Nodeların çoğunluğu olmadığı durumda primary, kendini secondary olarak atanır. Bu durumun sebebi, heartbeat’lerin diğer secondary’lere network partition’dan dolayı gitmemesi ihtimali ve bu secondary’lerin kendi arasında bir primary seçip 2 primaryli bir cluster oluşturma ihtimalini engellemektir.

MongoDB’de single document işlemler atomiktir, ancak multiple document işlemler atomik değildir.                         

Replication versus Backup

Replicationlar redundancy sağlasa da aslında backup değildir. Bir backup database’in belli belli aralıklarla snapshot’ını tutarken replikaların up to date olması beklenir. Backuplar logical bir fail olduğunda ve data kaybı, yanlış bir data oluştuğunda geriye dönebilmek için oradadır ancak replicationda bu yanlış data modifikasyonu replikalara da syncn olacaktır.

4. Commit ve Rollback Konsepti

Bir diğer önemli konu da replika setlerdeki commit ve rollback konseptidir. Mongodbde yaptığınız writelar replika setteki nodeların çoğunluğuna geçmediği sürece commit olmuş sayılmaz. Sebebini bir örnek üzerinden anlatmam gerekirse, bir primarye write yaptığımızı ve replikaların çoğunlugunun bir sebepten bu writei alamadığını düşünelim. Daha sonra secondarynin aniden primarye promote olduğunu düşünelim daha sonra da düşen primary sisteme tekrar secondary olarak dahil olsun. Öyle bir noktaya geliriz ki eski primarynin oplogundaki kayıt yeni primarynin oplogunda bulunmaz. Yani secondary primaryde olmayan bir dataya sahip ve daha güncel bir hale gelir. Bu da rollback durumunu tetikler.

Rollback durumunda clusterin çoğunluğuna geçmeyen writelar geri alınır ve secondarylerin oploglarından ve collectiondan silinir. Bu geri alınan writelar ise ilgili bode’un datapathinde bir rollbck subdirectoryde tutulur. İhtihaç duyulduğu durumda bu bsondump kullanarak bson filelarını inceyelebilir ve mongorestore ile manuel restore yapılabilir.

Uygulamanız ekstra yazma latencysini tolere edebiliyorsa, verilerinizin her yazma işleminde (veya belki   her birkaç yazma işleminden sonra) nodeların çoğunluğuna kopyalandığından emin olmak için write concernleri kullanabilirsiniz.

5. Recovery

Primary kill olursa secondary heartbeat alamaz ve secondary kendini primary olarak aday gösterir. Nodeların çoğu ayaktaysa ve birbirlerine ping atabiliyorlarsa election devam eder. Primary doğru bir şekilde shut down olup tekar ayağa kalktıgında sisteme secondary olarak dahil olur.

Recovery, replika clusteri bir failure sonrasında orijinal stateine geri getirme sürecidir. İki genel başarısızlık kategorisi ele alınmalıdır. İlk olarak, clean failure olarak adlandırılan durum, belirli bir node’un veri dosyalarının hala sağlam olduğu varsayılabilir. Bu duruma bir örnek, bir network partitioningtir. Bir nodeun clsuterının geri kalanına bağlantılarını kaybettiği bir durumda, sadece bağlantının yeniden sağlanmasını beklemeniz yeterli olacaktır ve bölünmüş node, cluster üyesi olarak yeniden devreye girecektir. Benzer bir durum, belirli bir nodeun mongod sürecinin herhangi bir nedenle sonlandırılması ancak temiz bir şekilde çevrimiçi getirilebilmesidir. Yine, süreç yeniden başlatıldığında clustera yeniden katılabilir.

İkinci tür ise categorical failure  olarak adlandırılır; burada bir nodeun veri dosyaları ya artık mevcut değildir ya da bozulmuş olduğu varsayılır. Journaling etkin olmayan mongod sürecinin temiz olmayan kapanışları ve sabit disk çökmesi, bu tür bir başarısızlığın örnekleridir. Kategorik olarak başarısız olan bir nodeu kurtarmanın tek yolu, veri dosyalarını tamamen yeniden senkronize etmek veya yakın bir yedeğe geri yüklemektir.