Informazioni sulle prestazioni dei database a thread singolo o multithread


58

H2 è un database a thread singolo con una buona reputazione per quanto riguarda le prestazioni. Altri database sono multi-thread.

La mia domanda è: quando un database multi-thread diventa più interessante di un database single thread? Quanti utenti? Quanti processi? Qual è il grilletto? Qualcuno ha esperienza da condividere?

Sommario

  • Il solito collo di bottiglia è l'accesso al disco
  • Gli SSD sono veloci, ma fragili (la procedura di fallimento è un must)
  • Una query lunga su un sistema a thread singolo bloccherà tutti gli altri
  • La configurazione del sistema multi-threading può essere complicata
  • I database multithread sono utili anche su sistemi single core

Discussione significa "thread o processo" ai fini di questa domanda, per quanto posso dire - ad esempio Postgres non è multi-thread ma la domanda non sta cercando di confrontare (H2, Postgres) con (Oracle, SQL Server ecc.)
Jack Douglas,

Risposte:


31

Ecco la mia opinione:

Di solito il collo di bottiglia (o la parte più lenta) di un sistema DB è il disco. La CPU raggiunge picchi solo durante le operazioni aritmetiche, l'elaborazione o qualsiasi altra attività svolta dalla CPU. Con un'architettura adeguata, il multithreading può aiutare a compensare il carico di una query nella CPU invece di eseguire letture / scritture lente del disco. Ci sono casi in cui è più veloce calcolare un valore utilizzando i cicli della CPU piuttosto che creare una colonna calcolata (precedentemente salvata su disco) e leggere questa colonna dal disco.

In alcuni RDBMS esiste un DB temporaneo (tempdb) che viene utilizzato da tutti i DB su quell'istanza per l'ordinamento, l'hashing, le variabili temporanee, ecc ... Il multithreading e la suddivisione di questi file tempdb possono essere utilizzati per migliorare il throughput del tempdb , migliorando così le prestazioni complessive del server.

Utilizzando il multithreading (parallelismo), il set di risultati di una query può essere suddiviso per essere elaborato sui diversi core del server, anziché utilizzare un solo core. Questa funzione non migliora sempre le prestazioni, ma ci sono casi in cui lo fa e quindi la funzione è disponibile.

I thread disponibili per il DB vengono utilizzati per vari scopi: lettura / scrittura su disco, connessioni utente, processi in background, blocco / latching, I / O di rete, ecc ... A seconda dell'architettura del sistema operativo, i thread vengono inviati preventivamente alla CPU e vengono gestito usando attese e code. Se la CPU riesce a sgretolare questi thread abbastanza rapidamente, i tempi di attesa saranno bassi. Un DB multi-thread sarà più veloce di un DB single-thread, poiché in un DB single-thread ci sarà il sovraccarico di riciclare un solo thread anziché avere altri gradini prontamente disponibili.

Anche la scalabilità diventa un problema, poiché saranno necessari più thread per gestire ed eseguire il sistema DB scalato.


Grazie per la comprensione. Sento persone lodare le unità a stato solido. Immagino che investire in quelle sia probabilmente la cosa migliore da fare dopo essersi assicurati che le query siano ben scritte e che l'applicazione sia ragionevolmente parallelizzata.
Jérôme Verstrynge,

@Stan - Penso che multithreadedin questo contesto significhi qualcosa di diverso , vale a dire che tutte le transazioni sono serializzate come menziona Luke nella sua risposta.
Jack Douglas,

@JVerstry ~ No, non proprio. Vai a leggere i pensieri di Jeff Atwood sugli SSD ... hanno un alto tasso di fallimento. La cosa migliore da fare è indicizzare correttamente i dati e avere query ben scritte.
jcolebrand

@jcolebrand Ok, sembra che li sostenga per la velocità solo con un forte sistema di backup per quando falliscono
Jérôme Verstrynge,

2
@Jverstry ~ Sì, e se capisci quel concetto, e sei d'accordo con esso, e non ti dispiace ricostruire l'intero ambiente di produzione (o aspettare che inizi un failover automatico e poi ricostruirlo ad un certo punto in quel prossimo futuro), allora provaci, renderanno le cose ancora più veloci, sì.
jcolebrand

47

Se c'è una cosa che posso dire su MySQL è che InnoDB, il suo motore di archiviazione transazionale (conforme ACID), è effettivamente multithread. Tuttavia, è multithread come LO CONFIGURA !!! Perfino "pronto all'uso", InnoDB funziona alla grande in un singolo ambiente CPU, date le sue impostazioni predefinite. Per sfruttare le funzionalità di multithreading di InnoDB, è necessario ricordare di attivare molte opzioni.

innodb_thread_concurrency imposta il limite superiore sul numero di thread simultanei che InnoDB può tenere aperti. Il miglior numero di round da impostare per questo è (2 X Numero di CPU) + Numero di dischi. AGGIORNAMENTO : Come ho appreso in prima persona dalla Conferenza di Percona a New York, dovresti impostarlo su 0 per avvisare InnoDB Storage Engine di trovare il miglior numero di thread per l'ambiente in cui è in esecuzione.

innodb_concurrency_tickets imposta il numero di thread che possono bypassare il controllo della concorrenza impunemente. Una volta raggiunto questo limite, il controllo della concorrenza dei thread diventa di nuovo la norma.

innodb_commit_concurrency imposta il numero di transazioni simultanee che possono essere impegnate. Poiché il valore predefinito è 0, la mancata impostazione consente a qualsiasi numero di transazioni di impegnarsi contemporaneamente.

innodb_thread_sleep_delay imposta il numero di millisecondi in cui un thread InnoDB può essere inattivo prima di rientrare nella coda InnoDB. L'impostazione predefinita è 10000 (10 sec).

innodb_read_io_threads e innodb_write_io_threads (entrambi da MySQL 5.1.38) allocare il numero specificato di thread per letture e scritture. L'impostazione predefinita è 4 e il massimo è 64.

innodb_replication_delay impone che il ritardo del thread su uno slave sia raggiunto innodb_thread_concurrency

innodb_read_ahead_threshold consente letture lineari del numero di estensioni impostato (64 pagine [pagina = 16K]) prima di passare alla lettura asincrona.

Il tempo mi sfuggirebbe se nominassi più opzioni. Puoi leggerli nella documentazione di MySQL .

La maggior parte delle persone non è a conoscenza di queste funzionalità e è abbastanza soddisfatta di InnoDB che sta effettuando transazioni conformi a ACID. Se modifichi una di queste opzioni, lo fai a tuo rischio e pericolo.

Ho giocato con le istanze di pool di buffer multipli di MySQL 5.5 (162 GB in 9 istanze di pool di buffer) e ho tentato di partizionare automaticamente i dati in memoria in questo modo. Alcuni esperti affermano che questo dovrebbe darti un miglioramento delle prestazioni del 50%. Quello che ho ottenuto è stato un sacco di blocco del thread che ha effettivamente fatto strisciare InnoDB. Sono passato a 1 buffer (162 GB) e tutto andava bene di nuovo al mondo. Immagino che tu abbia bisogno degli esperti Percona a tua disposizione per impostare questo. Domani sarò alla conferenza PercQL MySQL a New York e chiederò a questo proposito se l'opportunità si offre da sola.

In conclusione, InnoDB si comporta bene ora in un server multi-CPU date le sue impostazioni predefinite per le operazioni multithread. Ottimizzarli richiede molta cura, grande pazienza, ottima documentazione e ottimo caffè (o Red Bull, Jolt, ecc.).

Buongiorno, buonasera e buona notte !!!

AGGIORNAMENTO 2011-05-27 20:11

Sono tornato dalla conferenza MySQL di Percona a New York giovedì. Che conferenza. Ho imparato molto, ma ho una risposta che esaminerò in merito a InnoDB. Sono stato informato da Ronald Bradford che l'impostazione di innodb_thread_concurrency su 0 consentirà a InnoDB di decidere internamente il miglior modo di agire internamente con la concorrenza dei thread. Lo sperimenterò ulteriormente in MySQL 5.5.

AGGIORNAMENTO 2011-06-01 11:20

Per quanto riguarda una lunga query, InnoDB è conforme ACID e funziona molto bene utilizzando il controllo di concorrenza MultiVersion . Le transazioni dovrebbero essere in grado di trasportare livelli di isolamento (letture ripetibili per impostazione predefinita) che impediscono ad altri di accedere ai dati.

Per quanto riguarda i sistemi multi core, InnoDB ha fatto molta strada. In passato, InnoDB non poteva funzionare bene in un ambiente multicore. Ricordo di dover eseguire più istanze mysql su un singolo server per far sì che più core distribuissero i vari processi mysqld attraverso le CPU. Questo non è più necessario, grazie a Percona e successivamente a MySQL (eh, Oracle, dicendo che mi fa ancora vomitare), poiché hanno sviluppato InnoDB in un motore di archiviazione più maturo che può accedere ai core con semplicità senza molta ottimizzazione. L'attuale istanza di InnoDB oggi può funzionare bene in un singolo server core.


11

Non appena si hanno più utenti o processi simultanei o anche un singolo processo con accesso al database multi-thread, avere un database che supporta il thread diventerà potenzialmente interessante.

H2 è thread-safe, ma serializza tutte le richieste al database, che può diventare un potenziale problema di prestazioni in uno scenario di carichi pesanti. Se questo è effettivamente il caso di un particolare progetto dipende da una combinazione dei requisiti di prestazione, dal numero di thread / utenti / processi che accedono al database, dalla frequenza delle query eseguite da questi thread e dalle prestazioni medie e peggiori del tuo interrogazioni.

Ad esempio, se i tuoi requisiti di prestazione devono avere una risposta entro un secondo, non hai più di 10 utenti simultanei che eseguono una singola query che impiega 0,05 secondi per essere eseguiti, un database a thread singolo ti consentirebbe comunque di raggiungere quegli obiettivi (anche se multithread probabilmente darebbe già un notevole incremento delle prestazioni). Dato lo stesso scenario con una singola potenziale query con prestazioni nel caso peggiore di mezzo secondo, la serializzazione dell'accesso al database non ti consentirà più di raggiungere i tuoi obiettivi di prestazione.

Se al momento stai usando H2 sul tuo progetto, ti consiglierei di eseguire un profiler contro la tua base di codice in uno scenario di caricamento (basta dare il via a un numero x di thread che colpiscono il tuo codice contemporaneamente usando alcune usecase tipiche). Questo ti fornirà metriche effettive riguardanti le prestazioni e i colli di bottiglia nella tua base di codice, invece di limitarti a teorizzare. Se questo mostra che le tue richieste trascorrono gran parte del loro tempo in attesa di accedere al database, è tempo di passare a un database thread.


H2 serializza tutte le richieste o solo DML?
Jack Douglas,

8

Da quello che posso dire, "single threaded" è un po 'un termine improprio per H2. Il punto è che serializza tutte le transazioni (cioè le fa una alla volta).

La domanda cruciale per sapere se è "ok" o no per la tua applicazione non è "Quanti utenti?" o anche "Quanti processi?", ma "Quanto dureranno le mie transazioni?"

Se tutte le tue transazioni sono sub-second che potrebbero andare bene, se alcune richiedono diverse ore per il completamento, ciò potrebbe non andare bene poiché tutte le altre transazioni in sospeso aspetteranno che finiscano. La decisione se "va bene" o meno dipenderà dai propri requisiti di prestazione, ovvero per quanto tempo è un'attesa accettabile per i miei utenti che colpiscono il database con le transazioni.

--MODIFICARE

Sembra che H2 non serializzi realmente le transazioni - solo DML. In altre parole, molti aggiornamenti brevi all'interno di un'unica transazione lunga non bloccheranno altri aggiornamenti . Tuttavia, a meno che non si stia utilizzando la funzione sperimentale MVCC , il blocco delle tabelle significa che ciò ha un effetto simile nella pratica. Esiste anche una funzione sperimentale "multi_threaded" ma non può essere utilizzata contemporaneamente a MVCC


5

Citando bit e pezzi dal sito PostgreSQL ... Si noti che non ho assolutamente idea dei meriti di questi argomenti - semplicemente non rientravano in un commento.

Dalle Domande frequenti per gli sviluppatori ("Perché i thread non vengono utilizzati ..."):

http://wiki.postgresql.org/wiki/Developer_FAQ#Why_don.27t_you_use_threads.2C_raw_devices.2C_async-I.2FO.2C_.3Cinsert_your_favorite_wizz-bang_feature_here.3E.3F

I thread non sono attualmente utilizzati al posto di più processi per i back-end perché: (...)

  • Un errore in un back-end può danneggiare altri back-end se sono thread all'interno di un singolo processo
  • I miglioramenti della velocità con i thread sono piccoli rispetto al tempo di avvio del back-end rimanente.
  • La condivisione di mapping eseguibili di sola lettura e l'uso di shared_buffers significa che i processi, come i thread, sono molto efficienti in termini di memoria
  • La creazione e la distruzione regolari di processi aiuta a proteggere dalla frammentazione della memoria, che può essere difficile da gestire in processi a lungo termine

Dall'elenco Todo ("Funzionalità che non vogliamo"):

http://wiki.postgresql.org/wiki/Todo#Features_We_Do_Not_Want

Tutti i backend in esecuzione come thread in un singolo processo (non desiderato)

Ciò elimina la protezione del processo che otteniamo dalla configurazione corrente. La creazione di thread è in genere lo stesso overhead della creazione di processi su sistemi moderni, quindi non è saggio utilizzare un modello thread puro, e MySQL e DB2 hanno dimostrato che i thread introducono tutti i problemi che risolvono. (...)

Quindi, ancora una volta ... Non ho assolutamente idea dei meriti di cui sopra. Era semplicemente troppo lungo per inserirsi in un commento.


-3

Un database multithread ti gioverà solo quando hai più di 1 query parallela che va nel database. Dipende dal numero di utenti che hai. Se hai più di dieci utenti che lavorano contemporaneamente sull'applicazione, molto probabilmente produrranno più di una query sul database contemporaneamente.

Inoltre, un database multithread può trarre vantaggio solo da CPU multi core. Se esiste un core singolo, il database multi-thread deve mettere in coda il lavoro ed eseguirli in sequenza sul singolo core. Quando è presente un multi-core, ogni core può eseguire un thread in parallelo. Quindi prestazioni migliori.

Questo risponde alla tua domanda?


7
I database multithread sono utili anche su sistemi single core. Impedisce a una singola query di lunga durata di bloccare tutti gli altri accessi al database, inoltre potresti avere diversi thread in attesa su I / O su disco o in rete, mentre un altro thread sta attivamente analizzando le query, elaborando dati precaricati, ecc.

Un utente potrebbe utilizzare un programma che paralellizza alcune operazioni. Molto probabilmente questo programma trarrebbe beneficio se il database avesse anche capacità multi-thread / multi-elaborazione.
joanolo,
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.