2009-09-21 3 views
24

Sono responsabile dello sviluppo e della manutenzione di un gruppo di applicazioni Web incentrate su dati simili. L'architettura che ho deciso al momento era che ogni applicazione avrebbe il proprio database e l'applicazione web-root. Ogni applicazione gestisce un pool di connessioni al proprio database e un database centrale per dati condivisi (accessi, ecc.)Strategia del pool di connessioni: buona, cattiva o brutta?

Un collaboratore ha postulato che questa strategia non verrà ridimensionata perché non ci saranno così tanti diversi pool di connessione. scalabile e che dovremmo rifattorizzare il database in modo che tutte le diverse applicazioni utilizzino un singolo database centrale e che qualsiasi modifica che possa essere unica per un sistema debba essere riflessa da quel database e quindi utilizzare un singolo pool alimentato da Tomcat. Ha postulato che ci sono molti "metadati" che vanno avanti e indietro attraverso la rete per mantenere un pool di connessioni.

mia comprensione è che con una corretta messa a punto di utilizzare solo il maggior numero di collegamenti necessari tra le diverse piscine (applicazioni a basso volume sempre meno le connessioni, le applicazioni ad alto volume sempre più, etc.) che il numero di piscine non lo fa importa rispetto al numero di connessioni o più formalmente che la differenza di spese generali richiesta per mantenere 3 pool di 10 connessioni è trascurabile rispetto a 1 pool di 30 connessioni.

Il ragionamento alla base della rottura iniziale dei sistemi in una progettazione di un app-one-database era che ci sarebbero probabilmente differenze tra le app e che ogni sistema potrebbe apportare modifiche allo schema in base alle esigenze. Allo stesso modo, ha eliminato la possibilità di emorragia di dati di sistema attraverso altre app.

Purtroppo non c'è una forte leadership nell'azienda per prendere una decisione difficile. Sebbene il mio collega stia sostenendo le sue preoccupazioni solo con vaghezza, voglio assicurarmi di comprendere le implicazioni di più piccoli database/connessioni rispetto a un grande database/pool di connessioni.

+0

Non sono d'accordo con il tuo collega. Se sono presenti n Webapp, utilizzare n pool, anche se utilizzano lo stesso server di database. Ciò ti offre una migliore separazione delle preoccupazioni, opzioni di ottimizzazione più precise, isolamento migliore (se una webapp mangia tutte le connessioni, perché l'altra dovrebbe essere influenzata), ecc. Inoltre, davvero non vedo perché una piscina unica scalerebbe meglio . Questo è solo IMO non è vero. –

risposta

10

Il design originale si basa su principi sani. Se aiuta il tuo caso, questa strategia è nota come horizontal partitioning or sharding. Fornisce:

1) Maggiore scalabilità - perché ogni frammento può vivere su hardware separato, se necessario.

2) Maggiore disponibilità - in quanto il guasto di un singolo frammento non influisce gli altri frammenti

3) maggiori prestazioni - perché le tabelle da ricercare hanno meno righe e gli indici di conseguenza più piccole che i rendimenti ricerche più veloci.

Il suggerimento del collega consente di passare a un singolo punto di errore.

Per quanto riguarda la domanda relativa a 3 pool di connessione di dimensioni 10 vs 1 pool di connessioni di dimensioni 30, il modo migliore per risolvere il dibattito è con un punto di riferimento. Configura la tua app in ogni modo, quindi esegui alcuni test di stress con ab (Benchmark di Apache) e vedi come funziona meglio. Sospetto che non ci sarà una differenza significativa, ma fare il punto di riferimento per dimostrarlo.

+0

Grazie! Sfortunatamente non sono un DBA, ma non mi era venuto in mente che questa configurazione fosse in realtà uno stratagemma di spicco. Sfortunatamente, a meno che non ci siano ulteriori magie per consentire a MySQL di agire automaticamente come un ambiente più complesso, diversi database fungono anche da distinzioni commerciali e ciò renderebbe problematico il corretto benchmarking. Né sono i poteri che potrebbero darci il tempo di eseguire i parametri di riferimento. : \ – Drew

2

Ottima domanda. Non so quale sia la soluzione migliore, ma hai considerato la possibilità di progettare il codice in modo tale da passare da una strategia all'altra con il minimo possibile di dolore? Forse alcuni oggetti proxy del database leggero potrebbero essere utilizzati per mascherare questa decisione progettuale dal codice di livello superiore. Nel caso in cui.

+0

Potrebbe essere fattibile. Sfortunatamente non sono un DBA. So che MySQL ha una gestione nativa di sharding ma non ne so molto. Se dovessimo provare a farlo in modo programmatico, avremmo bisogno di aggiungere colonne discriminatorie e tutto quel divertimento. Fortunatamente, solo alcuni tavoli avrebbero bisogno di loro. Lo terrò nella parte posteriore della testa se i problemi di prestazioni reali alzino la testa. – Drew

1

Database e overhead-saggio, 1 pool con 30 connessioni e 3 piscine con 10 connessioni sono in gran parte le stesse assumendo che il carico sia lo stesso in entrambi i casi.

Per quanto riguarda l'applicazione, la differenza tra il fatto che tutti i dati passano attraverso un singolo punto (ad esempio un livello di servizio) o un punto di accesso per applicazione può essere abbastanza drastico; sia in termini di prestazioni e facilità di implementazione/manutenzione (si consideri che è necessario utilizzare la cache distribuita, ad esempio).

+0

La cache distribuita è un punto che non avevo considerato. Tuttavia, al momento attuale tutto il codice di persistenza è astratto in una singola libreria che è inclusa in ogni app Web, lasciando solo la configurazione da eseguire su base web-app. L'intento, tuttavia, è sempre stato quello di sostituire questo codice di persistenza (costruito su JDBC) con un ORM più completo. ORM si adatta molto bene ai nostri dati. I problemi del tempo ci hanno impedito di essere in grado di usarlo fin dall'inizio. – Drew

4

Se si dispone di un singolo database e due pool di connessione, con 5 connessioni ciascuno, sono disponibili 10 connessioni al database. Se si dispone di 5 pool di connessione con 2 connessioni ciascuno, si hanno 10 connessioni al database. Alla fine, hai 10 connessioni al database. Il database non ha idea che il tuo pool esista, nessuna consapevolezza.

Qualsiasi metadati scambiati tra il pool e il DB si verificherà su ciascuna connessione. Quando viene avviata la connessione, quando la connessione viene interrotta, ecc. Quindi, se si dispone di 10 connessioni, questo traffico si verificherà 10 volte (come minimo, supponendo che rimarranno tutti in salute per tutta la vita del pool). Questo accadrà se hai 1 piscina o 10 piscine.

Per quanto riguarda "1 DB per app", se non si sta parlando di un'istanza separata del database per ciascun DB, in pratica non importa.

Se si dispone di un server DB che ospita 5 database e si dispone di connessioni a ciascun database (ad esempio, 2 connessioni per), questo consumerà più overhead e memoria rispetto allo stesso DB che ospita un singolo database. Ma questo overhead è al massimo marginale e assolutamente insignificante su macchine moderne con buffer di dati di dimensioni GB. Oltre un certo punto, tutto ciò di cui il database si occupa è la mappatura e la copia delle pagine di dati dal disco alla RAM e viceversa.

Se si disponeva di una tabella ridondante di grandi dimensioni in duplicati tra i DB, ciò potrebbe essere potenzialmente inutile.

Infine, quando uso la parola "database", intendo l'entità logica che il server utilizza per fondere le tabelle. Ad esempio, a Oracle piace davvero avere un "database" per server, suddiviso in "schemi". Postgres ha diversi DB, ognuno dei quali può avere schemi. Ma in ogni caso, tutti i server moderni hanno confini logici di dati che possono utilizzare. Sto solo usando la parola "database" qui.

Quindi, fino a quando si colpisce una singola istanza del server DB per tutte le app, i pool di connessione non sono molto importanti nell'immagine grande, poiché il server condividerà tutta la memoria e risorse attraverso i client, se necessario.

+0

Tutti colpiscono un singolo server DB che esegue Mysql con i dati di ciascuna app in un "database" (stiamo usando il termine allo stesso modo) mentre un altro database centrale memorizza i dati condivisi. Dal tuo account, la mia comprensione è corretta. :) – Drew

0

Bene, ottima domanda, ma non è facile per discutere con un approccio più basi di dati (A) o quello grande (B):

  1. Dipende dal database stesso. Oracle, ad es. si comporta diversamente da Sybase ASE per quanto riguarda la strategia LOG (e quindi la LOCK). Potrebbe essere preferibile utilizzare diversi diversi data base & per mantenere bassa la percentuale di conflitto, se vi sono molte scritture parallele e il DB utilizza una strategia di blocco pessimistica (Sybase).
  2. Se il tablespace delle piccole basi di dati non è distribuito su più dischi, potrebbe essere meglio utilizzare un grande database per l'utilizzo della memoria (buffer/cache) solo per uno. Penso che sia raramente il caso.
  3. L'utilizzo di (A) è migliore per motivi diversi dalle prestazioni. È possibile spostare una base dati hot spot su un hardware diverso (più recente/più veloce) quando necessario senza toccare le altre basi di dati. Nella mia ex azienda questo approccio era sempre più economico della variante (B) (nessuna nuova licenza).

Personalmente preferisco (A) per la ragione 3.

+0

Siamo principalmente un negozio Open Source e per il database utilizziamo MySQL con InnoDB. Questo cambia la tua risposta? – Drew

0

Il design, l'architettura, i piani e le grandi idee sono insoddisfacenti quando non c'è un buon senso o una semplice matematica dietro. Un po 'più di pratica e/o esperienza aiuta ... Ecco una semplice spiegazione del perché 10 pool con 5 connessioni non sono la stessa di 1 pool con 50 connessioni: ogni pool è configurato con connessioni aperte min min. &, fatto sta che userà solitamente (99% delle volte) il 50% del numero minimo (2-3 in caso di 5 minuti) se sta utilizzando più di quello che questo pool è configurato in modo errato poiché sta aprendo e chiudendo le connessioni tutto il tempo (costoso) ... quindi abbiamo 10 piscine con 5 connessioni min ciascuna = 50 connessioni aperte ... significa 50 connessioni TCP; 50 connessioni JDBC in cima a loro ... (esegui il debug di una connessione JDBC? Sarai sorpreso di quanti metadati fluiscono in entrambi i modi ...) Se abbiamo 1 pool (che serve la stessa infrastruttura sopra) possiamo impostare il Min. 30 semplice perché sarà in grado di bilanciare gli extra in modo più efficiente ... questo significa 20 connessioni JDBS in meno. Non so voi ma per me questo è molto ... Il diavolo è nei dettagli - le 2-3 connessioni che si lasciano in ogni piscina per assicurarsi che non si apra/chiuda tutto il tempo. .. Non voglio nemmeno andare nel sovraccarico di 10 gestione del pool ... (Non voglio mantenere 10 pool tutti mai così diversi che l'altro, vero?) Ora che mi fai iniziare su questo se fossi in me vorrei "avvolgere" il DB (la fonte dei dati) con una singola app (livello di servizio chiunque?) che fornirebbe servizi diff (REST/SOAP/WS/JSON - scegli il tuo veleno) e le mie applicazioni vinte ' So anche di JDBC, TCP ecc. ecc. oh, aspetta che google lo abbia - GAE ...

+0

Fortunatamente il server delle applicazioni (Tomcat in questa istanza) gestisce i pool di connessione e ci fornisce i controlli di ottimizzazione. Inoltre, non seguo i tuoi calcoli. Supponendo che tutti i pool siano sintonizzati correttamente, se stiamo usando il 50%, perché i 10 pool necessitano di 50 connessioni aperte? Non avrebbe solo bisogno di 20-30? – Drew