Bir SQL sunucusuna ekleyebileceğiniz veritabanı sayısında bir sınır var mı?


43

Her müşteriye kendi veritabanını vermeyi planladığımız bir SaaS sistemi kuruyorum. Sistem zaten kuruludur, böylece yük çok fazla olduğunda kolayca ek sunuculara kolayca ölçeklenebiliriz; Binlerce hatta on binlerce müşterimiz olmasını umuyoruz.

Sorular

  • Bir SQL Server'da sahip olabileceğiniz / sahip olmanız gereken mikro veri tabanlarının sayısı konusunda pratik bir sınırlama var mı?
  • Sunucunun performansını etkileyebilir mi?
  • Her biri 100 MB'lık 10.000 veritabanına veya 1 TB'lik bir veritabanına sahip olmak daha mı iyidir?

Ek bilgi

"Mikro veritabanları" derken gerçekten "mikro" demek istemiyorum; Sadece binlerce müşteriyi hedeflediğimizi kastediyorum, bu nedenle her bir veritabanı toplam veri deposunun sadece binde biri veya daha azını oluşturur. Gerçekte, her bir veritabanı ne kadar kullanım alacağına bağlı olarak 100 MB civarında olacaktır.

10.000 veritabanı kullanmanın ana nedeni ölçeklenebilirliktir. İşin aslı, sistemin V1'inin bir veritabanı var ve DB yük altında zorlanırken rahatsız edici anlar yaşadık.

Yukarıdakilerin hepsi CPU, bellek, G / Ç'yi zorluyordu. Bu sorunları çözmemize rağmen, bir noktada, dünyadaki en iyi endekslemeyle bile, fark etmeyi umduğumuz kadar başarılı olursak, tüm verilerimizi tek bir büyük topluluğa koyamayacağımızı anlamamızı sağladılar. 'veritabanı. Yani V2 için biz paylaştık, bu yüzden yükü birden fazla DB sunucusu arasında bölebiliriz.

Geçen yılı bu keskin çözümü geliştirmek için harcadım. Sunucu başına bir lisans, ancak yine de Azure'da VM kullandığımızdan beri halledilir. Sorunun ortaya çıkmasının nedeni, daha önce sadece büyük kurumlara teklif vermemiz ve her birini kendimiz kurmamızdı. Bir sonraki işimiz, tarayıcıya sahip herhangi birinin kaydolacağı ve kendi veritabanını oluşturabildiği bir self servis modelidir. Veri tabanları büyük kurumlardan çok daha küçük ve çok daha fazla olacaktır.

Azure SQL Database Elastic Pools'u denedik . Performans çok hayal kırıklığı yarattı, bu yüzden normal sanal makinelere geri döndük.

Yanıtlar:


80

Tek seferde 8 ila 10 bin veritabanına sahip SQL Sunucular üzerinde çalıştım. Güzel değil.

Sunucuyu yeniden başlatmak bir saat veya daha uzun sürebilir. 10.000 veritabanı için kurtarma işlemini düşünün.

Nesne Gezgini'nde güvenilir bir veritabanı bulmak için SQL Server Management Studio'yu kullanamazsınız.

Yedekler bir kabustur, çünkü yedeklemelerin değerli olması için uygulanabilir bir felaket kurtarma çözümüne sahip olmanız gerekir. Umarım ekibiniz her şeyi yazmakta harikadır .

Veritabanlarını M01022, ve gibi sayılarla adlandırmak gibi şeyler yapmaya başlarsınız T9945. Doğru veritabanında çalıştığınızdan emin olmak, örneğin M001022bunun yerine M01022çıldırtıcı olabilir.

Bu veritabanları için bellek tahsis etmek çok acı verici olabilir; SQL Server, performansta gerçek bir sürükleme olabilecek çok fazla G / Ç işlemi gerçekleştirir. 10.000 şirket için 4 tabloda karbon kullanım ayrıntılarını kaydeden bir sistem düşünün. Bunu bir veritabanında yaparsanız, yalnızca 4 tabloya ihtiyacınız vardır; Bunu 10.000 veritabanında yaparsanız, aniden hafızasında 40.000 tabloya ihtiyacınız vardır. Bellekteki bu sayıdaki tablolarla başa çıkmanın ek yükü büyüktür. Bu tablolara göre tasarlanacak herhangi bir sorgu , kullanımda 10.000 veritabanı varsa, plan önbellekte en az 10.000 plan gerektirir .

Yukarıdaki liste, bu tür bir ölçekte çalışırken planlamanız gereken küçük bir problem örneğidir.

Muhtemelen SQL Server Hizmeti gibi şeylerin başlaması çok uzun zaman alıyor ve bu da Service Controller hatalarına neden oluyor. Hizmetin başlangıç ​​zamanını kendiniz artırabilir, aşağıdaki kayıt defteri girdisini oluşturabilirsiniz:

Alt anahtar: HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Control
İsim: ServicesPipeTimeout
Tür: REG_DWORD
Veri: Hizmet başlangıcı sırasında zaman aşımından önce geçen milisaniye sayısı

Örneğin, hizmet zaman aşımına uğramadan önce 600 saniye (10 dakika) beklemek için 600000 yazın.


Cevabımı yazdığımdan beri, sorunun Azure hakkında konuştuğunu anladım. Belki de bunu SQL Veritabanında yapmak o kadar problemli değildir; belki daha problemlidir. Şahsen, muhtemelen tek bir veritabanı kullanarak, belki de birden çok sunucuya dikey olarak bölünmüş bir sistem tasarlarım, ancak kesinlikle müşteri başına bir veritabanı değil.


3
İyi şeyler. Poster, birden çok veritabanı kullanma yöntemini düşünebilir, ancak veritabanı başına birden çok müşteri, böylece veritabanı sayısını sınırlayabilir, ancak yine de birden çok sunucuya ölçeklendirebilir.
Tony Hinkle

5
Şu anda yüksek 4 rakamda DB sayımı olan bir örneği yönetiyorum ve bunların hepsini ekolayabiliyorum. Bu ölçekte çalışırken ortaya çıkan bir diğer sorun, yürütme planlarını uzun süre önbelleğe alamamasıdır. Sonuç, çok sayıda CPU yanması yeniden derleme sorgusu planı.
alroc

19

Yani her iki yöntemin de Artıları ve Eksileri var. Başvurunuz veya sağlamak istediğiniz hizmetler hakkında daha fazla bilgi olmadan kesin bir cevap veremem ama konuyla ilgili bazı düşüncelerimi atacağım.

Neden tüm müşterileriniz için 1 Veritabanı kullanmanız gerektiğine dair davam.

Artıları

  • Kolay bakım. Bir DB'ye sahip olmak, bakım görevinizi birçok yerine tek bir yerde yapmanız gerektiği anlamına gelir. Yedeklemek için 1000 farklı veritabanını kullanmanın kabusunu hayal edin. 1000 DB'nin veya yeniden oluşturma endekslerindeki istatistiklerin güncellenmesine ya da DBCC CHECKDB?

  • Kod Dağıtımı. Diyelim ki uygulama kodunuzda veya raporlamada saklı bir prosedürle ilgili bir probleminiz var. Hızlı bir değişiklik yapmanız gerekiyor ... Şimdi bu değişikliği 1000+ DB'ye dağıtmanız gerekiyor. Hayır, teşekkürler, istemem.

  • Kolay Görünürlük Sadece 1000'den fazla DB'yi (titreme) açmaya çalışırken SSMS'yi hayal edin . Bu sorunu pratik olarak işe yaramaz hale getirir ve SSMS'yi açmak ve açmak için şaşırtıcı bir zaman alır. Unutma, eğer uygun bir adlandırma kuralı bulabilirseniz.

Eksileri

  • Güvenlik. Ayrı DB'ler olsaydı, kişilerin diğer müşterilerin verilerine bakmasını önlemek daha kolay olurdu. Ancak bunun olmasını önlemek için yapabileceğiniz bazı basit şeyler var.

  • Verim. Müşteri başına bir DB'nin sınırlandırılmasının, SQL sunucusunun sorguladığınız bilgileri almak için daha az veri taraması gerektiği anlamına geldiği iddia edilebilir. Bununla birlikte, uygun veri yapısı ve iyi indeksleme (ve olası bölümleme) ile, dikkatli bir şekilde yapılırsa, bunu bir arada problem olarak ortadan kaldırabilirsiniz. Müşteriye özel veriler içeren her tabloya, CompanyIDbu ek yükü azaltmak için bir tür lider olmasını tavsiye ediyorum .

Sonuçta en iyi bahsinizin sizin için bir tane DB olması ve sadece DB'nin içindeki müşteri verilerini bölmek olduğunu düşünüyorum. Size vereceği sıkıntılar, 1000'den fazla veritabanını yönetmenin kabusu ile kıyaslandığında hiçbir şey olmayacak.


17

SQL Server için Maksimum Kapasite Spesifikasyonları , 32.767 sınırının olduğunu belirtir.

Performansı etkileyip etkilemeyeceğine gelince, cevap evet, ancak performansı etkileyeceği ve önemli olup olmayacağı çok sayıda faktöre bağlı olacaktır.

10.000 veritabanına ayırmak için iyi bir neden olmadığı sürece tek bir veritabanı ile giderdim. Bir yedek veya 10.000 yedek? Bir bütünlük kontrolü veya 10.000? 10.000 küçük veritabanı kullanmak için iyi bir neden olabilir, ancak bunu belirlemek için yeterli ayrıntı vermediniz. İstediğiniz soru oldukça geniştir ve kimsenin en iyi cevabın ne olduğunu bilmesi için yeterli bilgi yoktur.


7

Burada bahsettiğiniz şey çok kiracı vs çoklu örnek mimarisi. Sorunuzda kullanmadığınız için bu terimleri getiriyorum, ancak tartışacağınız şeye bu denir ve "çok kiracılı mimariyi" Google’a eklerseniz, zengin kaynaklar ve tartışmalar bulacaksınız. Bu konuda, tüm kitaplar üzerine yazılmıştır.

Özellikle burada SQL Server ile ilgili bazı iyi kaynaklar:

https://msdn.microsoft.com/en-us/library/ff966499.aspx

https://docs.microsoft.com/en-us/azure/sql-database/sql-database-design-patterns-multi-tenancy-saas-applications

Ben yalın ki ben, diğer yanıtlarla olacağını kuvvetle çoklu örneğini lehine zorlayıcı nedenler olmadıkça, varsayılan olarak çok kiracı doğru.

Ölçeklendirmek için binlerce bireysel veri tabanına ayrılmanıza gerek yok, bunu yapmanın daha pek çok yolu var. Küme oluşturma, çoğaltma, paylaşma, bölme vb. Gibi. Tekerleği yeniden icat etmeyin. Bunu kendiniz bireysel bir müşteri düzeyinde kendiniz el ile bölmeniz gerektiğini söyleyen hiçbir şey yoktur ve gerçekten bunu yapmanız her yeni müşteriyi eklemenin maliyetini önemli ölçüde arttırır.

Bir milyonlarca müşteriden bahsediyorsunuz, herhangi bir büyük ölçekli bulut tabanlı yazılımı bir hizmet olarak düşünün, Gmail, ne olursa olsun, her yeni kayıt için tamamen yeni bir veritabanı oluşturduklarını düşünmüyorsunuz, ya şimdi?

Bunu kolaylaştırmak istemenizin nedenleri olabilir, örneğin, ürününüzü kendi altyapısı ile kendi bünyesinde barındırması gereken bir müşteriye satıyorsanız. Ancak genel bir SAAS kuralı olarak, çok kiracılı bir mimariye varsayılan olarak dayanmak.


7

Tek veritabanı önerisinde görebildiğim olumsuz noktalardan biri, verileri geri almaktır. Kiracı kurulumu başına bir veritabanınız varsa, her müşterinin verilerini bağımsız olarak geri yükleyebilirsiniz (ve belirli bir zamanda). Hepsi tek bir veritabanındaysa, bu daha zorlaşır (ve muhtemelen INSERT / UPDATE / DELETE ifadeleriyle yapılması gerekebileceği için hataya meyillidir).


+1 - Bu, kiracı başına bir veritabanına sahip olmanın çok arzulanan faydalarından biridir.
Max Vernon

6

Cevap veren herkese teşekkürler - bana düşünmeniz için verdiğiniz noktaları takdir edin. Elimdeki genel duygu, tek bir veri tabanının tercih edilebildiği yönündeydi, ancak parçalı mimari lehine bazı telafi edici noktalar eklemek ve başkalarının bahsettiği bazı kaygıları gidermek istiyorum.

Paylaşım için motivasyon

(Güncellenmiş) sorusunda belirtildiği gibi, dünya çapında milyonlarca kullanıcıyla büyük satışlar yapmayı hedefliyoruz. Dünyadaki en iyi donanım ve indeksleme ile, tek bir DB sunucusu bu yükü almayacak, bu yüzden birden fazla sunucuya dağıtabilmeliyiz. Ve herhangi bir müşterinin verisinin hangi sunucuda olduğuna bakmak zorunda kaldığınızda, onlara tahsis edilmiş bir veri tabanı oluşturmak çok fazla bir iş değildir;

Endişelere Tepki

  • Sunucuyu yeniden başlatmak uzun zaman alıyor: Tamam, ancak normal işletimde herhangi bir sunucuyu yeniden başlatmayı düşünmüyoruz. Sistem nihayetinde 7 gün 24 saat çevrimiçi olmalıdır, bu nedenle aksama süremiz varsa, zaten planlanmış olması gerekir.
  • Yedekleme / olağanüstü durum kurtarma: Her şeyi otomatikleştiren CloudBerry kullanıyoruz. Problem değil.
  • Veritabanlarını adlandırmak / SSMS'ye yerleştirmek: Adlandırma kuralı, yalnızca müşteri adına göre kolaydır. İsimler paylaşılıyorsa seri rakam ekleyin.
  • Bakım: Her veritabanı benim düşündüğüm kadar küçükse, dizinleri manuel olarak yeniden oluşturmaya gerek yoktur.
  • Kod dağıtma: Entity Framework kullanıyoruz, böylece her şema değişikliği otomatik olarak her sürüm için yeni sürümlerle birlikte dağıtılacak. Yine de, basit bir endeks ayarlamasıyla düzeltilebilecek üretimde bir performans sorununu keşfedersek, sadece onu oraya itmek kolay değildir. Öte yandan, her veritabanı çok küçükken, üretim parçalarında showtopper performans sorunları oluşması pek olası değildir. Ve ortak veritabanı, bu endişelerin uygulanmadığı tek bir DB olarak kalmaktadır.

Herhangi bir şeyi kaçırdığımı düşünüyorsanız, sizden yorumlarda sizleri tekrar duymaktan mutlu olurum!


3
Eğer 7 gün 24 saat çalışıyorsanız, veritabanlarınızı kümelemeye bakıyor olmanız gerekir. Sadece yamaların uygulanması, en azından bazı aksama sürelerine neden olacaktır. Bunun Azure gibi bulut tabanlı çözümlere nasıl uygulandığından emin değilim, umarım bunun sizin için halledilir.
Jay Zelos,

Bugünün DB teknolojisini kullanmanın 'sharding' için neredeyse tüm nedenlerin artık geçerli olmadığını düşünüyorum. Yolun aşağısında pişman olacağınıza veya nispeten ne kadar kötü olduğunuzu fark etmeyeceğinize ve dolayısıyla cehaletten pişman olamayacağınıza inanıyorum. Max'in cevabına katılıyorum ve bunu daha iyi açıklayamam.
Joe
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.