sharl del database del server sql - cosa fare con dati comuni / dati non condivisi


10

Abbiamo un database di livello aziendale su larga scala. Come parte del nostro modello di business, tutti gli utenti Web colpiscono i nostri server Web ogni mese allo stesso tempo, il che a sua volta martella la nostra casella sql. Il traffico è molto intenso e continua a crescere più pesante quanto più cresce l'azienda. l'ottimizzazione di sql proc è stata eseguita e l'hardware è già stato ridimensionato a un livello molto alto.

Stiamo cercando di frammentare il database ora per assicurarci di poter gestire la crescita dell'azienda e i carichi futuri.

Abbiamo deciso quali dati particolari dovrebbero essere suddivisi. È un sottoinsieme del nostro database molto utilizzato.

Tuttavia, la mia domanda riguarda i dati non condivisi che sono comuni / universali. Un esempio di dati come questo può essere una tabella di inventario, ad esempio o una tabella dei dipendenti, una tabella degli utenti, ecc.

Vedo due opzioni per gestire questi dati comuni / universali:

1) design 1 - Posiziona i dati comuni / universali in un database esterno. Tutte le scritture verranno eseguite qui. Questi dati verranno quindi replicati fino a ciascun frammento consentendo a ciascun frammento di leggere questi dati e unirli internamente a questi dati in procs t-sql.

2) design 2 - Dai a ogni frammento la propria copia di tutti i dati comuni / universali. Consentire a ogni frammento di scrivere localmente su queste tabelle e utilizzare la replica di unione sql per aggiornare / sincronizzare questi dati su tutti gli altri frammenti.

preoccupazioni per il design n. 1

1) Problemi transazionali: se si verifica una situazione in cui è necessario scrivere o aggiornare i dati in un frammento e quindi scrivere / aggiornare una tabella comune / universale in 1 proc memorizzato, ad esempio, non sarà più possibile farlo facilmente. I dati ora esistono su istanze e database sql separati. Potrebbe essere necessario coinvolgere MS DTS per vedere se è possibile racchiudere queste scritture in una transazione poiché si trovano in un database separato. Le prestazioni sono una preoccupazione in questo caso e potrebbero essere coinvolte possibili riscritture per i proc che scrivono su dati condivisi e comuni.

2) una perdita di integrità referenziale. Non è possibile eseguire l'integrità referenziale tra database.

3) Ricodifica di vaste aree del sistema in modo che sappia scrivere dati comuni nel nuovo database universale ma leggere dati comuni dai frammenti.

4). aumento dei viaggi nel database. Come il n. 1 sopra, quando si verifica una situazione in cui è necessario aggiornare i dati condivisi e i dati comuni, si effettueranno più round trip per ottenere ciò poiché i dati si trovano ora in database separati. Un po 'di latenza di rete qui, ma non sono preoccupato per questo problema tanto quanto sopra 3.

preoccupazioni per il design n. 2

Nel progetto n. 2 ogni frammento ottiene la propria istanza di tutti i dati comuni / universali. Ciò significa che tutto il codice che unisce o aggiorna i dati comuni continua a funzionare / eseguire esattamente come avviene oggi. Il team di sviluppo necessita di pochissime ricodifiche / riscritture. Tuttavia, questo design dipende completamente dalla replica di unione per mantenere i dati sincronizzati tra tutti i frammenti. i dbas sono altamente qualificati e sono molto preoccupati che l'unione della replica potrebbe non essere in grado di gestirla e che la fusione non riesca, che il recupero da questo errore non è eccezionale e potrebbe avere un impatto molto negativo su di noi.

Sono curioso di sapere se qualcuno ha scelto l'opzione di progettazione n. 2. Sono anche curioso di sapere se sto trascurando una terza o quarta opzione di design che non vedo.

Grazie in anticipo.


10
In questo caso, che cos'è "un database aziendale su larga scala" e hardware che "è già stato ridimensionato a un livello molto elevato"? 10 volte su 10, lo sharding non è la soluzione, quindi chiediti quale sia il problema che stai risolvendo.
Mark Storey-Smith,

5
In tutta serietà, dici che i tuoi server web "martellano" la tua casella SQL. Quale rapporto viene letto: scrivi? Esistono molti, molti modi per ridimensionare le letture senza sharding, con compromessi per prestazioni, costi o complessità a seconda di quanto devono essere realmente attuali i dati. E, naturalmente, ci sono modi per mettere in coda le scritture, sempre a seconda di quanto devono essere aggiornati i nanosecondi.
Aaron Bertrand

3
Questa particolare affermazione ha attirato la mia attenzione, "l'hardware è già stato ridimensionato a un livello molto elevato". Cosa è andato in questo ridimensionamento hardware?
sweckeck,

2
Hai 64 processori logici e la CPU è il collo di bottiglia? Cosa significa esattamente guidare la CPU, ricompilare? Lo sai?
Aaron Bertrand

1
Controlla i pantaloni quando hai finito lo sharding.
cambio il

Risposte:


5

La tua domanda si è concentrata su questo:

Tuttavia, la mia domanda riguarda i dati non condivisi che sono comuni / universali. Un esempio di dati come questo può essere una tabella di inventario, ad esempio o una tabella dei dipendenti, una tabella degli utenti, ecc.

Quando esegui il sharding e disponi di dati che devono essere visualizzati da tutti i frammenti, devi classificarli con alcuni attributi:

Cambia frequentemente? Nei tuoi esempi, hai elencato Inventario, Dipendente e Utente. In genere l'inventario cambia molto rapidamente, ma i record dei dipendenti cambiano solo periodicamente (diciamo, alcune centinaia di aggiornamenti al giorno).

Quanto ritardo può tollerare ogni frammento?Anche se l'inventario può cambiare costantemente, in genere è possibile tollerare una grande quantità di ritardo (minuti o persino ore) su una tabella del genere. Se vendi articoli unici con una quantità molto limitata che non puoi mai rifornire (pensa alle opere d'arte originali), allora non dividi affatto quei dati: esegui solo una query nel database originale. Tuttavia, nella maggior parte dei negozi online, non vendi tutti gli articoli ogni giorno e rifornirai comunque rapidamente le cose, quindi non hai davvero bisogno di conteggi fino al millesimo di secondo. In effetti, nella maggior parte dei casi, hai solo bisogno di un flag In-Stock che è 0 o 1 e un processo centrale aggiorna quel flag. In questo modo, non è necessario eseguire il push di ogni urto su / giù del conteggio degli oggetti su ogni frammento. Dipendenti o dati utente, d'altra parte,

Ti unirai dai tavoli a più tavoli a quelli non a più livelli? Idealmente, la risposta qui è no: dovresti fare due query separate per ottenere i dati e poi unirli sul lato app. Questo diventa molto più difficile dal punto di vista dell'app, ma ti dà la possibilità di ottenere i dati più aggiornati da ogni fonte.

Questi dati originali sono stati copiati?Un altro modo di pensare a questa domanda: di cosa hai bisogno per eseguire il backup e con quale frequenza? In genere in un ambiente di sharding ad alto volume, si desidera che i backup siano il più rapidi e piccoli possibile. (Dopotutto, devi proteggere ciascun nodo e vuoi che tutti i frammenti eseguano il failover su DR nello stesso momento nel tempo, non avere alcuni frammenti con dati più recenti di altri.) Ciò significa che i dati frammentati e i non- i dati frammentati dovrebbero trovarsi in database completamente separati, anche se si trovano sullo stesso server. Potrei aver bisogno di backup costanti del registro delle transazioni dei miei dati condivisi (originali), ma potrebbe non essere necessario eseguire il backup dei dati non condivisi. Probabilmente per me è più semplice aggiornare la mia tabella Employees o Users dalla singola fonte di verità piuttosto che eseguirne il backup su ogni frammento. Se tutti i miei dati si trovano in un unico database, tuttavia,

Ora, riguardo alle tue preoccupazioni:

"Problemi transazionali ... non sarai più in grado di farlo facilmente." Corretta. In scenari ristretti, getta il concetto di transazione fuori dalla finestra. Peggiora anche: per i dati frammentati, potresti avere un frammento attivo e online e un altro frammento temporaneamente temporaneo a causa di un failover o riavvio dell'istanza del cluster. È necessario pianificare il fallimento di qualsiasi parte del sistema, in qualsiasi momento.

"Impossibile eseguire l'integrità referenziale tra database." Corretta. Quando si suddivide una singola tabella su più server, si indossano i pantaloni grandi e si dice al server di database che si sta assumendo incarichi difficili come backup point-in-time, relazioni tra tabelle e combinazione di dati da più fonti. Ora tocca a te e al tuo codice.

"Ricodifica ampie aree del sistema in modo che sappia scrivere dati comuni nel nuovo database universale ma leggere dati comuni dai frammenti." Corretto anche qui. Non c'è un pulsante facile per questo, ma una volta che lo hai inserito nell'app, puoi ridimensionarlo come un matto. Direi che il modo più semplice per farlo è dividere le connessioni dell'app per letture .

"aumento dei viaggi nel database." - Sì, se si suddividono i dati in più server, l'app dovrà raggiungere di più la rete. La chiave è implementare anche la memorizzazione nella cache in modo che alcuni di questi dati possano essere archiviati in sistemi a basso costo, con throughput più elevato e senza blocco. La query più veloce è quella che non fai mai.

Ho anche presentato più vantaggi e svantaggi nella suddivisione di database multi-tenant qui , come l'ottimizzazione delle prestazioni su singoli frammenti, diverse strategie di backup / recupero per frammento e sfide di distribuzione dello schema.


0

Ad un livello elevato, il modo tipico di condividere (o partizionare orizzontalmente) i dati è quello di condividere le tabelle transazionali e replicare le tabelle di livello principale. Come la maggior parte delle soluzioni tecnologiche, questo ovviamente risolve una serie di problemi e crea una serie completamente nuova di problemi ... ma ormai ci siamo tutti abituati, vero? ;-)

Mi chiedo comunque se SQL Server sia la soluzione migliore per questo. Il carico di lavoro è più simile a OLTP o più come DW / BI?

Saluti, Dave Sisk


-2

Una possibile terza opzione. Utilizzando lo sharding relazionale (anziché lo sharding black box), dovresti essere in grado di eseguire lo shard e distribuire l'intero database. Poiché è basato su un tradizionale modello di dati relazionali, il database conosce quali dati sono archiviati su quali server e quindi dove trovarli, quindi tutti i tuoi dati possono essere considerati "comuni / universali". Dai un'occhiata a dbShards come possibilità per semplificare l'intero processo di sharding.


3
Questa risposta non ha senso senza una spiegazione di sharding relazionale, sharding black box, cosa fanno, perché uno è migliore dell'altro e, preferibilmente, un'ammissione che il tuo datore di lavoro è dbShards.
Geremia Peschka,
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.