MySQL parçalama yaklaşımları?


89

MySQL tablolarını parçalamak için en iyi yaklaşım nedir. Aklıma gelen yaklaşımlar:

  1. Uygulama Düzeyi parçalama?
  2. MySQL proxy katmanında parçalama mı?
  3. Parçalama için merkezi arama sunucusu?

Bu alandaki ilginç projeler veya araçlar biliyor musunuz?

Yanıtlar:


116

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 WHEREcü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.


2
Bu iyi bir cevap. Ancak, parçalamanın gerçekten yalnızca yüksek hacimli uygulamalar için gerekli olduğunu ve büyük olasılıkla bir tür gelir sağladığını belirtmek isterim. Üçüncü taraf bir parçalama uygulaması, birleştirmeler, parçalar arası işlemler vb. İle ilgili tüm endişelerinizi ele alacaktır. İyi bir tane alırsanız, "ilişkisel" bir veritabanının bütünlüğünü koruyacaktır. Diğer uygulamalar, haklısınız, veritabanınızı basitçe bir anahtar-değer çiftine dönüştürecek ve böylece SQL'in amacını bozacaktır.
chantheman

3
Ticari olsun ya da olmasın, verilerin artık ağa dağılmış olduğu ve gecikme kaynaklı bekleme eksikliğinden dolayı gecikmeye veya tutarsızlığa maruz kaldığı gerçeğini gizlemekte başarılı olan bir parçalama uygulamasına henüz rastlamadım. Parçalıyorsanız, uygulamanız fark edecek ve değişiklik gerektirecektir. Sen de kontrol edebilirsin. Gümüş kurşun yok, ama çok fazla yılan yağı var.
Isotopp

1
DbShards'a göz atmalısınız. Eklediğiniz "parça" sayısı başına doğrusal olandan daha iyi ölçeklenir. Uygulama tarafında varsa çok az değişiklik yapmanız gerekecek ve evet uygulamanız farkı bilmiyor. Sadece ODBC veya JDBC ile yaptığınız gibi işlemleri gönderir ve alır. dbShards, bir işlem üzerinde daha fazla kontrol sahibi olmak istiyorsanız parça ipuçlarına da izin verir. DbShards'a tam olarak hangi parçadan okumak veya yazmak istediğinizi söyleyebilirsiniz.
chantheman

1
@Gigala, genişliğine bakılmaksızın böyle iyi tanımlanmış bir cevap yazmak için zaman harcamak da gerekli değil, ancak bu cevap bana yardımcı olduğu için yapıldığına sevindim. Lütfen kullanıcıları cevap verirken "kutunun dışında düşünmemeleri" konusunda cesaretlendirmeyin.
mewm

12
  1. 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.

  2. 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.

  3. Bu gerçekten # 2 ile aynı.


dbShards bazı yerlerde üretimde kullanılıyor mu? ayrıca açık kaynak değildir.
sheki

Ayrıca, proxy DB veya bir mağaza yerine bir karmaya dayalı olarak ararsa, yaklaşım 2 ve 3 farklı olabilir.
sheki

1
dbShards çeşitli istemcilerle üretiliyor, ancak hayır, açık kaynak değil. İyi bir açık kaynak kodlama ürünü bulacağınızı sanmıyorum. Ve evet, bir hash'in arama olarak kullanılabileceği konusunda haklısınız, ancak bu durumda işleminizi veritabanına almak için hala bir "durdurma" daha yapmanız gerekiyor. Bu nedenle "uygulama farkında" parçalama neredeyse her zaman daha hızlı olacaktır.
chantheman

Ama dediğim gibi, ilişkilerin bütünlüğünü koruyan bir parçalama uygulaması elde edebilirseniz, o zaman iyi durumda olacaksınız. DbShards'tan bahsediyorum çünkü bildiğim tek şey o. Ve yaptığı için, yazma ve okuma hızlarınızı doğrusal olarak ölçeklendirir. 4 "parça" eklersiniz veya bir MySQL sunucunuzu 4'e bölersiniz ve 4 kat daha hızlı çalışır.
chantheman

7

Bu alandaki ilginç projeler veya araçlar biliyor musunuz?

Bu alandaki birkaç yeni proje:

  • citusdata.com
  • spockproxy.sourceforge.net
  • github.com/twitter/gizzard/

5

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.


3

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.


Önerdiğiniz kitap 8 yaşında ... günümüz teknolojileriyle ilgili parçaları içeriyor mu?
raffian

1
MySQL'i ölçeklendirmek için bazı temel yaklaşımları kapsar. AFAIK mysql ölçeklendirmesinde hiçbir şey değişmedi. Aynı uygulama düzeyinde parçalama ve çoğaltma teknikleri günümüzde yaygın olarak kullanılmaktadır.
Andrey Frolov

Yanılıyor olabilirim, ancak geçen hafta bununla ilgili bir sürü araştırma yapıyorum ve görünüşe göre mySQL son 8 yılda özellikle bölümleme ve önbelleğe alma ile ilgili birçok değişiklik yaptı. Bu yıl çıkan yeni bir sürüm var: amazon.com/High-Performance-MySQL-Optimization-Replication/dp/… Okumadım ama mevcut yeni çoğaltma modellerini kapsadığını düşünüyorum.
NateDSaint

4
Kitaplar .. neden burada açıklamayalım?
DDD

2

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.


Unutmayın PARTITION BY HASH(YEAR...)tarar tüm bir tarih aralığı varsa bölümleri. Yuck.
Rick James
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.