Birden Çok Veritabanını / Sunucuyu Kullanarak Verilerle Etkileşim


18

Şimdiye kadar uğraşmak zorunda olduğum tüm projeler tek bir sunucuda sadece tek bir veritabanı gerektiriyordu. Ölçeklenmesi gereken projelerin yükü yönetmeye yardımcı olmak için birden çok veritabanına ve / veya sunucuya nasıl taşındığı hakkında daha fazla bilgi edinmek istiyorum. Yüksek Ölçeklenebilirliğin farkındayım , ancak özellikle bu konuda daha fazla bilgi alabileceğim bazı kod örnekleri veya ek kaynaklarla ilgileniyorum.

Örneğin:

  • Birden çok veritabanındaki iki tablo arasında birleştirmeler nasıl oluşturulur? (Burada bir kod örneği yardımcı olacaktır).
  • Hangi veritabanında hangi tabloların bulunduğunu izlemek için özel stratejiler var mı?
  • Uygulama kodunun bir veya daha fazla veritabanının birden çok sunucuya dağıtıldığını bilmesi gerekiyor mu? Değilse, talepler hangi düzeyde filtrelenir?
  • 1 veritabanı / 1 sunucu kurulumunun ötesine geçme zamanı ne zaman? Bunu yapmak ne kadar yaygındır?

Bu soru Veritabanı Yöneticilerinde daha iyi yanıtlanabilir . Yine de burada gerçekten yanlış bir şey yok, bu yüzden sadece DBA modlarını kontrol edeceğim. Orada uygunsa, taşınmasını ister misiniz?
Adam Lear

@AnnaLear - Sanırım cevaplara bağlı. Bu noktada, sorunun uygulama tarafı ile daha fazla ilgileniyorum, bu yüzden şimdilik, burada daha iyi olabileceğini düşünüyorum.
VirtuosiMedia

@AnnaLear ack, OP ile anlaştıktan sonra uygulamaya özel kod istiyorlarsa.
jcolebrand

Yanıtlar:


13

Tamam, yıkalım:

  • Birden çok veritabanındaki iki tablo arasında birleştirmeler nasıl oluşturulur? (Burada bir kod örneği yardımcı olacaktır).

Bu oldukça basit. SQL Nesneleri, bir ila dört bölüm adlandırma kuralına sahiptir:

Servername.databasename.schemaname.tablename

Tüm tablolarınız aynı veritabanında, aynı sahip / şema ile aynı sunucudaysa, ilk üç bölümü yok sayabilir ve en çok kullandığınız şeyi kullanabilirsiniz:

Select a.*,b.* from 
tableA a inner join 
tableB b on a.col1=b.col1

Tablolarınızdan biri farklı bir veritabanındaysa ve her ikisi de veritabanları için varsayılan şemayı kullanıyorsa, veritabanını ikinci tabloya eklemeniz yeterlidir:

Select a.*,b.* from 
tableA a inner join 
databaseC..tableB b on a.col1 = b.col1

Sorguladığınız veritabanlarından farklı bir üçüncü veritabanındaysanız, her iki veritabanı adını da açıkça kullanırsınız:

Select a.*,b.* from 
databaseD..tableA a inner join 
databaseC..tableB b on a.col1 = b.col1

Sonunda farklı şemalar ve / veya sahipler kullanırsanız, bunları şuralara ekleyebilirsiniz:

Select a.*,b.* from 
databaseD.john.tableA a inner join 
databaseC.accounting.tableB b on a.col1 = b.col1

Ve son olarak, bu konuda çok dikkatli iseniz ve çok iyi bir nedeniniz varsa, başka bir sunucuda (genellikle küçük) bir masaya katılabilirsiniz:

Select a.* from 
databaseD.john.TableA a inner join 
ATLANTA.databaseC.accounting.tableB b on a.col1 = b.col1
  • 1 veritabanı / 1 sunucu kurulumunun ötesine geçme zamanı ne zaman? Bunu yapmak ne kadar yaygındır? Hangi veritabanında hangi tabloların bulunduğunu izlemek için özel stratejiler var mı?

Bu ikisini birleştireceğim çünkü birlikte gidiyorlar. Tasarım / iş / teknik kısıtlamalarınız sizi daha fazla kullanmaya zorlayana kadar, bir veritabanının bir sunucunun yeterli olduğu varsayımıyla başlamak için neredeyse her zaman iyisinizdir.

Bu nedenle, önce ikinci sorunuzu cevaplamak için, genellikle ayrı veritabanlarına sahip olmanız için bir nedeniniz olduğundan, sisteminizin tasarımının bir şeyin nerede olduğunu bilmesinden oldukça açık olması gerekir.

Ne zaman / neden tek bir veritabanının ötesine geçmek gerektiğine gelince. Genellikle iş kuralları, politika ve / veya teknik nedenlerin bir karışımıdır.

Örneğin, çalıştığım yerde 4 sunucuya yayılmış 16 veritabanımız var. Bir MainDB, ImageDB, referencetableDB, HighvolumeTransactionDB, ReportingDB, StagingDB, ProcessingDB, ArchiveDB, FinancialDB var. Neden farklı olduklarına dair bazı örnekler vermek için:

  • FinancialDB, hassas bilgiler
  • Image DB, belirli farklı depolama ve kurtarma gereksinimleri
  • ReferenceDB, düşük işlem, yüksek okuma
  • RaporlamaDB, çok yüksek okuma, diğer verilerin çoğunun aksine, diğer çeşitli ortamlara geri yüklenmesi / çoğaltılması gerekiyor
  • StagingDB, kalıcı bir şey değil, sadece üzerinde daha fazla kontrole sahip olduğumuz bir sığır tempdb
  • MainDB, diğer tüm DB'lerle arayüz oluşturur, ancak diferansiyel yedeklemeye ihtiyaç duyar, bu yüzden ...
  • HighVolumeTransaction tabloları (nispeten geçici olan), yedeklemenin makul büyüklüğünü korumak için kendi DB'lerine.
  • Arşiv, Ana ve Raporlama ile aynı verilerin birçoğu, ancak daha uzun saklama süreleri ve verilerin derinlemesine kazılması daha zor isabet sorguları ile. Bu hala Ana / Raporlama ile birleştirilse, sistemimizi batar.

Uygulama kodunun bir veya daha fazla veritabanının birden çok sunucuya yayıldığını bilmesi gerekiyor mu? Değilse, talepler hangi düzeyde filtrelenir?

Geniş anlamda, muhtemelen yaparlar. En azından veritabanı bağlantı dizesinde hangi sunucuyu işaret ettiklerini bilmeleri gerekir. İşleme, Raporlama, Ana vb.

Oradan altında çalıştırmak için bir veritabanı bağlamına ihtiyaç duyarlar. Genellikle bu uygulama için en çok kullanılan, hatta bir veritabanı / uygulamanın bir sunucu gün orijinal olabilir. Uygulamanın her çağrıda açıkça veritabanı bağlamını değiştirmesini sağlayabilirsiniz, ancak bu, uygulamayı değiştirmeden veritabanını ayarlamayı zorlaştırır.

Her zamanki (ya da en azından benim olağan) yaklaşım, her zaman bir ya da belki iki ana veritabanından erişmektir.

Ardından, saklı yordamlar aracılığıyla veritabanıyla arabirim oluşturmakla birlikte gerektiğinde diğer veritabanlarına görünümler oluşturun.

Açıklamak gerekirse:

Diyelim ki bir Müşterinin demografik bilgilerini, Satış verilerini ve Kredi bakiyesini almak istiyorsunuz ve bu aslında tüm MainDB'de üç tabloya yayılmıştır.

Yani uygulamanızdan bir çağrı yazıyorsunuz:

Select c.ClientName, c.ClientAddress, s.totalSales,f.CreditBlance from
Clients c join Sales s on c.clientid = s.clientid inner join AccountReceivable f on 
c.clientid=f.clientid where c.clientid = @clientid

Muhteşem. Ancak, şimdi bir sütun adını değiştirdiğimizde veya bir tabloyu yeniden adlandırdığımızda / taşıdığımızda uygulama kodunu güncellemeniz gerekir. Bunun yerine iki şey yapıyoruz:
İstemciler, Satışlar, Hesap Alımları Görünümleri Oluştur (Select * kullanmazsınız, ancak burada demo yapıyorum)

Use MainDB
GO
Create view v_Clients as select * from Clients
Create view v_Sales as select * from Sales
Create view v_AccountReceivable as select * from AccountReceivable
Go

Sonra bir de saklı yordam, spGetClientSalesAR oluşturmak

Create proc spGetClientSalesAR @clientID int
as
Select c.ClientName as ClientName, 
       c.ClientAddress as ClientAddress, 
       s.totalSales as TotalSales, 
       f.CreditBlance as CreditBalance 
from
v_Clients c join v_Sales s 
    on c.clientid = s.clientid 
inner join v_AccountReceivable f 
    on c.clientid=f.clientid 
where c.clientid = @clientid

Ve uygulamanızın bunu aramasını sağlayın.

Şimdi o saklı proc arabirimi değiştirmek sürece, ben hemen hemen ölçeklendirmek veya dışarı arka uç veritabanına yapmak için gereken her şeyi yapabilirim.

Aşırı olarak, eski MainDB'mi bile oluşturduğumuz bu görünümlerin altında şöyle görünüyordu:

Create view v_Clients as select * from ServerX.DatabaseY.dbo.Clients
Create view v_Sales as select * from ServerQ.DatabaseP.dbo.Sales
Create view v_AccountReceivable as select * from ServerJ.DatabaseK.dbo.AccountReceivable

Ve uygulamanız farkı asla bilemez, (diğer şeylerin yanı sıra hızlı borular ve iyi hazırlanmış veriler varsayarak).

Açıkçası bu aşırı ve her şeyin bu şekilde planlandığını söylesem yalan söylüyordum, ancak yeniden düzenleme sırasında yapsanız bile saklı yordamları / görünümleri kullanmak, uygulamanız mütevazi bir veritabanından / bir sunucusundan büyüdükçe size çok fazla esneklik sağlayacaktır. başlangıç.


TetonSig - Cevabınız için teşekkürler. Size tam ödül (seyahat ediyordum) vermek için soruya zamanında geri dönemedim, ancak soru için yeni bir ödül yarattım ve 24 saat içinde size verebileceğim.
VirtuosiMedia

Vay canına, teşekkürler. Bunu takdir ediyorum. Soruyu cevaplamak çok eğlenceliydi.
TetonSig

5

Web dünyasında (soru PHP etiketli olduğundan) birden fazla veritabanı sunucusuyla karşılaştığım birincil yol, bir 'ana' (yazma) veritabanı ve ardından bir veya daha fazla çoğaltılmış 'slave' (okuma) veritabanının bulunduğu kurulumlardır. . Veritabanı yazma işlemleri 'ana' veritabanına karşı yapılır. Bu veritabanının içeriği 'gerçek' sunuculara neredeyse gerçek zamanlı olarak çoğaltılır. Sorgular - özellikle yoğun raporlar - yükü bu sunuculara kaydırmak için 'bağımlı' veritabanlarından birine karşı çalıştırılır. Bu özel kurulumun çok fazla okuma yapan, ancak çok fazla yazma olmayan uygulamalar için en iyisi olduğunu unutmayın. Hiçbir şekilde işleri düzenlemenin tek yolu bu değildir.


3

Birden çok veritabanındaki iki tablo arasında birleştirmeler nasıl oluşturulur? (Burada bir kod örneği yardımcı olacaktır).

Onlar değil. NoSQL veritabanları "birleşim" yapmaz ve RDBMS sunucularında SQL birleştirmesi yapabilseniz bile , performansa değer verip vermediğinizi (dağıtılmış bilgi işlemin yanlışları ) istemezsiniz .

Hangi veritabanında hangi tabloların bulunduğunu izlemek için özel stratejiler var mı?

İlişkisel / SQL veritabanında bölümleme normalde farklı disklere yerleştirilmiş farklı dosyalar kullanılarak tek bir sunucunun / veritabanının sınırları içinde yapılır. Hemen hemen yatay bir ölçeklendirme çözümü, tüm veritabanlarının tüm tablolara sahip olduğu ve tüm verilerin olması gerektiği yere ulaştığından emin olmak için bir tür işlemsel yansıtma, çoğaltma veya özel nihai tutarlılık çözümüne sahip olduğunuz anlamına gelir .

Veritabanını sadece fiziksel olarak değil, mantıksal olarak bölüyorsanız, DAL veya ORM'nizde tanımlanan eşlemeler hangi tabloların hangi veritabanında olduğunu bildirir.

NoSQL veritabanları, bölümleme çözümlerinin bir karışımıdır. Bazen bölümlenen "tablolar" (veya daha yaygın olarak "koleksiyonlar") olur. Diğer zamanlarda "satırlar" (veya "belgeler"). Bazı durumlarda , HBase gibi sütun odaklı bir veritabanında olduğu gibi, aslında sütunlardır . Bu tamamen kullandığınız teknolojiye bağlıdır. Bunların ortak noktası olan tek şey, motorun kendisinin hepsini takip etmesidir, bu yüzden tek yapmanız gereken bir belge veya satır istemektir.

Tabii ki, sadece bir sürü farklı veritabanı oluşturmakla kalmayıp, parçalama özelliklerini kullandığınız varsayılıyor. Eğer ikincisini yapıyorsanız, kendi başınızasınız.

Uygulama kodunun bir veya daha fazla veritabanının birden çok sunucuya dağıtıldığını bilmesi gerekiyor mu? Değilse, talepler hangi düzeyde filtrelenir?

Farklı mantıksal veritabanlarıysa, evet. Sadece fiziksel olarak dağıtılmışlarsa, ya özel veritabanınızın yerel olarak gölgelemeyi desteklediğini ya da bir yük dengeleme çözümü kullandığınızı (SQL veritabanları için) varsayalım. Ayrıca tüm operasyonlarınızın vatansız olduğunu varsayarsak; yatay ölçeklendirme istiyorsanız, ACID'den vazgeçmeniz gerekecektir.

1 veritabanı / 1 sunucu kurulumunun ötesine geçme zamanı ne zaman? Bunu yapmak ne kadar yaygındır?

Tek bir sunucuda yapabileceğiniz her şeyi optimize ettiğiniz ve G / Ç yükündeki kısıtlamalar nedeniyle hala yeterli performansı elde edemediğiniz zaman. Soruyu sormanız gerekiyorsa, o zaman çok erken.

İyi bir RDBMS ürünündeki (Oracle, SQL Server) performans sorunlarının kötü tasarım, kötü dizin oluşturma, kötü sorgular, kilit çekişmesi vb. bu ürünler dikey olarak saçma bir dereceye kadar ölçeklenebilir. Bu nedenle, performans sorunlarınızın yalnızca bir alt-par tasarım / uygulamadan değil, donanım sınırlamalarından kaynaklandığından kesinlikle eminseniz "1 veritabanı / 1 sunucu kurulumunun ötesine geçmeyi" düşünmelisiniz .

Ya da, bazı insanların dağıtılmış veritabanlarına geçmesinin bir başka nedeni, lisanslama ücretlerinde çok (veya herhangi bir) para ödemeye hazır olmadıkları ve artan uygulama karmaşıklığı için düşük maliyeti işlemek için SQL'i bilinçli bir seçenek olarak atmak istedikleri zaman. Bir yazılım başlangıcıysanız ancak genellikle şirket sektöründe geçerli değilse, tamamen geçerli neden.


+1 - Gerçekten NoSQL'i düşünmüyordum, ama bu da aynı şekilde yardımcı oluyor. Teşekkürler.
VirtuosiMedia

1

Veritabanları için üç ana çoğaltma yapılandırması türü vardır:

  • Köle başı
  • Usta-Master
  • Uzlaşma

Master-Slave örneği: MySQL master + MySQL slave'leri, MongoDB

Master-Master örneği: CouchDB, Cassandra, Riak

Fikir birliği örneği: ScalienDB

...birkaç isim.

Bunlar farklı özelliklere sahiptir. Master-slave yapılandırmaları, slave düğümlerin okuma hızlarını çok hızlı bir şekilde sunarken slave düğümlerin master'a maksimum hızda yetişmesine izin verirken, ana sunucu veri bütünlüğünden sorumludur. Tüm yazma işlemleri ustaya gittiği için, çekişmeyi asla kilitlemez, çünkü nispeten yavaş tek bir yazar birçok okuyucuyu engeller, ancak diğer taraftan, bağımlı sunucular sonunda tutarlıdır ve sahip olacağınız işlem yalıtım garantisini alamazsınız. sadece efendiden okumaktan. (daha fazla okuma; ACID vs BASE, İşlem yalıtım düzeyleri, veritabanı çoğaltma, MVCC / Yalıtım: Anlık Görüntü, İşlemsel Çoğaltma)

Master-Master her zaman yazma işlemlerine izin verir, bu yüzden neyin doğru olduğuna dair birden fazla yetkiniz olur. Bu, uygulamanızın ne yaptığına bağlı olarak bir sorun olabilir veya olmayabilir, ancak çakışan veriler yazarsanız, bir dahaki sefere uygulama mantığı ile birleştirmeniz gereken anahtar / satır / sütunu okuduğunuzda birden fazla sonuç alabilirsiniz. veritabanına geri kaydedin. (daha fazla okuma: CAP teoremi, CouchDB replikasyonu, Riak replikasyonu, tutarlı karma, Bitcask & StormDB, ağ bölünmesinde Quorum- w / MongoDB, birleştirme çözünürlüğü stratejileri)

Scalien gibi düğümler arasında çoğaltma yapılan konsensüs tabanlı veritabanları her zaman yazma konusunda tutarlı olur, ancak yazma işlemini ACKing yapmadan önce birden fazla ileti alışverişi pahasına olur. Hızlı bir ethernet'iniz varsa ve ACKing'den önce diske yazmanız gerekmiyorsa, bu çok sorun değil, en az üç sunucunuz ayrı güç kaynaklarına sahip farklı sunucu raflarındaysa (bir tane) ölür; diğer ikisi diske kaydettiklerinden emin olur). (daha fazla okuma; PAXOS, PAXOS COMMIT, dağıtılmış işlemlerle iki fazlı taahhüt, üç fazlı taahhüt)

Çeşitli okumalar: (kitap: 'Dağıtılmış Hesaplamanın Öğeleri', vektör saatler, sürüm vektörleri, matris vektörleri, mantıksal saatler, fırın algoritması, aralık ağacı saatleri, aktörler ve reaktif programlama ve reaktörler, yazılım işlem belleği, işlemciler, AKKA, Stact, dağıtılmış bilgi işlem yanlışlıkları, dedikodu protokolleri, Cassandra'nın entropi karşıtı dedikodu protokolü uzantıları, dağıtılmış karma tablolar, dağıtılmış bir ortamda veri birleştirme kağıtları, ZooKeeper mimarisi, "eşzamansız protokol" hakkında InfoQ sunumu, HBase mimarisi, MapReduce kağıdı, Amazon Dinamo kağıdı tüm NoSQL öğelerini, kuyruğu, rabbitmq yüksek kullanılabilirlikli kümelemeyi başlatan)

Umarım düşünce için yiyecek verdim :). Bu şeyler hakkında da tweetler istiyorsan beni twitter @henrikfeldt'dan takip edebilirsin.


1

Tamam, bu yüzden ölçeklenebilirlik üzerine başka bir bakış açısı.

İşlerin veri olmasının ne anlama geldiğini, davranışa sahip olmanın ne anlama geldiğini ve uygulama mantığına sahip olmanın ne anlama geldiğini tartışalım.

Normalde, bir kişi kurumsal uygulamalar ve benzerlerinin diyarına girdiği zaman, katmanlaşma fikrine maruz kalırdı. Tabii ki, katmanlama, ağ yığını (ISO modeli) veya grafiklerde (Photoshop) veya SOA'da (hizmetler kardeşleri veya çocukları arayabilir, ancak asla ebeveynleri arayamaz) bilgisayarlarda her yerde bulunur.

Ancak, ne olursa olsun istismar edilen spesifik katmanlama türü 'GUI', 'Business Logic Layer' ve ardından 'Data Access Layer'. Yani, evet, fikir prensipte iyidir, komünizm prensipte iyidir, ama gerçekte değildir.

Neden olduğuna bir bakalım. Kullanacağım argüman eşleştirme ile ilgili; bir katmandaki noktalar başka bir katmandaki noktalara dokunur. İnsanların girdiği varsayılan giriş modunda n katmanlı bir katmanlı uygulama oluşturmaya başladığınızda, katmanlar arasında çok fazla temas noktası yaratırlar.

Özünde, katmanlar birbirinin yerine geçebilir; ama değiller! Neden? Tüm çağrı sitesi bağlantısı nedeniyle.

Bunun yerine, ağın neden ayrıldığına bir göz atın! Arayüz açık bir sokete işaret eden tek bir dosya tanıtıcısı üzerinde bir bayt akışı olduğu için! ISO modellerindeki tüm katmanlar, 'sorumluluk zinciri' olarak adlandırılan tasarım modelinin nesne yönelimi için olduğu gibidir! Her katman, alttaki katmandaki verilerin anlamını bilmeden, alttaki katmanı sarar.

Bir veri paketi altta ethernet ve ham elektrik sinyallerine doğru yürürken, yalnızca kendi özel mesaj zarfını, gönderebileceği kendi özel 'bayt yığınını' bilen katmanlarla sürekli sarılır; ve başka hiçbir şey. Paketin içeriğine bağlı olarak çağrı yollarını değiştirmeye gerek yoktur.

Bunu, katmanlarınızı veritabanına giderken bir 'çağrı' ile uygulama katmanlarınızdaki çağrı yolunu değiştirmek zorunda kalacağınız n-katman ile karşılaştırın - örneğin, 'altın müşteriler' polimorfik olarak 'normal müşterilerin' üst kümesidir ve böylece 'alt-sınıf başına tablo' kullandığımız için, şimdi verilerin (varlık) katmanları gezdiğini bilmeliyiz; hem sözde 'iş mantığı katmanında' hem de gerçekte tasarrufu yapan veri katmanında.

Bilgi işlem açısından ne ölçeklenebilir ne de optimumdur.

Neden ölçeklenebilir değil? Mimari birleştiğinden ve hala birçok düğüme ölçeklendirmeye çalıştığınız eski DB'nin içindesiniz! Ancak, bunun için ACID'e ihtiyacınız olduğu için, bu ve üçüncü bir varlığa (veri nesnesi) bunları işlem yapan tek bir veritabanında bulundurmanız gerekir!

Doğru, yani bu yolun dışına çıktı; başka hangi yollar var?

'SOA' denilen nefret kısaltması, yani hizmet odaklı mimari var. Tabii ki, dünyadaki Tomas Erls, tüm katmanlarınızı XML veya SOAP ile uygulamanızı sağlar.

Yukarıdaki tüm nedenlerden dolayı, bu yanlış bir yoldur, çünkü kendinizi yukarıda açıklandığı gibi uygulama katmanlarıyla eşleştirdiğiniz gibi kendinizi bu XML proxy'lerine bağlarsınız.

Bunun yerine, mesajlaşmayı kullanın ve onlar için işlevsellik uygulayan her şeyi bırakın, dinleyin. Daha sonra servis yüzeyiniz gönderebileceğiniz mesajların bir listesi haline gelir ve operasyonlarınızı servis cephenize bağlamazsınız; ve bu işlemleri hangi uygulamanın veya uç noktanın uyguladığını bilmenize bile gerek yoktur, çünkü yaptığınız tek şey başka bir yönlendirme mekanizmasının doğru tüketiciye yönlendirileceğini bildiren bir mesaj yayınlamaktır!

Hizmet cephelerini gerçekleştirmek istediğiniz gerçek işlemlerden ayırdığınız için, artık birden çok hizmet ekleyebilirsiniz; aslında Netflix bunu böyle yapıyor. Şu sunumlara bir göz atın: http://www.slideshare.net/adrianco/global-netflix-platform . http://www.slideshare.net/adrianco/global-netflix-platform . Onlar iyi!


0

Bir bulunmaktadır yeni SQL (ASİT) veritabanı elastik ölçekleme özelliklerine sahip olduğu iddia edilmektedir beta. Şu anda devam eden ücretsiz bir beta program var ve bir göz atmanızı öneririm, buna NuoDB denir.

Görünüşe göre, tek bir dişli makinede bile MySQL'den daha iyi performans gösteriyor, ancak belirli kriterlerde 70'ten fazla örneğe mutlu bir şekilde ölçekleniyor.


Tek bir iplik mi? Öyleyse bu nasıl alakalı bir kriterdir?
Henrik
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.