Esiste un limite al numero di database che è possibile inserire in un server SQL?


43

Sto configurando un sistema SaaS, dove stiamo pianificando di fornire a ciascun cliente il proprio database. Il sistema è già impostato in modo che possiamo facilmente passare a server aggiuntivi se il carico diventa troppo grande; speriamo di avere migliaia o addirittura decine di migliaia di clienti.

Domande

  • C'è qualche limitazione pratica sul numero di micro-database che puoi / dovresti avere su un SQL Server?
  • Può influire sulle prestazioni del server?
  • È meglio avere 10.000 database da 100 MB ciascuno o un database da 1 TB?

Informazioni aggiuntive

Quando dico "micro-database", non intendo davvero "micro"; Voglio solo dire che puntiamo a migliaia di clienti, quindi ogni singolo database sarebbe solo un millesimo o meno della memoria totale dei dati. In realtà, ogni database si aggirerebbe intorno ai 100 MB, a seconda della quantità di utilizzo che ottiene.

Il motivo principale per utilizzare 10.000 database è per la scalabilità. Il fatto è che V1 del sistema ha un database e abbiamo avuto dei momenti scomodi in cui il DB si stava sforzando sotto il carico.

Stava sforzando CPU, memoria, I / O - tutto quanto sopra. Anche se abbiamo risolto questi problemi, ci hanno fatto capire che ad un certo punto, anche con la migliore indicizzazione al mondo, se avremo il successo che speriamo di essere, semplicemente non possiamo mettere tutti i nostri dati in un unico grande segreto ' Banca dati. Quindi per V2 stiamo condividendo, quindi possiamo dividere il carico tra più server DB.

Ho trascorso l'ultimo anno a sviluppare questa soluzione frammentata. È una licenza per server, ma comunque è stata curata dal momento che stiamo usando VM su Azure. Il motivo per cui la domanda si pone ora è perché in precedenza offrivamo solo a grandi istituzioni e fondavamo ognuna di noi. Il nostro prossimo ordine di attività è un modello self-service in cui chiunque abbia un browser può registrarsi e creare il proprio database. I loro database saranno molto più piccoli e molto più numerosi delle grandi istituzioni.

Abbiamo provato i pool elastici del database SQL di Azure . Le prestazioni sono state molto deludenti, quindi siamo tornati alle VM normali.

Risposte:


80

Ho lavorato su server SQL con 8-10 mila database in un'unica istanza. Non è carino.

Il riavvio del server può richiedere fino a un'ora o più. Pensa al processo di recupero per 10.000 database.

Non è possibile utilizzare SQL Server Management Studio per individuare in modo affidabile un database in Esplora oggetti.

I backup sono un incubo, poiché per fare in modo che i backup siano utili è necessario disporre di una soluzione di ripristino di emergenza funzionante. Spero che la tua squadra sia brava a scrivere tutto .

Inizi a fare cose come nominare database con numeri, come M01022e T9945. Cercare di assicurarsi di lavorare nel database corretto, ad esempio M001022invece di M01022, può essere esasperante.

Allocare memoria per molti database può essere lancinante; SQL Server finisce per eseguire molti I / O, il che può essere un vero freno per le prestazioni. Si consideri un sistema che registra i dettagli sull'uso di carbonio su 4 tabelle per 10.000 aziende. Se lo fai in un database, hai solo bisogno di 4 tabelle; se lo fai in 10.000 database, all'improvviso avrai bisogno di 40.000 tabelle in memoria. Il sovraccarico di gestire quel numero di tabelle in memoria è notevole. Qualsiasi query progettata che verrà eseguita su tali tabelle richiederà almeno 10.000 piani nella cache dei piani se sono in uso 10.000 database.

L'elenco sopra è solo un piccolo campione di problemi che dovrai pianificare quando operi su quel tipo di scala.

Probabilmente ti imbatterai in cose come il servizio SQL Server che impiega molto tempo per avviarsi, il che può causare errori del controller di servizio. Puoi aumentare tu stesso il tempo di avvio del servizio, creare la seguente voce di registro:

Sottochiave: HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Control
Nome: ServicesPipeTimeout
Digitare: REG_DWORD
Dati: il numero di millisecondi prima del timeout durante l'avvio del servizio

Ad esempio, per attendere 600 secondi (10 minuti) prima del timeout del servizio, digitare 600000.


Da quando ho scritto la mia risposta mi sono reso conto che la domanda sta parlando di Azure. Forse farlo sul database SQL non è così problematico; forse è più problematico. Personalmente, probabilmente progetterei un sistema usando un singolo database, forse suddiviso verticalmente su più server, ma certamente non un database per cliente.


3
Roba buona. Il poster potrebbe prendere in considerazione un metodo per utilizzare più database, ma più clienti per database in modo da poter limitare il numero di database, ma essere comunque in grado di scalare su più server.
Tony Hinkle,

5
Attualmente gestisco un'istanza con un conteggio DB nelle cifre in alto 4 e posso fare eco a tutto questo. Un altro problema che si presenta quando si opera su questa scala è l'incapacità di memorizzare nella cache i piani di esecuzione per un lungo periodo di tempo. Il risultato è un sacco di piani di query di ricompilazione della masterizzazione della CPU.
alroc,

19

Quindi ci sono vantaggi e svantaggi di entrambi i metodi. Senza sapere di più sulla tua applicazione o sui servizi che stai cercando di fornire, non sarò in grado di dare una risposta definitiva, ma espanderò alcuni dei miei pensieri in merito.

Il mio caso per cui dovresti usare 1 database per tutti i client.

Professionisti

  • Facile manutenzione. Avere un DB significa che devi solo eseguire le tue attività di manutenzione in una posizione anziché in molte. Immagina l'incubo di gestire 1000 database diversi per il backup. Che ne dici di aggiornare le statistiche su 1000 DB o ricostruire indici o DBCC CHECKDB?

  • Codice di distribuzione. Supponiamo che tu abbia un problema con una procedura memorizzata nel codice dell'applicazione o nei rapporti. È necessario apportare una modifica rapida ... Ora è necessario distribuire tale modifica su oltre 1000 DB. No, grazie, preferirei di no.

  • Visibilità facile Immagina solo SSMS che prova ad aprire 1000+ DB (shudder) . Praticamente renderebbe inutile il problema e richiederebbe una quantità sorprendente di tempo per aprire e rendere SSMS. Tieni a mente, questo è se sei in grado di elaborare una convenzione di denominazione decente.

Contro

  • Sicurezza. Sarebbe più facile impedire alle persone di guardare i dati di altri clienti se li avessi come DB separati. Tuttavia ci sono alcune cose molto semplici che puoi fare per evitare che ciò accada.

  • Prestazione. Si potrebbe obiettare che limitarlo a un DB per cliente significa che il server SQL dovrà scansionare meno dati per ottenere le informazioni che stai interrogando. Tuttavia, con una struttura dei dati adeguata e una buona indicizzazione (e un possibile partizionamento), è possibile eliminarlo come un problema tutti insieme se fatto con attenzione. Consiglierei di dare ad ogni tabella che contiene i dati specifici del cliente una sorta di vantaggio CompanyIDper ridurre tale sovraccarico.

In definitiva, penso che la tua scommessa migliore sia avere un DB per la tua applicazione e suddividere i dati dei clienti all'interno del DB stesso. I problemi che ti darà non saranno nulla in confronto all'incubo della gestione di oltre 1000 database.


17

Le specifiche di capacità massima per SQL Server indicano che esiste un limite di 32.767.

Per quanto riguarda se influenzerà le prestazioni, la risposta è sì, ma i modi in cui influenzeranno le prestazioni e se sarebbero sostanziali dipenderebbero da una miriade di fattori.

Vorrei andare con un database a meno che non ci sia una buona ragione per dividerlo in 10.000 database. Un backup o 10.000 backup? Un controllo di integrità o 10.000? Potrebbe esserci un buon motivo per utilizzare 10.000 piccoli DB, ma non hai fornito dettagli sufficienti per determinarlo. La domanda che hai posto è piuttosto ampia e semplicemente non ci sono abbastanza informazioni per nessuno per sapere qual è la risposta migliore.


7

Quello di cui stai parlando qui è l' architettura multi-tenant vs multi-istanza . Sto solo mettendo in evidenza questi termini poiché non li usi nella tua domanda, ma questo è ciò che stai discutendo viene chiamato e se colleghi semplicemente "architettura multi-tenant" a Google, troverai una ricchezza di risorse e discussioni a riguardo, sono stati scritti interi libri su di esso.

Alcune buone risorse su SQL Server in particolare qui:

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

Starei con altre risposte, in quanto mi spingerei fortemente verso il multi-tenant come impostazione predefinita, a meno che tu non abbia validi motivi per favorire la multiistanza.

Non è necessario suddividere in migliaia di singoli database client per ridimensionare, ci sono molti altri modi per farlo, che sono probabilmente preferibili. Come clustering, replica, sharding, partizionamento ecc. Non reinventare la ruota. Non c'è nulla di intrinseco che dice che è necessario dividerlo manualmente a livello di singolo cliente e, in effetti, è probabile che ciò aumenti significativamente i costi di aggiunta di ogni nuovo cliente.

Stai parlando di "milioni" di clienti, pensi a qualsiasi software su larga scala basato su cloud come un servizio, Gmail, qualunque cosa, difficilmente pensi che creino un database completamente nuovo per ogni nuova iscrizione, adesso?

Ci possono essere motivi per cui si desidera facilitare ciò, ad esempio, se si sta vendendo il prodotto a un cliente che DEVE averlo ospitato internamente sulla propria infrastruttura. Ma come regola generale SAAS, appoggiarsi come impostazione predefinita a un'architettura multi-tenant.


7

Uno dei lati negativi che posso vedere nel suggerimento di un singolo database è relativo al rollback dei dati: se si dispone di un database per impostazione del tenant, è possibile ripristinare i dati di ciascun client in modo indipendente (e in un determinato momento). Se sono tutti in un unico database, questo diventa molto più difficile (e molto più incline all'errore in quanto probabilmente dovrebbe essere fatto tramite le istruzioni INSERT / UPDATE / DELETE).


+1: questo è uno dei pochissimi vantaggi altamente desiderabili di avere un database per tenant.
Max Vernon,

6

Grazie a tutti coloro che hanno risposto: apprezzo molto i punti su cui mi hai dato pensare. La sensazione generale che ho avuto è che fosse preferibile un singolo database, ma vorrei aggiungere alcuni punti compensativi a favore dell'architettura frammentata e affrontare alcune delle preoccupazioni che altre persone hanno menzionato.

Motivazione per lo sharding

Come menzionato nella domanda (aggiornata), puntiamo a enormi vendite in tutto il mondo, con letteralmente milioni di utenti. Con l'hardware e l'indicizzazione migliori al mondo, un singolo server DB non prenderà il carico, quindi dobbiamo essere in grado di distribuire su più server. E una volta che devi cercare su quale server si trovano i dati di un determinato cliente, non è molto più lavoro fornire loro un database dedicato, il che semplifica le cose in termini di segregazione ordinata dei dati delle persone.

Risposta alle preoccupazioni

  • Il riavvio del server richiede molto tempo: OK, ma durante il normale funzionamento non intendiamo riavviare alcun server. Alla fine il sistema deve essere online 24 ore su 24, 7 giorni su 7, quindi se dovremo avere dei tempi di inattività dovrà comunque essere programmato.
  • Backup / disaster recovery: stiamo usando CloudBerry, che automatizza tutto. Non è un problema.
  • Assegnare un nome ai database / localizzarli in SSMS: la convenzione di denominazione è semplice, basata solo sul nome del cliente. Aggiungi cifre seriali se i nomi sono condivisi.
  • Manutenzione: se ogni database è piccolo come immagino, non dovrebbe essere necessario ricostruire manualmente gli indici.
  • Distribuzione del codice: utilizziamo Entity Framework, quindi ogni modifica dello schema verrà automaticamente implementata su ogni database con nuove versioni. È vero, tuttavia, che se scopriamo un problema di prestazioni in produzione che può essere risolto con un semplice ritocco dell'indice, non è così semplice solo spingerlo là fuori. D'altra parte, con ogni database così piccolo, è improbabile che si verifichino problemi di prestazioni di showtopper sui frammenti di produzione. E il database comune rimane un singolo DB, al quale queste preoccupazioni non si applicano.

Sarò felice di sentirti nei commenti se pensi che mi manchi qualcosa!


3
Se stai cercando 24 ore su 24, 7 giorni su 7, devi cercare di raggruppare i tuoi database. Applicare solo le patch comporterà almeno dei tempi di inattività. Non sono sicuro di come questo si applichi a soluzioni basate su cloud come Azure, spero che si occupi di te.
Jay Zelos,

Credo che l'utilizzo della tecnologia DB odierna quasi tutti i motivi del "sharding" non siano più validi. Credo che te ne pentirai lungo la strada o forse non ti renderai nemmeno conto di quanto male sei comparativamente e quindi non te ne pentirai per ignoranza. Sono d'accordo con la risposta di Max e non potrei spiegarlo meglio.
Joe,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.