Sharding, bir veritabanını her biri verinin bir kısmını tutan birkaç veritabanına böler. Tek bir makine yazmaları artık kaldıramadığında ya da veriyi tutamadığında cevap budur; ama aynı zamanda bir sistemin ömründeki en pahalı kararlardan biridir: sorgular, transaction'lar, şema değişiklikleri ve operasyonlar hep zorlaşır.
Bu yazı sharding'in ne zaman değdiğini, shard anahtarının nasıl seçileceğini, başlıca sharding yöntemlerini, sorguların doğru shard'ı nasıl bulduğunu ve kesinti olmadan nasıl yeniden sharding yapılacağını ele alıyor. Diyagram, mantıksal shard'lar kullanan ve hash ile shard'lanmış bir sipariş veritabanını gösteriyor.
Önce diğer her şeyi deneyin
Sharding'den önce daha ucuz seçenekleri kabaca şu sırayla kontrol edin:
- Sorguları ve indeksleri düzeltin. "Veritabanı çok yavaş" sorunlarının çoğu eksik bir indeks ya da gereğinden fazla veri okuyan bir sorgudur.
- Dikey ölçekleyin. Daha fazla belleği ve daha hızlı diskleri olan daha büyük bir makine, birçok sistem için yıllar kazandırır.
- Okuma replikaları ekleyin: okuma ağırlıklı yük için; veritabanı replikasyonu yazısı bunlarla gelen gecikmeyi ele alıyor.
- Sık okunan verileri önbelleğe alın, önbellekleme stratejileri yazısındaki gibi.
- İşleve göre bölün: analitik, arama ya da denetim tablolarını kendi veritabanlarına taşıyın.
Bu adımlardan sonra bile yazmalar ya da veri boyutu tek bir primary'nin kaldırabileceğini aşıyorsa ve eğilim daha da kötüleşeceğini söylüyorsa shard'layın.
Shard anahtarı seçmek
Shard anahtarı, bir satırın hangi shard'da duracağına karar verir. İyi bir anahtarın üç özelliği vardır:
- Her sık sorgu onu içerir. Sipariş listesi sorgusu müşteriye göre filtreliyorsa
customer_id, router'ın onu tek bir shard'a göndermesini sağlar. Anahtarı içermeyen bir sorgu her shard'a sormak zorunda kalır. - Yükü eşit dağıtır. Çok sayıda farklı değer vardır ve hiçbir tek değer trafiğin büyük bir payını üretmez.
- İlişkili verileri bir arada tutar. Bir müşterinin tüm siparişlerinin, kalemlerinin ve ödemelerinin aynı shard'da olması, transaction'ların ve join'lerin yerel kalması demektir.
Çok kiracılı bir SaaS için anahtar genellikle tenant kimliğidir. Bir tüketici uygulaması için kullanıcı ya da müşteri kimliği. İyi görünüp yükü yoğunlaştıran anahtarlara dikkat edin: zaman damgası (tüm yeni yazmalar tek bir shard'a gider) ya da ülke kodu (bir ülke baskın çıkar) gibi.
Aralık, hash ya da dizin
| Yöntem | Satırlar nasıl yerleştirilir | Güçlü yanı | Zayıf yanı |
|---|---|---|---|
| Aralık | A-F, G-M gibi anahtar aralıklarına göre | Aralık taramaları tek bir shard'da kalır | Yeni ya da popüler aralıklar sıcak noktaya dönüşür |
| Hash | Anahtarın hash'ine göre | Eşit dağılım | Aralık sorguları her shard'a gider |
| Dizin | Bir arama tablosu her anahtarı ya da grubu bir shard'a eşler | Tam kontrol, kolay taşıma | Dizin kritiktir ve hızlı olmak zorundadır |
Yaygın bir melez yaklaşım: anahtarı sabit sayıda mantıksal shard'a (örneğin 1.024) hash'leyin ve mantıksal shard'ları fiziksel host'lara eşleyen küçük bir dizin tutun. Anahtarlar mantıksal shard'lar arasında asla yer değiştirmez; yalnızca mantıksal shard'lar bütün olarak host'lar arasında taşınır. Instagram'ın mühendislik ekibi bu yaklaşımı 2012'de, çok daha az sayıda veritabanı sunucusu üzerinde binlerce mantıksal shard ile anlatmıştı.
Sorguları yönlendirmek
Her anahtarın nerede durduğunu bir şeyin bilmesi gerekir:
- Uygulamada, anahtarı hash'leyip host'u bulan bir kütüphane aracılığıyla. Basittir, ama her servisin ve her dilin aynı mantığa ihtiyacı olur.
- Bir proxy'de, uygulama ile veritabanları arasında. Vitess bunu MySQL için VTGate proxy'siyle, Citus ise Postgres için bir koordinatör düğümü aracılığıyla yapar.
Her iki durumda da shard haritasını önbelleğe alın ve değiştiğinde yeniden yükleyin. Taşıma sırasında eskimiş bir harita, klasik yeniden sharding hatasıdır: bir router geçişten sonra eski host'a yazar ve satır sessizce yenisinden kaybolur. Haritayı versiyonlayın ve eski versiyon taşıyan yazmaları reddedin. Shard anahtarı içermeyen sorgular tüm shard'lara dağıtılır ve sonuçlar birleştirilir; bu, seyrek yönetim işleri için işe yarar, olağan bir erişim yolu olarak ise çöker.
Kesintisiz yeniden sharding
Mantıksal shard'larla kapasite eklemek, bazı mantıksal shard'ları yeni bir host'a taşımak demektir:
- Eski host hizmet vermeye devam ederken mantıksal shard'ların verisini yeni host'a kopyalayın.
- Kopya yetişene kadar süregelen değişiklikleri veritabanının replikasyonuyla ya da change data capture ile aktarın.
- Bu mantıksal shard'lar için yazmaları kısa bir süre durdurun, son değişikliklerin gelmesini bekleyin, shard haritasını güncelleyin ve devam edin.
- Doğrulayın, sonra taşınan veriyi eski host'tan silin.
Vitess ve Citus bu iş akışının farklı sürümlerini otomatikleştirir. İhtiyaç duymadan önce prova edin; yük altında ilk kez yeniden sharding yapmak kötü bir gündür.
Shard'lar arasında çalışan kimlikler
Veritabanı başına bir sequence, her shard'da aynı kimlikleri dağıtır. Koordinasyon gerektirmeden benzersiz olan kimlikler kullanın: UUID'ler (sürüm 7 onları kabaca zaman sıralı tutar, bu da indeksler için daha iyidir) ya da zaman damgasını, bir shard ya da makine numarasını ve bir sayacı birleştiren Snowflake tarzı 64 bit kimlikler. Mantıksal shard numarasını kimliğe gömmenin bir bonusu vardır: elinde yalnızca bir sipariş kimliği olan router, kimseye sormadan nereye bakacağını bilir.
Mimari diyagram
Diyagram içeriği
- Order service
- Shard router
- Shard map
- Host 1: shards 0-255
- Host 2: shards 256-511
- Host 3: shards 512-767
- Host 4: shards 768-1023
- Host 5: shards 896-1023
- Analytics warehouse
- query + key
- cached lookup
- move shards 896-1023
- CDC from all hosts
Nasıl okunur:
- Sol: sipariş servisi her sorguyu bir müşteri kimliğiyle shard router'ına gönderir.
- Orta: router müşteri kimliğini 1.024 mantıksal shard'dan birine hash'ler ve host'u önbellekteki shard haritasında bulur (kesikli).
- Sağ: dört Postgres host'unun her biri 256 mantıksal shard tutar. Host 4, üst yarısını yeni host 5'e taşıyor; bu, sürmekte olan yeniden sharding adımıdır.
- Sağ üst: müşteriler arası raporlar, change data capture ile beslenen bir analitik veri ambarından okur; böylece asla shard'lar arasına dağılmazlar.
- Markdown bloğu sorgu yazan herkesin uyması gereken kuralları listeler.
Kabul ettiğiniz maliyetler
Çok kiracılı SaaS mimari diyagramı bu tasarımın kiracı başına shard varyantını gösteriyor; aşağıdaki ödünleşimler orada kiracı başına geçerlidir.
- Shard'lar arası transaction'lar dağıtık transaction'lara ya da saga'lara dönüşür. Tasarımı bunlar seyrek olacak şekilde yapın.
- Shard'lar arası benzersizlik kısıtları veritabanı başına bir sequence yerine küresel bir kimlik şeması gerektirir.
- Şema değişiklikleri her shard'da çalışır; bu yüzden migration'lar araç desteği ister ve kısmen tamamlanmış olmayı tolere etmelidir.
- Operasyonlar katlanır: her shard için yedekler, yükseltmeler ve izleme.
Sharding diyagramına neler konmalı
- Shard anahtarı ve yöntem (hash, aralık, dizin).
- Mantıksal ve fiziksel shard'lar, eğer ayırıyorsanız.
- Yönlendirmenin nerede yapıldığı: kütüphane, proxy ya da koordinatör.
- Anahtarsız sorguların yolu, örneğin bir veri ambarı ya da arama indeksi.
- Yeniden sharding durumu, bir taşıma sürüyorsa.
Archboard'da oluşturun
- Google ya da GitHub ile giriş yapın ve bir diyagram oluşturun.
- Servis ve shard router'ı için C4 Modeli paketinden Konteyner düğümleri, shard haritası için de bir Veritabanı ekleyin.
- Host'lar için Veri paketinden Postgres düğümleri ekleyin, onları mantıksal shard aralıklarıyla etiketleyin ve yeni host için bir tane daha ekleyin.
- Raporlar için Veri paketinden bir Veri ambarı ekleyin ve onu noktalı bir CDC kenarıyla besleyin.
- Yeniden sharding taşımasını kesikli bir kenarla çizin ve sharding kurallarını içeren, Temel paketinden bir Markdown bloğu ekleyin.
Örnek 10 diyagram düğümü kullanıyor ve Free planın sınırları içinde kalıyor.
SSS
Sharding ile partitioning arasındaki fark nedir? Partitioning genellikle bir tabloyu tek bir veritabanı sunucusunun içinde bölmek demektir. Sharding ise veriyi birkaç sunucuya yayar; her biri verinin yalnızca bir kısmını tutar.
Shard anahtarını nasıl seçerim? Her sık sorgunun filtrelediği, ilişkili verileri bir arada tutan, çok sayıda farklı değeri olan ve yükü eşit dağıtan özelliği seçin; örneğin bir tenant ya da müşteri kimliği.
Mantıksal shard'lar nedir? Daha az sayıda fiziksel sunucuya eşlenen, sabit ve büyük sayıda hash kovası. Kapasite eklerken mantıksal shard'ları bütün olarak sunucular arasında taşımak, her anahtarı yeniden hash'lemekten kurtarır.
Tüm shard'lar üzerinde nasıl sorgu çalıştırırım? Sık kullanılan yollarda bundan kaçının. Raporlar için veriyi bir veri ambarına replike edin; seyrek yönetim işleri için router üzerinden dağıtılan bir sorgu kabul edilebilir.
Ne zaman shard'lamalıyım? Yazma hacmi ya da veri boyutu iyi ayarlanmış tek bir primary'nin kaldırabileceğini aştığında ve eğilim sürdüğünde; indeksleme, dikey ölçekleme, replikalar, önbellekleme ve işlevsel bölmeden sonra.