MySQL tablolarını parçalamak için en iyi yaklaşım nedir. Aklıma gelen yaklaşımlar:
- Uygulama Düzeyi parçalama?
- MySQL proxy katmanında parçalama mı?
- Parçalama için merkezi arama sunucusu?
Bu alandaki ilginç projeler veya araçlar biliyor musunuz?
Yanıtlar:
MySQL tablolarını parçalamak için en iyi yaklaşım, bunu yapmak tamamen kaçınılmaz olmadıkça bunu yapmamaktır.
Bir uygulama yazarken, genellikle bunu hızı ve geliştirici hızını en üst düzeye çıkaracak şekilde yapmak istersiniz. Gecikmeyi (yanıt hazır olana kadar geçen süre) veya verimi (zaman birimi başına yanıt sayısı) yalnızca gerektiğinde optimize edersiniz.
Yalnızca tüm bu bölümlerin toplamı artık tek bir veritabanı sunucusu örneğine sığmadığında bölümleri farklı ana bilgisayarlara (= parça) bölümler ve atarsınız - bunun nedeni yazma veya okuma olmasının nedeni.
Yazma durumu, a) yazma sıklığı bu sunucu disklerini kalıcı olarak aşırı yüklüyor veya b) çoğaltmanın bu çoğaltma hiyerarşisinde kalıcı olarak gecikmesi için devam eden çok fazla yazma var.
Parçalama için okuma durumu, verilerin boyutunun çok büyük olduğu ve çalışma kümesinin artık belleğe sığmadığı ve veri okumalarının çoğu zaman bellekten sunulmak yerine diske vurmaya başlamasıdır.
Eğer sadece zaman var shard için sen yap.
Parçaladığınız an, bunun için çeşitli şekillerde ödeme yaparsınız:
SQL'inizin çoğu artık bildirimsel değil.
Normalde, SQL'de veritabanına hangi verileri istediğinizi söylersiniz ve bu belirtimi bir veri erişim programına dönüştürmek için onu optimize ediciye bırakırsınız. Bu iyi bir şey çünkü esnek ve çünkü bu veri erişim programlarını yazmak hıza zarar veren sıkıcı bir iş.
Parçalanmış bir ortamda, muhtemelen B düğümündeki verilere karşı A düğümündeki bir tabloya katılıyorsunuz veya A ve B düğümlerinde bir düğümden daha büyük bir tablonuz var ve B ve C düğümlerindeki verilere karşı ondan gelen verileri birleştiriyorsunuz. Bunu çözmek için (veya MySQL kümesini yeniden icat ediyorsunuz) uygulama tarafı hash tabanlı birleştirme çözümlerini manuel olarak yazmaya başlıyorsunuz, yani artık bildirimsel olmayan ancak SQL işlevselliğini yordamsal bir şekilde ifade eden çok sayıda SQL elde edersiniz. (örneğin döngülerde SELECT deyimleri kullanıyorsunuz).
Çok fazla ağ gecikmesi yaşıyorsunuz.
Normalde, bir SQL sorgusu yerel olarak çözülebilir ve iyileştirici yerel disk erişimleriyle ilişkili maliyetleri bilir ve sorguyu bunun maliyetlerini en aza indirecek şekilde çözer.
Parçalanmış bir ortamda, sorgular ya anahtar-değer erişimlerini bir ağ üzerinden birden çok düğüme çalıştırarak (umarız toplu anahtar erişimleriyle ve gidiş dönüş başına tek tek anahtar aramaları ile değil) ya da WHERE
cümlenin bölümlerini yapabilecekleri düğümlere ileriye doğru iterek çözümlenir. uygulanabilir (buna 'durum aşağı itme' denir) veya her ikisi.
Ancak en iyi durumlarda bile bu, yerel bir durumdan çok daha fazla ağ gidiş-dönüşünü içerir ve daha karmaşıktır. Özellikle MySQL iyileştiricisi ağ gecikmesi hakkında hiçbir şey bilmediğinden (Tamam, MySQL kümesi bu konuda yavaş yavaş iyileşiyor, ancak kümenin dışındaki vanilya MySQL için bu hala geçerli).
SQL'in çok fazla ifade gücünü kaybediyorsunuz.
Tamam, bu muhtemelen daha az önemli, ancak yabancı anahtar kısıtlamaları ve veri bütünlüğü için diğer SQL mekanizmaları birden çok parçayı kapsayacak durumda değil.
MySQL, çalışma düzeninde olan eşzamansız sorgulara izin veren bir API'ye sahip değildir.
Aynı türdeki veriler birden fazla düğümde bulunduğunda (örneğin, A, B ve C düğümlerindeki kullanıcı verileri), yatay sorgular genellikle bu düğümlerin hepsinde çözülmelidir ("90 gündür oturum açmamış tüm kullanıcı hesaplarını bulun yada daha fazla"). Veri erişim süresi, birden çok düğüm paralel olarak sorulmadığı ve sonuçlar geldikçe toplanmadığı sürece düğüm sayısı ile doğrusal olarak artar ("Harita-Azalt").
Bunun ön koşulu, MySQL için iyi bir çalışma biçiminde bulunmayan bir zaman uyumsuz iletişim API'sidir. Bunun alternatifi, bir sezon geçişinde emzirme dünyasını ziyaret eden çocuk süreçlerinde çok fazla çatallanma ve bağlantıdır.
Parçalamaya başladığınızda, veri yapısı ve ağ topolojisi, uygulamanıza performans noktaları olarak görünür hale gelir. Makul derecede iyi performans göstermesi için, uygulamanızın bunlardan haberdar olması gerekir ve bu, gerçekten yalnızca uygulama düzeyinde parçalama mantıklı olduğu anlamına gelir.
Otomatik olarak parçalamak (örneğin birincil anahtarlara hashing uygulayarak hangi satırın hangi düğüme gideceğini belirlemek) veya manuel olarak işlevsel olarak bölmek istiyorsanız ("xyz kullanıcı öyküsüyle ilgili tablolar buna gidin master, abc ve def ile ilgili tablolar ise o master'a gider ").
İşlevsel parçalama, doğru yapılırsa çoğu geliştirici için görünmez olma avantajına sahiptir, çünkü kullanıcı öyküleriyle ilgili tüm tablolar yerel olarak erişilebilir olacaktır. Bu, bildirim temelli SQL'den mümkün olduğunca uzun süre yararlanmalarına olanak tanır ve ayrıca ağlar arası aktarımların sayısı minimum düzeyde tutulduğu için daha az ağ gecikmesine neden olur.
İşlevsel parçalama, tek bir tablonun tek bir örnekten daha büyük olmasına izin vermemesi ve bir tasarımcının manuel olarak ilgilenmesini gerektirmesi dezavantajına sahiptir.
İşlevsel parçalama, aşırı büyük olmayan bir dizi değişiklikle mevcut bir kod tabanına göreceli olarak kolayca yapılabilme avantajına sahiptir. http://Booking.com bunu geçtiğimiz yıllarda birçok kez yaptı ve onlar için iyi çalıştı.
Tüm bunları söyledikten sonra, sorunuza bakarak, yanlış sorular sorduğunuza inanıyorum veya sorun ifadenizi tamamen yanlış anlıyorum.
Uygulama Düzeyi parçalama: dbShards, "uygulamaya duyarlı parçalama" yaptığını bildiğim tek ürün. Web sitesinde birkaç güzel makale var. Sadece tanımı gereği, uygulamaya duyarlı parçalama daha verimli olacaktır. Bir uygulama, bir işlemle tam olarak nereye gideceğini, ona bakmak zorunda kalmadan veya bir proxy tarafından yönlendirilmeden bilirse, bu kendi içinde daha hızlı olacaktır. Ve hız, birisi parçalama işine girdiğinde, tek endişe değilse de, çoğu zaman birincil endişelerden biridir.
Bazı insanlar bir vekil ile "parçaladılar", ancak benim gözümde parçalama amacını bozan. İşlemlerinize verileri nerede bulacağınızı veya nerede depolayacağınızı söylemek için başka bir sunucu kullanıyorsunuz. Uygulamaya duyarlı parçalama ile uygulamanız nereye gideceğini kendi başına bilir. Çok daha verimli.
Bu gerçekten # 2 ile aynı.
Bu alandaki ilginç projeler veya araçlar biliyor musunuz?
Bu alandaki birkaç yeni proje:
Shard-Query , MySQL için OLAP tabanlı bir parçalama çözümüdür. Parçalanmış tablolar ile parçalanmamış tabloların bir kombinasyonunu tanımlamanıza olanak tanır. Parçalanmamış tablolar (arama tabloları gibi), parçalanmış tablolara serbestçe birleştirilebilir ve parçalanmış tablolar, tablolar parça anahtarı ile birleştirildiği sürece birbirine birleştirilebilir (parça sınırlarını aşan çapraz parça veya kendi kendine birleşmez). Bir OLAP çözümü olan Shard-Query, basit sorgular için bile genellikle 100 ms veya daha az minimum yanıt süresine sahiptir, bu nedenle OLTP için çalışmayacaktır. Shard-Query, büyük veri kümelerini paralel olarak analiz etmek için tasarlanmıştır.
MySQL için de OLTP parçalama çözümleri mevcuttur. Kapalı kaynak çözümleri arasında ScaleDB , DBShards bulunur . Açık kaynaklı OLTP çözümü arasında JetPants , Cubrid veya Flock / Gizzard (Twitter altyapısı) bulunur.
Elbette uygulama seviyesi.
Bu kitapta bulduğum en iyi yaklaşım
Yüksek Performanslı MySQL http://www.amazon.com/High-Performance-MySQL-Jeremy-Zawodny/dp/0596003064
Kısa açıklama: Verilerinizi birçok parçaya bölebilir ve her sunucuda ~ 50 parça depolayabilirsiniz. Parçalama konusundaki en büyük ikinci sorun olan yeniden dengelemeden kaçınmanıza yardımcı olacaktır. Sadece bazılarını yeni sunucuya taşı ve her şey yoluna girecek :)
Satın almanızı ve "mysql ölçeklendirme" bölümünü okumanızı şiddetle tavsiye ederim.
2018 itibariyle, buna MySql-yerel bir çözüm var gibi görünüyor. Aslında en az 2 - InnoDB Kümesi ve NDB Kümesi vardır (bunun ticari ve topluluk versiyonu vardır).
MySql topluluk sürümünü kullanan çoğu kişi InnoDB motoruna daha aşina olduğundan, bu, birinci öncelik olarak araştırılması gereken şeydir. Kutudan çıkar çıkmaz çoğaltma ve bölümlemeyi / parçalamayı destekler ve farklı yönlendirme / yük dengeleme seçenekleri için MySql Router'ı temel alır.
Tablo oluşturma işleminizin sözdiziminin değiştirilmesi gerekir, örneğin:
CREATE TABLE t1 (col1 INT, col2 CHAR(5), col3 DATETIME) PARTITION BY HASH ( YEAR(col3) );
(bu, dört bölümleme türünden yalnızca biridir )
Çok önemli bir sınırlama:
InnoDB yabancı anahtarlar ve MySQL bölümleme uyumlu değildir. Bölümlenmiş InnoDB tablolarında yabancı anahtar başvuruları olamaz veya yabancı anahtarlar tarafından başvurulan sütunlar olamaz. Yabancı anahtarlara sahip olan veya yabancı anahtarlar tarafından başvurulan InnoDB tabloları bölümlenemez.
PARTITION BY HASH(YEAR...)
tarar tüm bir tarih aralığı varsa bölümleri. Yuck.