Modern microservice mimarilerinde ve yüksek ölçekli sistemlerde veri yönetimi için, bir işlemin hızı ile o işlemin ne kadar güvenli kaydedildiği arasındaki dengeyi kurmak, yazılım mimarları için en kritik kararlardan biridir. MongoDB bize bu dengeyi dinamik olarak yönetebilmemiz için iki temel kaldıraç sunar: Read Preferences ve Write Concerns.
MongoDB’nin dağıtık mimarisinde veri bütünlüğünü yöneten Read Preference ve Write Concern parametreleri, bir cluster üzerindeki operasyonel davranışları belirleyen temel konfigürasyonlardır. Write Concern, bir yazma işleminin başarılı sayılabilmesi için verinin kaç tane replica set üyesine (örneğin; w: 1, w: majority veya journaled) kalıcı olarak işlenmesi gerektiğini tanımlayarak dayanıklılık seviyesini belirler. Öte yandan Read Preference, yapılan sorguların topolojideki hangi düğümlere (primary, secondary, nearest vb.) yönlendirileceğini kontrol eder. Bu ise sistemin eventual consistency veya strong consistency modellerinden hangisine göre çalışacağını doğrudan etkiler.
Bu özellikler veri tutarlılığı hassasiyeti olan her ölçekteki yapıda kullanılır. Örneğin e-ticaret sistemlerinde ödeme kayıtları ve stok güncellemelerinde “writeConcern: majority” kullanıldığında verinin en az iki veya daha fazla düğüme yazıldığından emin olurlar. Canlı sistemi yormamak için “readPreference: secondary” kullanarak rapor sorgularını ana sunucudan değil yedeklerden çektirebilirsiniz.
Bu mekanizmaların doğru yapılandırılması, yüksek trafikli sistemlerde gecikme sürelerini minimize eder, aynı zamanda veri kaybı riskini de minimize ederek sistemin hata toleransını optimize eder.
Read Preferences
Read preferences, istemci tarafındaki sorguların bir Replica Set içerisindeki hangi düğüme (primary veya secondary) yönlendirileceğini belirleyen mekanizmadır. Varsayılan olarak tüm okuma işlemleri en güncel veriyi garanti eden primary düğümden yapılır. Ancak performans ihtiyacına göre sorgular dilerseniz en yakın düğüme (nearest) veya yedek düğüm (secondary) olacak şekilde yönlendirilebilir.
Bir veri primary sunucuya yazıldıktan sonra secondary sunuculara kopyalanması milisaniyeler sürer. O veriyi primary sunucusundan okursanız az önce yazdığınız veriyi orada bulursunuz. Secondary tarafından okursanız veri o an henüz kopyalanmamış olabilir, yani kullanıcı profil bilgisini güncellediğinde eski bilgiyi kısa bir süre de olsa görme ihtimali var. Bankacılıkta primary şarttır fakat bir gönderinin kaç beğeni aldığı bilgisini birkaç saniye gecikmeli görseniz sorun olmaz, bu sebeple de secondary kullanılabilir.

Server Selection Algorithm
MongoDB Driver, hangi replica set üyesinin kullanılacağını veya birden fazla mongos örneğine (instance) bağlı olunduğunda hangi örneğinin kullanılacağını seçmek için bir sunucu seçim algoritması kullanır. Ek bir işlem gerektirmez. Kod bölümünde verinin “secondary” bölümünden okunacağını belirttiğinizde (ReadPreference = Secondary), geri kalan tüm bu ping ölçme, sepet oluşturma ve rastgele seçme işini Driver yerinize saniyeler içinde defalarca yapar.
Bunun ne olduğunu biraz daha açalım. MongoDB Driver akıllı seçim stratejisine sahiptir. Elinizde 3 tane sunucu var ve kod tarafında “ReadPreference = Secondary” kullanılmış. Burada MongoDB driver hangi secondary sunucusuna gideceğine nasıl karar veriyor? Hepsine birden mi soruyor yoksa birini mi seçiyor? Bunu kendi algoritmasıyla yapıyor.
Driver arka planda sürekli olarak sunucuları kontrol eder. Sonra bu düzende karar verir:
- Önce cluster altındaki tüm sunucuların listesini tutar
- Sonra her birine düzenli aralıklarla “ping” atar. Ping sonucuuna göre Secondary A 10ms, Secondary B 12ms, Secondary C 30ms çıktığını varsayalım. Bu listedeki en hızlıyı bulur.
- En hızlı sürenin üzerine varsayılan olarak 15ms ekler. Yani 10ms (en hızlı seçim) + 15ms (tolerans) = 25ms kabul eder.
- Süresi 25ms ve altında olan tüm sunucuları bir sepete koyar. Bizim örneğimizde sepete Secondary A ve Secondary B girer. Diğerleri elenir.
- Son adımda ise A veya B sunuculardan birine rastgele sorguyu gönderir.
Bu konuyu detaylı öğrenmek için: https://www.mongodb.com/docs/manual/core/read-preference-mechanics/
Write Concern
Dağıtık bir sistemde yazma işlemi sadece diske yazmak değildir, aynı zamanda verinin replika set üyelerine kopyalanması sürecidir. Write Concern, bir yazma işleminin başarılı sayılabilmesi için kaç tane sunucunun bu veriyi aldığını teyit (acknowledge) etmesi gerektiğini belirleyen ayardır. w (sunucu sayısı) ve wtimeout (bekleme süresi) parametreleri ile yönetilir.
MongoDB bu veriyi alır ve belirlediğiniz w değerine ulaşana kadar bekler. İstenen sayıya ulaşıldığında driver tarafına başarılı (acknowledged) sinyali gönderir.

Write concern seçenekleri:
w: 0 (Unacknowledged): Bu seviyede driver, veriyi soket üzerinden gönderdiği anda işlem bitti kabul eder. Herhangi bir ACK mesajı beklemez. TCP paketi gönderilir ve yeniden koda döner. Burada bir hata varsa (örneğin disk dolu gibi) uygulama bundan haberdar olmaz.
w: 1 (Acknowledged – Default): MongoDB’nin varsayılan ayarıdır. Yazma işleminin sadece primary düğüm tarafından onaylanması yeterlidir.
w: majority (Data Durability): En güvenli standart seviyedir. Verinin replica set üyelerinin salt çoğunluğu (örneğin 3 düğümden 2 tanesi gibi) tarafından onaylanmasını bekler. Primary veriyi yazar ve ardından secondary düğümlere yayar. Çoğunluktaki düğümler veriyi aldıklarını primary tarafına mesaj bildirene kadar primary bölümü driver için ACK yanıtı dönmez. Bu seviye verinin bir failover durumunda kaybolmayacağını garanti eder. Finansal işlemler, envanter yönetimi, domain kayıt süreçleri gibi veri kaybının kabul edilemez olduğu kritik operasyonlar için idealdir.
w: (Custom Replication Count): Belirli bir sayıdaki düğümün onayını beklemek için kullanılır. (Örn: w: 2, w: 3). Primary dahil toplamda belirtilen sayı kadar düğümün veriyi onaylaması gerekir. Eğer cluster altındaki aktif düğüm sayısı verdiğiniz sayıdan azsa (örneğin 3 sunucu var ama siz w: 4 dediniz) işlem hata verir.
w: “tag” (Tag-Aware): Replica set üyelerine atanan etiketlere göre çalışma prensibidir. Örneğin sunucularınızı coğrafi olarak etiketlediniz ({ “dc”: “Gebze” }). w: “GebzeDC” gibi bir kural koyarak verinin mutlaka Gebze’deki düğümlere yazıldığından emin olabilirsiniz. Yasal mevzuat gereği belirli lokasyonlara ulaşma garantisi vermek zorunda kalabilirsiniz.
MongoDB driver bölümünde örnek bir bağlantı:
// Majority atandı ve 500ms timeout var
var secureWrite = new WriteConcern(WriteConcern.WValue.Majority)
{
WTimeout = TimeSpan.FromMilliseconds(500)
};
var settings = new MongoClientSettings();
settings.WriteConcern = secureWrite;Dilerseniz bunların yanında Journal parametresi vererek günlükleme yapabilirsiniz. “j: true” ayarı RAM’den diskteki bir log dosyasına veriyi yazar.
MongoDB size sabit bir veritabanı kuralı dayatmaz, aksine read ve write işlemleri için gelişmiş bir yapılandırma sunuyor. Bir yazılım mimarının görevi uygulamanın her bir fonksiyonu için en doğru dengeyi seçerek sistemi hem hızlı hem de güvenilir kılmaktır.


Yorum bırakın