La disabilitazione dell'hyperthreading migliorerà le prestazioni sulla nostra installazione di SQL Server


28

Correlato a: Saggezza attuale su SQL Server e Hyperthreading

Di recente abbiamo aggiornato il nostro server di database Windows 2008 R2 da un X5470 a un X5560 . La teoria è che entrambe le CPU hanno prestazioni molto simili, semmai l'X5560 è leggermente più veloce.

Tuttavia, le prestazioni di SQL Server 2008 R2 sono state piuttosto scarse nell'ultimo giorno e l'utilizzo della CPU è stato piuttosto elevato.

L'aspettativa di vita della pagina è enorme, stiamo ottenendo quasi il 100% di hit della cache per le pagine, quindi la memoria non è un problema.

Quando ho corso:

SELECT * FROM sys.dm_os_wait_stats 
order by signal_wait_time_ms desc

Ho ottenuto:

wait_type waiting_tasks_count wait_time_ms max_wait_time_ms signal_wait_time_ms
-------------------------------------------------- ---------- -------------------- -------------------- -------------------- --------------------
XE_TIMER_EVENT 115166 2799125790 30165 2799125065
REQUEST_FOR_DEADLOCK_SEARCH 559393 2799053973 5180 2799053973
SOS_SCHEDULER_YIELD 152289883 189948844 960 189756877
CXPACKET 234638389 2383701040 141334 118796827
SLEEP_TASK 170743505 1525669557 1406 76485386
LATCH_EX 97301008 810738519 1107 55093884
LOGMGR_QUEUE 16525384 2798527632 20751319 4083713
WRITELOG 16850119 18328365 1193 2367880
PAGELATCH_EX 13254618 8524515 11263 1670113
ASYNC_NETWORK_IO 23954146 6981220 7110 1475699

(10 righe interessate)

Ho anche corso

-- Isolate top waits for server instance since last restart or statistics clear
WITH Waits AS (
   SELECT 
        wait_type, 
        wait_time_ms / 1000. AS [wait_time_s],
        100. * wait_time_ms / SUM(wait_time_ms) OVER() AS [pct],
        ROW_NUMBER() OVER(ORDER BY wait_time_ms DESC) AS [rn]
FROM sys.dm_os_wait_stats
WHERE wait_type NOT IN ('CLR_SEMAPHORE','LAZYWRITER_SLEEP','RESOURCE_QUEUE',
    'SLEEP_TASK','SLEEP_SYSTEMTASK','SQLTRACE_BUFFER_FLUSH','WAITFOR','LOGMGR_QUEUE',
    'CHECKPOINT_QUEUE','REQUEST_FOR_DEADLOCK_SEARCH','XE_TIMER_EVENT','BROKER_TO_FLUSH',
    'BROKER_TASK_STOP','CLR_MANUAL_EVENT','CLR_AUTO_EVENT','DISPATCHER_QUEUE_SEMAPHORE',
    'FT_IFTS_SCHEDULER_IDLE_WAIT','XE_DISPATCHER_WAIT', 'XE_DISPATCHER_JOIN'))

SELECT W1.wait_type, 
    CAST(W1.wait_time_s AS DECIMAL(12, 2)) AS wait_time_s,
    CAST(W1.pct AS DECIMAL(12, 2)) AS pct,
    CAST(SUM(W2.pct) AS DECIMAL(12, 2)) AS running_pct
FROM Waits AS W1
INNER JOIN Waits AS W2 ON W2.rn <= W1.rn
GROUP BY W1.rn, W1.wait_type, W1.wait_time_s, W1.pct
HAVING SUM(W2.pct) - W1.pct < 95; -- percentage threshold

E ottenuto

wait_type wait_time_s pct running_pct
CXPACKET 554821.66 65.82 65.82
LATCH_EX 184123.16 21.84 87.66
SOS_SCHEDULER_YIELD 37541.17 4.45 92.11
PAGEIOLATCH_SH 19018.53 2.26 94.37
FT_IFTSHC_MUTEX 14306.05 1.70 96.07

Ciò mostra enormi quantità di tempo nella sincronizzazione di query che coinvolgono il parallelismo (CXPACKET elevato). Inoltre, molte di queste domande sui problemi vengono eseguite aneddoticamente su più core (non abbiamo suggerimenti MAXDOP in nessun punto del nostro codice)

Il server non è stato caricato per più di un giorno circa. Stiamo riscontrando una grande varianza con le esecuzioni delle query, in genere molte query sembrano essere più lente rispetto al nostro precedente server DB e la CPU è davvero elevata.

La disabilitazione dell'hyperthreading può aiutare a ridurre l'utilizzo della CPU e aumentare la velocità effettiva?



Tieni presente che CXPACKET non significa che c'è molto tempo in attesa che i processi vengano uniti. CXPACKET significa che il thread è in attesa che un altro thread termini la sua elaborazione. Devi guardare una query specifica che ha un thread nell'attesa di CXPACKET e vedere quali altri thread stanno aspettando oltre a CXPACKET. Di solito è IO o rete. Nell'output sopra è in attesa di chiusure e viene pianificato. Alcune query devono essere ottimizzate oppure è necessario capire perché vengono prese le levette.
mrdenny,

Nel nostro caso, CXPACKET era alto poiché gli altri thread stavano leggendo eccessivamente dalla cache (20 milioni di letture logiche per query). Il nostro caso, ancora una volta, era un brutto antisemijoin con una tabella partizionata che era di soli 700K righe.
Ozamora,

@mrdenny, sì, il tempo di attesa del latch elevato riguarda il fatto che al momento lo stiamo studiando.
Sam Saffron,

Risposte:


10

Sento ancora che testare il tuo carico di lavoro specifico , secondo la risposta originale, è l'unico modo per essere sicuri. Non è una risposta ideale quando si sta tentando di mettere a punto un sistema di produzione (quindi chiederei se fosse possibile ottenere un banco di prova identico in sistemi in cui sia le prestazioni che la disponibilità contano davvero) ma è l'unica a cui mi sento davvero a mio agio con.

Possiamo parlare della teoria se l'hyperthreading debba danneggiare o migliorare le cose in generale (trovo che abbia più probabilità di danneggiare che aiutare sui server, quindi per una distribuzione "generica" ​​probabilmente lo disabiliterei), ma c'è solo un modo per vedere con certezza se farà la differenza nel tuo caso specifico, e cioè provarlo e vedere.


3
Nota: non ho votato a fondo, abbiamo bisogno di tutto l'aiuto possibile, tuttavia vorremmo evitare pugnalate al buio su un sistema di produzione. Voglio assicurarmi di aver raccolto abbastanza dati diagnostici prima di effettuare la chiamata giocando con questa impostazione.
Sam Saffron,

3
Sono sicuro che vorresti evitare di "giocare" con un sistema di produzione, in un mondo ideale avremmo tutti ambienti di test identici alla produzione per quel motivo. Sono d'accordo con non voler cambiare la produzione su speculazione. Tuttavia, rispondo la mia risposta: testare carichi di lavoro specifici è una parte importante di qualsiasi distribuzione e chiunque ti dica diversamente è un ciarlatano. Per me, tutti i segni indicano che l'hyperthreading è un problema qui, ma possiamo parlare di cose tutto il giorno e tutta la notte e ci sarà ancora solo un modo per saperlo con certezza.
Rob Moir,

5
Vota qui: sono d'accordo con la risposta. La risposta generale è: disattivare Hyperthreading. La risposta più specifica è: dipende dalle specifiche e DEVE ESSERE TESTATA.
TomTom,

1
Stranamente, penso che questa sia la migliore risposta da accettare, confondersi con le impostazioni di maxdop può portare a molti problemi, nehalem cpus sono molto più veloci degli xeon basati su core anche a velocità di clock leggermente più lente, trovo un po 'gli argomenti memorizzati nella cache di un'aringa rossa perché la cache l3 è molto più grande. Come addendum vedi: blog.stackoverflow.com/2010/10/database-upgrade , se qualcuno sta vedendo più del 20% di hit / gain ... probabilmente non è dovuto a HT.
Sam Saffron,

Ho avuto l'esperienza opposta a @TomTom e @Robert. Ho scoperto che HT è di solito il 10-15% migliore rispetto a spento. L'occasione in cui spegnerlo migliora le prestazioni è stata davvero rara.
Brian Knoblauch,

12

Sono d'accordo

  • nella migliore delle ipotesi la raccomandazione è "prova HyperThreading sul tuo carico di lavoro e guarda cosa succede". Lo stiamo facendo proprio adesso mentre scrivo, e ... non va bene!
  • probabilmente dovresti sempre iniziare con HyperThreading disabilitato, poiché è il più sicuro

Sembra che dovremmo accordare due cose:

  1. MAXDOP (gradi massimi di parallelismo). Tutto quello che ho letto indica che avere questo illimitato è probabilmente una cattiva idea e la documentazione di Microsoft dice:

    L'impostazione di questa opzione [MAXDOP] su un valore maggiore [di 8] spesso causa consumo di risorse indesiderate e degrado delle prestazioni.

    qualcosa di più alto di quanto 8non sia generalmente raccomandato .. quindi l'ho impostato su 4per ora. Inizialmente era zero (illimitato).

  2. Soglia di costo per il parallelismo. Apparentemente il default di 5qui è considerato un default piuttosto basso secondo alcuni post di MVP SQL che ho trovato - possiamo sintonizzarlo per ridurre quanto parallelismo viene persino tentato dallo scheduler.

Ma onestamente sembrano soluzioni alternative; Penso che la vera soluzione per il nostro carico di lavoro (indice full-text pesante) sia disabilitare HT.


4
MAXDOP causa anche problemi con HT in quanto potrebbe tentare di eseguire due thread sulla stessa CPU, se hai detto 8 core e 16 thread, e il tuo maxdop è impostato su 10. Generalmente 1 MAXDOP per processore logico dovrebbe essere il massimo. Ed eseguire due thread sulla stessa CPU per lo stesso processo è in qualche modo inutile.
Mark Henderson

2
@Farseeker che si verifica solo se non si dispone di un sistema operativo compatibile con HyperThreading. Windows più recente di 2000 ne è consapevole.
Mircea Chirea,

vale la pena notare che queste sostituzioni maxdop stavano causando solo problemi. il default andava bene per noi
Sam Saffron,

2
La versione standard di SQL Server raggiunge il massimo a MAXDOP di 4 comunque se lasciata illimitata. Ho bisogno di Enterprise per andare oltre. Abbiamo avuto alcuni carichi di lavoro che sono andati più veloci con MAXDOP di 1 (scatola non HT, con più AMD a 8 core) ...
Brian Knoblauch

1
@Brian Knoblauch - Lo so più di un anno dopo, ma mi sono imbattuto in questa "Versione standard di SQL Server massima a MAXDOP di 4 comunque se lasciata illimitata" ogni possibilità che tu possa indicarmi un po 'di documentazione. Attualmente stiamo parlando dell'utilizzo di MAXDOP al lavoro, ma non siamo sicuri su come impostarlo. Ciò significa fondamentalmente che 4 è uguale a non associato corretto?
Jeremy A. West,

9

Anandtech ha scoperto che con il puro carico di lettura, faceva un po 'male, e con un carico pesante di scrittura, era un po' una vittoria. Non ho visto nulla per farmi pensare che ti farà ottenere un successo molto peggiore del -5% o una vittoria molto migliore del 15%. Nota cosa con un Atom, è una vittoria enorme, ma è una cpu molto strana.

Tutto quello che hai cambiato è stato il CPU? Sei passato da 12 MB di cache e 4 thread, quindi 3 MB di cache per thread, a 8 MB di cache e 8 thread, quindi 1 MB per thread. Ora, questo è semplicissimo, ma scommetto che è quello che ti sta uccidendo, hai usato per eseguire query nella cache e ora eseguirle dalla RAM perché hanno bisogno di più di 1 MB ma meno di 3 MB. La disattivazione di HT probabilmente aiuterà, ma tornerei alla vecchia CPU. Disattiva HT e ottieni 2 MB per thread, ma se il tuo carico di lavoro si blocca con così tanto, non sarà di aiuto. È possibile che la vecchia CPU da 12 MB di cache sia enormemente più veloce per il tuo carico di lavoro.

Vorrei provare a disattivare HT e vedere se si tratta di un miglioramento, ma sospetto che la cache sia il re per il carico di lavoro e potrebbe essere necessario tornare al chip da 12 MB.


3
La cache L2 per osservazione core è un'enorme semplificazione, poiché la CPU è avanti di una generazione completa (classe Nehalem / Core i7 vs Core 2 Quad).
Jeff Atwood,

@Jess, @Ronald e Nehalem ha poca cache L2. La maggior parte è L3 che è condivisa tra i core.
Mircea Chirea,

7

L'hyperthreading è, nella migliore delle ipotesi, solo un modo per astrarre l'attività che si allontana dal sistema operativo e lo posiziona on-die, con accesso diretto alla cache L1 e L2, che rende più veloce lo scambio di attività.

I test con VMWare hanno indicato che la disabilitazione di HT non ha fatto alcuna differenza riconoscibile sotto carico standard e un aumento del 5% sotto carico pesante, dovuto al fatto che ESXi è abbastanza intelligente da conoscere la differenza tra il thread "reale" e il thread "falso" (c'è molto di più, ma in parole povere). SQL Server 2005 non è poi così intelligente, ma combinato con un sistema operativo aggiornato ci dovrebbe essere un piccolo vantaggio nel disabilitare l'HT.

Detto questo, concordo con Ronald sul fatto che molto probabilmente sarà la tua cache L2. Un calo del 33% nella dimensione della cache è sostanziale e quando specifichiamo i nostri server SQL andiamo sempre alla cache sulla velocità di clock non elaborata ogni volta.


Puoi impostare l'affinità esternamente in modo che i 4 core giusti vengano ignorati da SQL?
Sam Saffron,

3
Generalmente imposti l'affinità con l'altro thread della CPU, ma fintanto che MAXDOP è impostato correttamente non vedo alcun motivo per impostare l'affinità. Con HT però il primo thread ad essere colpito su una CPU diventa il thread "principale" e il secondo thread è il thread "HT". Non ci sono thread "principali" e "ht" reali, perché è quello che ci è arrivato prima, e poi quando cambiano attività, l'ordine viene invertito.
Mark Henderson

Le CPU basate su Nehalem hanno cache L2 MOLTO, MOLTO PICCOLA, la maggior parte delle quali L3 condivisa.
Mircea Chirea,

7

In base alla mia esperienza, HT stava facendo sì che le operazioni di I / O impiegassero un'eternità sui miei nodi attivi su un cluster di Windows 2008 R2 (con SQL Server 2008 R2). Un fatto interessante è che non si rifletteva né nelle statistiche di attesa né nel pssdiag che ho corso per il supporto Microsoft.

Il modo in cui ho notato I / O basso è stato solo guardando i contatori del sistema operativo per il disco fisico. Come ha sottolineato Sam, ne ho scritto qui e qui

Se NON si verificano problemi di I / O e sono associati alla CPU, ti suggerisco di iniziare in questo modo:

Individua quali processi e blocchi T-SQL stanno causando il maggior utilizzo della CPU. Nella nostra esperienza, dopo aver risolto il problema con l'I / O (disattivando HT) abbiamo identificato il codice che stava funzionando in modo orribile nel 2008 R2 e stava andando bene nel 2005. Ne ho scritto qui .

Mentre sei sotto carico, esegui sp_whoisactive di Adam Machanic. Puoi scaricarlo da qui . Stavamo riscontrando un utilizzo della CPU molto elevato a causa dell'eccessiva quantità di letture logiche (20 milioni per query) a causa di un piano davvero scadente. I nostri processi eseguivano join anti-semi con tabelle partizionate.

La mia prossima raccomandazione è quella di eseguire il profiler per identificare un insieme di codice T-SQL che sia ad alto contenuto di CPU e letture logiche I / O.

Con i passaggi precedenti siamo stati in grado di ottimizzare i processi offensivi e passare dall'85% di utilizzo della CPU a quasi zero.

Buona fortuna e sentiti libero di scrivermi se trovi una soluzione poiché vorrei aggiungere il caso al mio blog.

Grazie

Oscar


1
+1 per il profiler, mi ha salvato molte volte una volta individuato un punto problematico
Mark Henderson

+1 grazie per tutti i tuoi suggerimenti, l'ottimizzazione del nostro SQL su un livello ragionevole è un incubo totale, dipendiamo dal fulltext abbastanza pesantemente per i nostri rapporti con i tag, abbastanza spesso stiamo cercando un elenco di articoli in tag particolari in modo da prendere il tutto impostare e filtrare verso il basso. Ad esempio, ottenere un elenco di domande con i tag [x] e [y] ordinati per data comporta l'estrazione di enormi quantità di dati dal testo completo e quindi un join massiccio.
Sam Saffron,

Inteso. Prendi un campione ed eseguilo con statistiche IO ON e vedi se riesci a individuare qualsiasi tabella con le letture più logiche. Ancora una volta, stavamo andando bene nel 2005 e davvero male nel 2008 R2. Se trovi solo un elevato utilizzo della CPU e hai un'attesa CXPACKET elevata, prova prima aumentando la Soglia di costo per il parallelismo a 10, 15 o anche 20
ozamora,

Se nient'altro aiuta, offline il DB, disattivare HT e andare da lì. Buona fortuna
ozamora,

sp_whoisactive è uno strumento davvero fantastico, adoro il modo in cui le query sono selezionabili
Sam Saffron,

2

È difficile stabilire se HT sia buono o cattivo.

Dipende davvero dal modello di caricamento del server basato sull'esperienza e sulla lettura. Cioè, quando influisce sulle prestazioni, fa così male : altrimenti non te ne accorgi.

La teoria che ho letto è che i thread condividono la cache, il che significa che in condizioni avverse ogni thread può sovrascrivere la cache dell'altro thread. Se non hai molto parallelismo o il tuo carico è composto da molte brevi query, potrebbe non interessarti.

Ho provato con MAXDOP e l'affinità del processore (nel mio ultimo vero ruolo DBA su SQL Server 2000) ma non ho mai trovato nulla di conclusivo: ma solo per il mio negozio in quel momento.

Come test rapido, è possibile impostare l'affinità del processore per utilizzare solo i core fisici (i numeri inferiori) e vedere cosa succede.

Tuttavia, al massimo perdi metà dei tuoi core. Al giorno d'oggi potrebbe non importare rispetto a quello con cui giocavo qualche anno fa quando era 2 contro 4 o 4 contro 8. Ora sono 8 contro 16 o 16 contro 32.

Modifica: un test di Slava Oks


i core 0-3 sono fisici e 4-7 logici? Funziona così? Non potevamo dirlo, e non sono riuscito a trovare alcuno strumento per farmi sapere ..
Jeff Atwood,

2
@Jeff Atwood: ne troverò di più in seguito. Ho ho letto da qualche parte .... Per ora: support.microsoft.com/kb/322385
gbn

Quell'articolo KB lo riassume praticamente.
pauska,

Sebbene l'articolo KB contenga alcune informazioni utili, non sembra rispondere direttamente alla domanda di Jeff su come esattamente i processori logici sono associati a quelli fisici. Il mio cervello è impazzito per metà, ma spero che questo articolo INTEL ti dia ciò di cui hai bisogno per capire la mappatura: software.intel.com/en-us/articles/… vedi anche software.intel.com/en-us/ blogs / 2009/12/21 / ... con i relativi collegamenti.
BradC,

@Jeff Atwood, @BradC: Lordy, difficile da trovare. Vedi questo: si basa su raccomandazioni Intel. SQL Server utilizzerà l'enumerazione di Windows sottostante download.microsoft.com/download/5/7/7/… .
gbn,

2

Sfortunatamente, non penso che otterrai una risposta più definitiva di "prova a disattivare l'hyperthreading e vedi se questo aiuta".

Nonostante la risposta utile di Jonathan nel mio thread originale (che hai collegato nella tua domanda), non sono mai stato in grado di ottenere prove definitive sull'impatto dell'HT sui server specifici su cui stavo indagando. Nel mio caso, i server erano già programmati per la sostituzione, quindi semplicemente lasciamo che quei rimpiazzi "prendano cura del problema" per così dire.

Il mio consiglio:

Prova un'impostazione MAX Grado di parallelismo a livello di server pari a 1 . Il parallelismo su SQL è comunque molto utile per query più grandi e più lunghe, e il tuo carico (presumo) consiste comunque in un numero enorme di query più piccole. Questo dovrebbe eliminare completamente le attese di CXPACKET. Ciò potrebbe far sì che alcune singole query vengano eseguite leggermente più a lungo, ma dovrebbe consentire una maggiore "velocità effettiva" delle query totali sul server.

Ho ottenuto buoni risultati facendo questo sui server OLTP. Altri tipi di server (server di report, server di elaborazione, data warehousing) necessitano sicuramente di un MAXDOP superiore.

E per essere chiari, questa impostazione consentirebbe comunque a SQL di utilizzare più thread per ogni singola tabella in un JOIN, quindi non stai davvero eliminando del tutto il parallelismo.

Almeno vale la pena provare, poiché questa modifica delle impostazioni ha effetto immediato e non richiede nemmeno il riavvio del servizio SQL: http://msdn.microsoft.com/en-us/library/ms181007.aspx
Ciò significa che è possibile cambiare torna immediatamente se le cose iniziassero all'inferno.

La disattivazione dell'hyperthreading nel BIOS richiederebbe un riavvio completo del server, quindi è un po 'più rischioso.


0

Per la cronaca, abbiamo anche avuto prestazioni inaspettatamente cattive dopo un aggiornamento del server. Si è scoperto essere a causa di problemi con il risparmio energetico del BIOS e della CPU. L'impostazione predefinita sul server (HP) era di ignorare il controllo del sistema operativo della velocità della CPU e utilizzare il proprio algoritmo. La modifica del controllo del sistema operativo e l'aggiornamento del BIOS hanno comportato miglioramenti significativi. C'erano alcune note di rilascio (non le trovo ora) che c'era un bug del BIOS che bloccava la CPU allo stato di prestazione più basso.

https://serverfault.com/a/196329/6390

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.