İki arkadaş küçük bir uygulama çıkarıyor: adı Chirp olsun. İnsanlar kaydoluyor, kısa gönderiler paylaşıyor, birbirini izliyor. Açılış günü birkaç yüz kişi var ve bütün düzen tek bir uygulama sunucusu ile tek bir veritabanı makinesinde dönüyor. Gönder düğmesine basınca yazı anında kaydoluyor, profil bir tıkla açılıyor. Burası mahalle bakkalı gibi: tek kasa, kısa kuyruk, herkes mutlu. Ben bu tabloyu seviyorum çünkü ölçek denen derdin önce yokluğunu gösteriyor.
Sonra kullanıcı sayısı artıyor: iki yüz kişi iki bin oluyor, sonra on binler geliyor. Burada iki işi ayıralım. Biri okuma: birinin profilini açmak, gönderileri listelemek. Öteki yazma: yeni gönderi eklemek, birini izlemek. Okuma da yazma da aynı makineye yığılınca kasa kuyruğu uzuyor. İlk akla gelen çare makineyi büyütmek: daha güçlü işlemci, daha geniş hafıza. Ama bunun bir duvarı var. Bir noktada daha büyük makine bulunmuyor ya da faturası can yakıyor. Sharding sorusu tam bu duvarda doğuyor.
Sharding, tabloyu dilimleyip her dilimi ayrı bir makineye koymak demek. Kullanıcılar tablosu dört parçaya bölünüyor, her parça farklı makinede duruyor. Ön yüze bir de trafik polisi ekleniyor: yönlendirme katmanı. Hangi sorunun hangi makineye gideceğini o biliyor. Benzetme gözümde canlanıyor: tek bakkal yerine dört semt şubesi açıyorsun, kapıya da müşteriyi doğru şubeye yollayan bir santral koyuyorsun. Düzenin adı bu kadar basit, hüneri ayrıntıda gizli.
Ayrıntıların ilki parça anahtarı: veriyi dilimlere dağıtan sütun. Chirp ekibi kullanıcı kimliğini anahtar yapıyor. Peki anahtarı sonradan değiştirmek istersen ne olur? Ülkeye göre dağıtmaya karar verdiğini düşün. Her dilimdeki her satırı tek tek elden geçirmen, herkesin ülkesini bulup doğru dilime taşıman gerekir. Devasa bir taşıma operasyonu. O yüzden anahtar tercihi baştan ciddi düşünülür. MongoDB belgeleri de aynı uyarıyı yapıyor: anahtar tercihi için değer çeşitliliğine, değer sıklığına ve sürekli artıp artmadığına bakmak gerekiyor.
İyi anahtarın huylarını sayalım. Bir: çok farklı değeri olmalı. Ülkeye göre dilimlersen elinde iki yüz değer var, altmış dört dilimi besleyemezsin. Kalabalık bölgelere düşen dilimler terler, sessiz yerlere düşen dilim boş oturur. Kullanıcı kimliğinde ise milyonlarca farklı değer var, istediğin kadar dilime yayarsın. İki: yeni gelenler dilimlere dengeli düşmeli. Kayıt yılına göre dilimlersen bu yılki dilim şişer, geçen yılların dilimleri sinek avlar. Kimliğe göre dilimlersen yeni üyeler sırayla sıfır, bir, iki, üç diye gider ve yük kendiliğinden dengelenir.
Dağıtımın ilk yolu hash: kimliği bir hash işlevinden geçir, çıkan sayıyı dilim sayısına böl, kalana bak. Leo örneğin sıfırıncı dilime düşüyor. Bu kuralın güzelliği şurada: yalnız kimlik ve dilim sayısı yetiyor. Her makine hesabı tek başına yapıyor, kimseye danışmıyor. Benzetme niyetine çamaşır sepetleri geliyor aklıma: kura ile sepete atıyorsun, her ev sakini kuralı ezbere biliyor. Eşit dağılım isteyen, aralık sorusu az soran ekipler bu yolu seviyor.
İkinci yol aralıkla dağıtım: her dilime bir değer aralığı veriliyor. Banka işlemleri uygulamasında Mart kayıtları tek dilimde duruyor, Nisan sonrakine geçiyor. Soru hep aralık soruyorsa bu düzen uçuyor: Mart listesi tek dilimden geliyor. Ama bir bedeli var. Her yeni işlem bugünün tarihini taşıyor, o yüzden bütün yazmalar en yeni dilime yağıyor. MongoDB kılavuzu da bu dengeyi açık yazıyor: aralık soruları az dilim gezer ama sürekli artan anahtar tek dilimi yakar, hash ise yazmayı yayar ama aralık sorusunu dağıtır.
Üçüncü yol dizinle dağıtım: hangi müşterinin hangi dilimde durduğunu yazan bir arama tablosu tutuluyor. Büyük müşteriye tek satırla özel dilim açılabiliyor, küçükler bir arada duruyor. Esneklik tavan. Bedeli de belli: her istek önce bu tabloya soruyor. Tablo yavaşlarsa herkes yavaşlıyor, tablo durursa kimse yerini bulamıyor. Apartman görevlisinin defteri gibi: herkesin dairesini biliyor ama defter kaybolursa apartman kilitleniyor. Değişken büyüklükte müşterileri olan ekipler bu yolu tercih ediyor.
Dördüncü yol coğrafi dağıtım: veri, sahibine yakın makinede duruyor. Avrupalı kullanıcının satırları Avrupa'daki dilimde. İki gerekçesi var. Bir: hız. Soru okyanus aşmadan yanıtlanıyor. İki: kurallar. Bazı verilerin ülke dışına çıkması istenmiyor. Şubeden alışveriş gibi: un almak için şehir dışına gitmiyorsun. Bedeli de dengesizlik olabilir; bir bölge coşarsa o dilim terliyor. Bölgeye göre soru soran, gecikmeye duyarlı ekipler bu yolu kullanıyor.
Şimdi işin nazik yerine gelelim: sıcak anahtar. Lena'nın gönderisi patlıyor, milyonlarca beğeni tek dilime yazılıyor. Dilim nefes alamıyor. Çare tuzlama: 500 numaralı kimliğin yanına 1'den 10'a ekler konuyor, beğeniler on farklı anahtara dağılıyor. Hash işlevi tek harf değişince bambaşka sayı verdiği için bu on anahtar farklı dilimlere düşüyor. Profil ve gönderiler yerinden oynamıyor, yalnız beğeni yükü yayılıyor. Bedeli toplamda: beğeni sayısını göstermek için on dilimi okuyup toplamak gerekiyor. O yüzden kural net: az beğenili Chris'e tuz yok, yalnız alev alan anahtar tuzlanıyor. CosmicLearn anlatımı bu derdi sayılarla koyuyor: tek bölüm saniyede bini aşan yazmada tıkanıyor. Amazon yazısı da ısınan bölümün kendiliğinden ikiye ayrıldığını anlatıyor.
Trafik polisi nasıl karar veriyor dersen, akış şöyle. Her okuma önce önbelleğe uğruyor. Yanıt oradaysa dilimlere hiç gidilmiyor. Yoksa ya da istek yazmaysa top yönlendirme katmanında. Katman iki soru soruyor: bu istek tuzlanan anahtarla mı ilgili, hangi dilim bakmalı. Tuzluysa on anahtardan biri gelişigüzel belirleniyor, beğeni oraya yazılıyor. Toplam soruluyorsa on dilim okunup toplanıyor. Sekreter ve santral benzetmesi cuk oturuyor: sekreter bildiğini yanıtlıyor, bilmediğini santrale bağlıyor, santral de defterine bakıp doğru odaya yolluyor.
Dilim eklemek neden sancılı, onu da görelim. Dört dilimden beşe çıkıyorsun, kural kimliği dörde değil beşe bölüyor. Kalanlar değişiyor, neredeyse herkes taşınıyor. Chris de Leo da yeni evlere gidiyor. Büyümek için çıktığın yol taşınma kamyonlarıyla doluyor. Çare tutarlı hash denen halka düzeni. Bütün hash değerleri bir çembere diziliyor, dilimler çemberin üstüne konuyor. Kural basit: kimliğin yerinden saat yönünde yürü, vardığın ilk dilim senin evin. Yeni dilim çembere konunca yalnız komşusunun yükünü alıyor, Chris ve Leo yerinden oynamıyor. Ekleme maliyeti herkesin taşınmasından bir dilimin taşınmasına iniyor. Bu çember fikrinin kökü 1997 tarihli Karger çalışmasına, Akamai günlerine uzanıyor.
Halkanın da topallayan yanı var: dilimler çembere gelişigüzel düşünce biri geniş yay, biri dar yay kapıyor. Geniş yayın sahibi terliyor, arızada yük tek komşuya yığılıyor. Çare sanal düğüm: her dilimi çembere bir kez değil on kez koymak. Sıfırıncı dilim on ayrı noktada, birinci dilim on ayrı noktada duruyor. Her dilim küçük yayların toplamını taşıyor, toplamlar birbirine yaklaşıyor. Arıza olunca yük bütün dilimlere dağılıyor, kimse ezilmiyor. Gerçek dünya notu da var: Cassandra yıllarca 256 konumla çalıştı, sonra bakım maliyetini kısıp 16 konuma indi. Az konum yetersiz denge, çok konum ağır bakım demek; tatlı nokta aranıyor. Peki araçlar ne yapıyor? Vitess belgeleri çevrimiçi yeniden dilimlemeyi adım adım anlatıyor: yeni dilimler kuruluyor, veri akarken kopyalanıyor, önce yedek okumalar sonra yazmalar yeni adrese alınıyor. Postgres dünyasından gelen CitusData belgeleri de benzer canlı dengeleme sunuyor. Benim çıkardığım ders şu: sharding bir kerelik ameliyat değil, ev idaresi gibi sürekli iş. Verin tek makineye sığmıyorsa, makine sayın zamanla değişecekse ve taşınma maliyetini göze alıyorsanız bu düzen sizin düzeniniz. Yoksa büyük makine, iyi dizinler ve önbellek daha ucuz barış demek.
Videodaki anahtar anlar
AI yorumu
"Bence bu konu her yazılımcının bir gün kapısını çalıyor. Ben olsam sharding kararını son güne bırakmaz, parça anahtarını ilk günden ciddiye alırdım."
AI değerlendirmesi
Bence bu anlatımın en güçlü yanı soyut kavramları tek bir hikâyeye bağlaması. Chirp örneği sayesinde parça anahtarı, tuzlama ve halka gibi başlıklar havada kalmıyor, hepsi aynı uygulamanın derdi oluyor. Ben olsam ekibe ilk gün şunu sorardım: verimiz iki yıl sonra kaç katına çıkar ve hangi sütun o yükü taşır. Bu sorunun yanıtı yoksa sharding günü geldiğinde panik başlar.
Karşı taraf da haklı: sharding her derde deva değil. Dilim sayısı arttıkça toplam okuma maliyeti büyür, tuzlanan anahtarlarda sayım için çok dilim gezmek gerekir, dizinli kurulumda arama tablosu tek aksama noktası olur. Küçük ve orta ölçekte daha büyük makine, iyi dizinler ve önbellek çoğu zaman yeter. Benim ölçüm şu: tek makine gerçekten dolmadan dilimlere bölünmem, ama anahtarımı da o güne hazır tutarım.
Kaynaklar
6 bağlantı; bunları kullanan başka yayımlanmış haber yok. Aynı bağlantıyı paylaşan haberler birbirini doğrulamış sayılmaz; kaynağın kökeni bağlantı sayısından çıkarılmaz.
sharding · veritabanı · ölçekleme