MongoDB'de sharding, bir koleksiyonun verisini birden fazla sunucuya (shard) bölerek dağıtma yöntemidir. Hangi belgenin hangi shard'a gideceğini shard key belirler: koleksiyonu sh.shardCollection("veritabani.koleksiyon", { alan: 1 }) veya { alan: "hashed" } ile shard'larsınız. İyi bir shard key yüksek kardinaliteye sahip, değerleri dengeli dağılan, sürekli artmayan ve en sık sorgularınızda yer alan bir alandır (ya da alan birleşimidir).
Bu yazı sharded kümenin bileşenlerini, ranged ve hashed sharding farkını, shard key seçerken bakılacak ölçütleri, benzersizlik kısıtlarını ve shard key'i sonradan değiştirme yollarını anlatıyor. Sharding, replica set üzerine kurulur; temel kavramlar için önce replica set kurulumu yazısını okumanızı öneririz. Serinin tamamı MongoDB öğrenme rehberinde yer alıyor.
Neden Sharding? Dikey ve Yatay Ölçekleme
Büyük veri kümeleri veya yüksek işlem hacmi tek bir sunucunun sınırlarını zorlar. Yüksek sorgu oranları işlemciyi tüketebilir; çalışma kümesi (working set) RAM'den büyük olduğunda diskler baskı altına girer. Bu büyümeye iki yolla cevap verilir. Dikey ölçekleme tek sunucuya daha güçlü işlemci, daha fazla RAM veya disk eklemektir; mevcut donanımın ve bulut sağlayıcılarının sunduğu yapılandırmalar bunun pratik bir üst sınırını çizer. Yatay ölçekleme ise veriyi ve yükü birden fazla sunucuya bölmek, gerektikçe sunucu eklemektir. Her makine işin bir bölümünü üstlenir; bedeli altyapı ve bakımdaki artan karmaşıklıktır.
Sharding'in üç somut kazancı vardır. Okuma ve yazma yükü shard'lara dağılır ve shard ekledikçe kapasite artar. Depolama kapasitesi shard sayısıyla birlikte büyür. Shard'lar ve config sunucuları replica set olarak çalıştığı için erişilebilirlik artar; bir shard tamamen erişilemez olsa bile küme diğer shard'lardaki veriler için kısmi okuma ve yazmaya devam edebilir.
Chunk, Balancer ve Veri Dağılımı
MongoDB shard edilmiş veriyi chunk adı verilen parçalara böler. Her chunk, shard key değerleri üzerinde alt sınırı dahil, üst sınırı hariç bir aralığı kapsar. Arka planda çalışan balancer, shard'lar arasında dengeli bir dağılım sağlamak için aralıkları shard'lar arasında taşır. Sharding koleksiyon düzeyinde yapılır: aynı veritabanında shard edilmiş ve edilmemiş koleksiyonlar birlikte bulunabilir. Shard edilmemiş bir koleksiyon herhangi bir shard'da durabilir ama shard'lar arasında bölünmez.
Bir belgede shard key alanlarından biri eksik olabilir. Belgelere göre eksik alanlar, belgeler shard'lara dağıtılırken null değer gibi ele alınır ve bu belgeler null shard key değerleriyle aynı chunk aralığında yaşar; sorgu yönlendirmede ise böyle ele alınmaz.
Bir Koleksiyonu Shard Etmek
Koleksiyonu shard etmek için tam ad alanını ("veritabani.koleksiyon") ve shard key belgesini verirsiniz. Değer 1 ise ranged (aralık tabanlı), "hashed" ise hashed sharding uygulanır. MongoDB 6.0'dan itibaren bunun için önce sh.enableSharding() çalıştırmanız gerekmez.
// ranged sharding: musteriId ve olusturma alanlarına göre
sh.shardCollection("magaza.siparisler", { musteriId: 1, olusturma: 1 })
// hashed sharding: tek alan
sh.shardCollection("magaza.olaylar", { cihazId: "hashed" })
// bileşik hashed shard key: ön alan aralık, son alan hash
sh.shardCollection("magaza.loglar", { bolge: 1, kayitNo: "hashed" })Shard edilen koleksiyonun shard key ile başlayan bir indeksi olmalıdır. Koleksiyon boşsa ve uygun indeks yoksa sh.shardCollection() bu indeksi kendisi oluşturur. Koleksiyon doluysa indeksi önce sizin oluşturmanız gerekir. Shard key'i destekleyen tek gizlenmemiş indeksi silemez veya gizleyemezsiniz. İndeks oluşturma ayrıntıları için MongoDB index oluşturma ve bileşik indeksler için compound index ve ESR kuralı yazılarına bakın.
// dolu bir koleksiyonda önce indeks, sonra sharding
db.siparisler.createIndex({ musteriId: 1, olusturma: 1 })
sh.shardCollection("magaza.siparisler", { musteriId: 1, olusturma: 1 })Hashed ve Ranged Sharding Karşılaştırması

Ranged sharding veriyi shard key değerlerine göre aralıklara böler. Birbirine yakın değerler büyük olasılıkla aynı chunk'ta durur; bu da mongos'un aralık sorgularını yalnızca ilgili shard'lara yönlendirmesini (targeted operation) sağlar. Verimliliği tamamen seçilen shard key'e bağlıdır; kötü seçilmiş bir key dengesiz dağılım ve darboğaz üretir.
Hashed sharding shard key alanının hash değerini hesaplar ve chunk aralıklarını bu hash değerleri üzerinden belirler. Hash'i uygulamanın hesaplaması gerekmez; MongoDB sorguları çözerken bunu kendisi yapar. Yakın değerler farklı chunk'lara dağıldığı için özellikle sürekli artan alanlarda çok daha dengeli bir dağılım elde edilir. Bedeli, shard key üzerindeki aralık sorgularının artık tek bir shard'a hedeflenememesi ve kümenin tamamına yayın (broadcast) yapılmasıdır; eşitlik sorguları ise yine tek bir shard'a yönlendirilebilir.
| Ölçüt | Ranged | Hashed |
|---|---|---|
| Sürekli artan alan (ObjectId, zaman damgası) | Yeni yazmalar tek chunk'a yığılır | Yazmalar dengeli dağılır |
| Shard key üzerinde aralık sorgusu | İlgili shard'lara hedeflenir | Çoğunlukla tüm shard'lara yayılır |
| Eşitlik sorgusu | Hedeflenir | Hedeflenir |
| Benzersiz (unique) shard key | Mümkün | Hashed indekste unique tanımlanamaz |
| Zone kullanımı | Doğrudan | Bileşik hashed key'in hash olmayan ön alanlarıyla |
Örnek: Bir Sipariş Koleksiyonu için Karar
Bir e-ticaret uygulamasında siparisler koleksiyonunu düşünelim. Belgelerde _id (ObjectId), musteriId, durum ve olusturma tarihi var. En sık sorgu "bir müşterinin siparişlerini tarihe göre listele" şeklinde.
{ durum: 1 }: Yalnızca birkaç farklı değer (beklemede, kargoda, teslim) olduğu için kardinalitesi düşük ve değerlerin dağılımı dengesizdir. Uygun değil.{ olusturma: 1 }: Sürekli artar; tüm yeni siparişlerMaxKeychunk'ına gider. Uygun değil.{ _id: "hashed" }: Yazmaları dengeli dağıtır ama "bir müşterinin siparişleri" sorgusu shard key içermediği için tüm shard'lara yayılır.{ musteriId: 1, olusturma: 1 }: Müşteri sayısı yüksekse kardinalite yüksektir, sorgu shard key'in ön ekini içerdiği için hedeflenir ve tek bir müşterinin tarih aralığı da aynı shard'da kalır. Birkaç müşteri siparişlerin çok büyük bölümünü oluşturuyorsa sıklık sorunu doğabileceğini akılda tutun.
Bu örnekte son seçenek sorgu kalıbı ile dağılım arasında iyi bir denge kurar. Kararı vermeden önce gerçek veriniz üzerinde analyzeShardKey ile ölçüm yapmak, tahmine dayanmaktan daha güvenilirdir.
Benzersizlik ve Sharding
Sharded bir kümede benzersizlik kısıtı shard'lar arasında ancak unique indeks shard key üzerindeyse ya da shard key'i ön ek olarak içeriyorsa uygulanır. Ranged sharding kullanan bir koleksiyonda yalnızca shard key üzerindeki indeks, shard key'in ön ek olduğu bileşik indeks veya varsayılan _id indeksi unique olabilir. Hashed indekste ise unique kısıtı tanımlanamaz. sh.shardCollection() çağrısında unique: true verirseniz koleksiyonun shard key üzerinde unique bir indeksi olmalıdır; dolu bir koleksiyonda bu indeksi önceden oluşturmanız gerekir ve shard key'i destekleyen indeks unique değilse komut hata döndürür. Benzersiz indeks hataları için E11000 duplicate key ve unique, partial ve sparse index yazılarına bakın.
Zone'lar Hakkında Kısa Not
Birden fazla veri merkezine yayılan kümelerde zone'lar veri yerelliğini iyileştirir. Her zone bir veya daha fazla shard key aralığını kapsar; aralık alt sınırı dahil, üst sınırı hariçtir. Zone aralıkları shard key alanlarıyla tanımlanır, bileşik key'de aralığın key'in ön ekini içermesi gerekir. Belgeler, zone kullanmayı düşünüyorsanız bunu shard key seçerken hesaba katmanızı önerir; zone'ları ve aralıklarını boş ya da henüz var olmayan bir koleksiyonu shard'lamadan önce tanımlamak, zone tabanlı kurulumu hızlandırır.
MongoDB 9.0 Notları
MongoDB 9.0, mongosh için sh.shardDrainingStatus() ve sh.getTransitionToDedicatedConfigServerStatus() yöntemlerini ekler, checkMetadataConsistency komutuna yeni tutarsızlık türleri ve bir chunk kontrol eşiği seçeneği getirir. Sürüm notlarındaki açık bir bilinen soruna göre sharded kümedeki düğümler her config sunucusuna en az ShardingTaskExecutorPoolMinSize kadar bağlantı açar ve bu, config sunucularının bağlantılarını tüketebilir. Bu parametreyi 1'den büyük ayarladıysanız, ayrı (dedicated) config sunucusu kullanan kümelerde etkilenen bir 9.0 sürümüne geçmeden önce ShardingTaskExecutorPoolMinSizeForConfigServers değerini 1 yapmanız önerilir. Tüm değişiklikler için MongoDB 9.0 yenilikleri yazısına bakın.
Sık Yapılan Hatalar

- Henüz ihtiyaç yokken sharding'e geçmek. Belgeler sharded kümenin altyapı gereksinimlerinin ve karmaşıklığının dikkatli planlama ve bakım gerektirdiğini vurgular; önce indeksleri ve sorguları iyileştirmek çoğu zaman yeterlidir.
- Sürekli artan bir alanı (tarih, sayaç, ObjectId) ranged shard key olarak seçmek.
- Düşük kardinaliteli bir alanı tek başına shard key yapmak.
- Uygulamayı
mongosyerine doğrudan bir shard'a bağlamak. - En sık sorgularda shard key'i kullanmayıp her sorgunun tüm shard'lara yayılmasına neden olmak.
- Hashed shard key üzerinde benzersizlik beklemek.
Sık Sorulan Sorular
Sharding için kaç sunucu gerekir?
Belgelerdeki üretim önerisi; üç üyeli bir config sunucusu replica set'i, her biri üç üyeli replica set olan en az iki shard ve bir veya daha fazla mongos'tur. Yani üretim için tek sunucuda sharding anlamlı değildir.
Shard key değerini sorgularda hash'lemem gerekir mi?
Hayır. Hashed indeks kullanan sorgularda MongoDB hash değerini kendisi hesaplar; uygulamanız normal değerle sorgu yazar.
Shard key'i yanlış seçersem ne olur?
Belgeler kötü bir shard key'in tipik belirtilerini jumbo chunk'lar, dengesiz yük dağılımı ve düşen sorgu performansı olarak sıralar. Düzeltmek için key'i inceltebilir veya koleksiyonu yeniden shard'layabilirsiniz; ikisi de planlama ve kaynak gerektirir.
Shard edilmiş bir koleksiyonun shard key'ini nasıl görürüm?
Belgelere göre db.printShardingStatus() yöntemi koleksiyonun kullandığı shard key'i gösterir.
Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.
İlgili içerikler: MongoDB öğrenme rehberi · Replica set kurulumu · Write concern ve read concern · Index oluşturma · Compound index ve ESR · Production notları
