La désactivation de l'hyperthreading améliorera-t-elle les performances de notre installation SQL Server


28

En relation avec: Sagesse actuelle sur SQL Server et Hyperthreading

Récemment, nous avons mis à niveau notre serveur de base de données Windows 2008 R2 d'un X5470 vers un X5560 . La théorie est que les deux processeurs ont des performances très similaires, mais le X5560 est légèrement plus rapide.

Cependant, les performances de SQL Server 2008 R2 ont été plutôt mauvaises au cours du dernier jour environ et l'utilisation du processeur a été assez élevée.

L'espérance de vie des pages est énorme, nous obtenons presque 100% de cache pour les pages, donc la mémoire n'est pas un problème.

Quand j'ai couru:

SELECT * FROM sys.dm_os_wait_stats 
order by signal_wait_time_ms desc

J'ai eu:

wait_type wait_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 ligne (s) affectée (s))

J'ai aussi couru

-- 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

Et j'ai

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

Cela montre d'énormes quantités de synchronisation de temps impliquant des requêtes impliquant le parallélisme (CXPACKET élevé). De plus, de façon anecdotique, bon nombre de ces requêtes problématiques sont exécutées sur plusieurs cœurs (nous n'avons aucune indication MAXDOP nulle part dans notre code)

Le serveur n'est pas sous charge depuis plus d'un jour environ. Nous constatons une grande variance avec les exécutions de requêtes, généralement de nombreuses requêtes semblent être plus lentes qu'elles étaient sur notre serveur de base de données précédent et le processeur est vraiment élevé.

La désactivation de l'hyperthreading contribuera-t-elle à réduire notre utilisation du processeur et à augmenter le débit?



Gardez à l'esprit que CXPACKET ne signifie pas qu'il faut beaucoup de temps pour fusionner les processus. CXPACKET signifie que le thread attend qu'un autre thread termine son traitement. Vous devez examiner une requête spécifique qui a un thread dans l'attente CXPACKET et voir ce que les autres threads attendent en plus de CXPACKET. Il s'agit généralement d'E / S ou de réseau. Dans la sortie ci-dessus, vous attendez les verrous et vous êtes en cours de planification. Certaines requêtes doivent être ajustées, ou vous devez voir pourquoi les verrous sont pris.
mrdenny

Dans notre cas, CXPACKET était élevé car les autres threads ne faisaient que lire excessivement dans le cache (20 millions de lectures logiques par requête). Notre cas, encore une fois, était un mauvais anti-semi-joint avec une table partitionnée qui ne faisait que 700K lignes.
ozamora

@mrdenny, oui, le temps d'attente élevé est préoccupant, nous l'étudions actuellement.
Sam Saffron du

Réponses:


10

Je pense toujours que tester votre charge de travail spécifique , selon la réponse originale, est le seul moyen d'être sûr. Ce n'est pas une réponse idéale lorsque vous essayez de régler un système de production (donc je demanderais s'il était possible d'obtenir un banc d'essai identique dans des systèmes où les performances et la disponibilité sont vraiment importantes) mais c'est le seul que je suis vraiment à l'aise avec.

Nous pouvons parler de la théorie selon laquelle l'hyperthreading devrait blesser ou améliorer les choses en général (je trouve qu'il est plus susceptible de blesser que d'aider sur les serveurs, donc pour un déploiement "générique", je le désactiverais probablement), mais il y a une seule façon de voir avec certitude si cela va faire une différence dans votre cas spécifique, et c'est de l'essayer et de voir.


3
Notez que je n'ai pas downvote, nous avons besoin de toute l'aide que nous pouvons obtenir, mais nous aimerions éviter les coups de couteau dans le noir sur un système de production. Je veux m'assurer que nous avons rassemblé suffisamment de diagnostics avant de passer l'appel à jouer avec ce paramètre.
Sam Saffron

3
Je suis sûr que vous voulez éviter de «jouer» avec un système de production, dans un monde idéal, nous aurions tous des environnements de test identiques à la production pour cette raison. Je suis d'accord avec ne pas vouloir changer la production sur spéculation. Cependant, je maintiens ma réponse: tester des charges de travail spécifiques est une partie importante de tout déploiement et quiconque vous dit différent est un charlatan. Pour moi, tous les signes indiquent que l'hyperthreading est un problème ici, mais nous pouvons parler de choses toute la journée et toute la nuit et il n'y aura toujours qu'une seule façon de savoir avec certitude.
Rob Moir

5
Votez ici - je suis d'accord avec la réponse. La réponse générale est: Désactivez l'hyperthreading. Une réponse plus spécifique est: Cela dépend des spécificités et DOIT ÊTRE TESTÉ.
TomTom

1
Curieusement, je pense que c'est la meilleure réponse à accepter, le nettoyage avec les paramètres maxdop peut entraîner beaucoup de problèmes, les processeurs nehalem sont beaucoup plus rapides que les xeons basés sur le noyau même à des vitesses d'horloge légèrement plus lentes, je trouve les arguments mis en cache l2 un peu d'un hareng rouge parce que le cache l3 est tellement plus grand. En tant qu'addendum , voir: blog.stackoverflow.com/2010/10/database-upgrade , si quelqu'un voit plus de 20% de hit / gain ... ce n'est probablement pas dû à HT.
Sam Saffron

J'ai eu l'expérience opposée à @TomTom et @Robert. J'ai trouvé que HT activé est généralement 10 à 15% meilleur que désactivé. L'occasion où sa désactivation améliore les performances est en effet rare.
Brian Knoblauch

12

Je suis d'accord que

  • au mieux, la recommandation est "essayez HyperThreading sur votre charge de travail et voyez ce qui se passe". Nous faisons cela en ce moment même pendant que je tape, et .. ce n'est pas bon!
  • vous devriez probablement toujours commencer avec HyperThreading désactivé, car c'est le plus sûr

Il semble que nous devrions régler deux choses:

  1. MAXDOP (degrés maximum de parallélisme). Tout ce que je lis indique qu'avoir ce sans limites est probablement une mauvaise idée, et la documentation de Microsoft dit:

    La définition de cette option [MAXDOP] sur une valeur supérieure à [8] entraîne souvent une consommation indésirable des ressources et une dégradation des performances.

    quelque chose de plus élevé que ce qui 8n'est généralement pas recommandé .. donc je l'ai réglé 4pour l'instant. Il était initialement nul (sans limite).

  2. Seuil de coût pour le parallélisme. Apparemment, la valeur par défaut 5ici est considérée comme une valeur par défaut assez faible selon quelques publications SQL MVP que j'ai trouvées - nous pouvons la régler pour réduire la quantité de parallélisme tentée par le planificateur.

Mais honnêtement, cela ressemble à des solutions de contournement; Je pense que la vraie solution pour notre charge de travail (index plein texte lourd) est de désactiver HT.


4
MAXDOP provoque également des problèmes avec HT car il peut essayer d'exécuter deux threads sur le même processeur si vous avez, par exemple, 8 cœurs et 16 threads, et votre maxdop est défini sur 10. Généralement, 1 MAXDOP par processeur logique devrait être le maximum. Et exécuter deux threads sur le même CPU pour le même processus est un peu inutile.
Mark Henderson

2
@Farseeker qui ne se produit que si vous ne disposez pas d'un système d'exploitation compatible avec HyperThreading. Windows plus récent que 2000 en est conscient.
Mircea Chirea du

il convient de noter que ces remplacements maxdop ne causaient que des problèmes. par défaut était très bien pour nous
Sam Saffron

2
La version standard de SQL Server atteint un maximum de MAXDOP de 4 de toute façon lorsqu'elle n'est pas limitée. Besoin d'Enterprise pour aller plus haut que cela. Nous avons eu des charges de travail qui sont allées plus vite avec MAXDOP de 1 (boîtier non HT, exécutant plusieurs AMD à 8 cœurs) ...
Brian Knoblauch

1
@Brian Knoblauch - Je le sais plus d'un an plus tard, mais j'ai rencontré cette "version standard de SQL Server au maximum à MAXDOP de 4 de toute façon quand elle n'est pas limitée". Toute chance que vous puissiez me diriger vers une documentation. Nous parlons actuellement d'utiliser MAXDOP au travail, mais nous ne savons pas à quoi le régler. Cela signifie essentiellement que 4 est le même que non lié, n'est-ce pas?
Jeremy A. West

9

Anandtech a constaté qu'avec la charge de lecture pure, cela faisait un peu mal, et avec une charge d'écriture lourde, c'était un peu une victoire. Je n'ai rien vu qui me fasse penser que ça va vous faire un coup bien pire que -5%, ou une victoire bien meilleure que 15%. Notez qu'avec un Atom, c'est une énorme victoire, mais c'est un processeur très étrange.

Tout ce que vous avez changé, c'est le processeur? Vous êtes passé de 12 Mo de cache et 4 threads, donc 3 Mo de cache par thread, à 8 Mo de cache, et 8 threads, donc 1 Mo par thread. Maintenant, cela simplifie à l'excès, mais je parie que c'est ce qui vous tue, vous exécutiez des requêtes dans le cache et les exécutez maintenant à partir de la RAM car elles nécessitent plus de 1 Mo mais moins de 3 Mo. La désactivation de HT aidera probablement, mais je reviendrais à l'ancien processeur. Désactivez HT, et vous obtenez 2 Mo par thread, mais si votre charge de travail déborde de beaucoup, cela n'aidera pas. Il se pourrait bien que l'ancien processeur de cache de 12 Mo soit extrêmement plus rapide pour votre charge de travail.

J'essaierais de désactiver HT et de voir si c'est une amélioration, mais je soupçonne que le cache est roi pour votre charge de travail, et vous devrez peut-être revenir à la puce de 12 Mo.


3
Le cache L2 par observation est un noyau massif simplification, étant donné que l'unité centrale est une génération en avant (i7 Nehalem / Core vs Core 2 Quad classe).
Jeff Atwood

@Jess, @Ronald et Nehalem ont peu de cache L2. La majeure partie est L3 qui est partagée entre les cœurs.
Mircea Chirea

7

L'hyperthreading est, au mieux, juste un moyen d'abstraire la tâche de s'éloigner du système d'exploitation et de le placer sur la puce, avec un accès direct au cache L1 et L2, ce qui accélère le changement de tâche.

Les tests avec VMWare ont indiqué que la désactivation de HT ne faisait aucune différence perceptible sous une charge standard et une augmentation de 5% sous une charge lourde, car ESXi est suffisamment intelligent pour connaître la différence entre le "vrai" thread et le "faux" thread (Il y a beaucoup plus que cela, mais c'est en termes simples). SQL Server 2005 n'est pas tout à fait aussi intelligent, mais il combiné avec un système d'exploitation à jour, il devrait y avoir peu d'avantages à désactiver HT.

Cela dit, je suis d'accord avec Ronald que ce sera probablement votre cache L2. Une baisse de 33% de la taille du cache est substantielle, et lorsque nous spécifions nos serveurs SQL, nous optons toujours pour le cache à une vitesse d'horloge brute à chaque fois.


Pouvez-vous définir une affinité externe pour que les 4 cœurs appropriés soient ignorés par SQL?
Sam Saffron

3
En règle générale, vous définissez l'affinité entre les deux threads de processeur, mais tant que le MAXDOP est correctement défini, je ne vois aucune raison de définir l'affinité. Avec HT, le premier thread à être touché sur un processeur devient le thread "principal" et le deuxième thread est le thread "HT". Il n'y a pas de vrais threads "principal" et "ht" cependant, car c'est celui qui est arrivé en premier, puis quand ils changent de tâche, l'ordre est inversé.
Mark Henderson

Les processeurs basés sur Nehalem ont un cache L2 TRÈS, TRÈS PEU, la plupart partagés en L3.
Mircea Chirea du

7

D'après mon expérience, HT faisait en sorte que les opérations d'E / S prennent une éternité sur mes nœuds actifs sur un cluster Windows 2008 R2 (exécutant SQL Server 2008 R2). Un fait intéressant était que cela ne se reflétait ni dans les statistiques d'attente ni dans le pssdiag que j'ai exécuté pour le support de Microsoft.

La façon dont j'ai remarqué une faible E / S était simplement en regardant les compteurs du système d'exploitation pour le disque physique. Comme Sam l'a souligné, j'ai écrit à ce sujet ici et ici

Si vous ne rencontrez PAS de problèmes d'E / S et êtes lié au processeur, je vous suggère de commencer de cette façon:

Identifiez les processus et les blocs T-SQL qui provoquent le plus d'utilisation du processeur. D'après notre expérience, après avoir résolu le problème d'E / S (en désactivant HT), nous avons identifié du code qui fonctionnait horriblement en 2008 R2 et fonctionnait bien en 2005. J'ai écrit à ce sujet ici .

Sous forte charge, exécutez sp_whoisactive d'Adam Machanic. Vous pouvez le télécharger ici . Nous connaissions une utilisation très élevée du processeur en raison de la quantité excessive de lectures logiques (20 millions par requête) en raison d'un très mauvais plan. Nos processus effectuaient des jointures anti-semi avec des tables partitionnées.

Ma prochaine recommandation est d'exécuter le profileur pour identifier un ensemble de code T-SQL qui sont à la fois riches en lectures logiques CPU et E / S.

Grâce aux étapes ci-dessus, nous avons pu régler les processus incriminés et passer de 85% d'utilisation soutenue du processeur à presque zéro.

Bonne chance et n'hésitez pas à me laisser un message si vous trouvez un correctif car j'aimerais ajouter le cas à mon blog.

Merci

oscar


1
+1 pour le profileur, m'a sauvé de nombreuses fois une fois qu'un point problématique a été identifié
Mark Henderson

+1 merci pour toutes vos suggestions, régler notre SQL à un niveau raisonnable est un véritable cauchemar, nous dépendons assez largement du texte intégral pour nos relations avec les balises, nous recherchons souvent une liste d'éléments dans des balises particulières, donc nous saisissons l'ensemble régler et filtrer. Par exemple, obtenir une liste de questions avec les balises [x] et [y] classées par date implique d'extraire des quantités massives de données du texte intégral, puis une jointure massive.
Sam Saffron

Compris. Prenez un échantillon et exécutez-le avec des statistiques IO ON et voyez si vous pouvez localiser n'importe quelle table avec les lectures les plus logiques. Encore une fois, nous allions très bien en 2005 et vraiment mal en 2008 R2. Si vous trouvez simplement une utilisation élevée du processeur et que vous attendez un CXPACKET élevé, essayez d'abord en augmentant le seuil de coût pour le parallélisme à 10, 15 ou même 20.
ozamora

Si rien d'autre ne vous aide, déconnectez la base de données, désactivez HT et allez-y. Bonne chance
Ozamora

sp_whoisactive est un outil assez génial, j'adore la façon dont les requêtes sont cliquables
Sam Saffron

2

Il est difficile de déterminer si HT est bon ou mauvais.

Cela dépend vraiment du modèle de charge du serveur basé sur l'expérience et la lecture. Autrement dit, quand il affecte les performances, il le fait si mal : sinon vous ne le remarquez pas.

La théorie que j'ai lue était que les threads partagent le cache, ce qui signifie que dans des conditions défavorables, chaque thread peut écraser le cache de l'autre thread. Si vous n'avez pas beaucoup de parallélisme ou si votre charge est composée de nombreuses requêtes courtes, cela peut ne pas vous affecter.

J'ai essayé avec MAXDOP et l'affinité du processeur (de retour dans mon dernier vrai rôle DBA sur SQL Server 2000) mais je n'ai jamais rien trouvé de concluant: mais seulement pour ma boutique à l'époque.

Comme test rapide, vous pouvez définir l'affinité du processeur pour utiliser uniquement les cœurs physiques (les nombres inférieurs) et voir ce qui se passe.

Cependant, vous perdez tout au plus la moitié de vos cœurs. De nos jours, cela n'a plus d'importance par rapport à ce avec quoi je jouais il y a quelques années quand c'était 2 contre 4 ou 4 contre 8. Maintenant, c'est 8 contre 16 ou 16 contre 32.

Edit: Un test de Slava Oks


les cœurs 0-3 sont-ils physiques et 4-7 logiques? Est-ce ainsi que cela fonctionne? Nous ne pouvions pas le dire, et je ne pouvais trouver aucun outil pour me le faire savoir.
Jeff Atwood

2
@Jeff Atwood: J'en trouverai plus plus tard. Je l' ai lu quelque part .... Pour l'instant: support.microsoft.com/kb/322385
gbn

Cet article KB résume à peu près tout.
pauska

Bien que cet article de la base de connaissances contienne des informations utiles, il ne semble pas répondre directement à la question de Jeff sur la façon dont les processeurs logiques sont exactement mappés aux processeurs physiques. Mon cerveau a frit à mi-chemin, mais j'espère que cet article INTEL devrait vous donner ce dont vous avez besoin pour comprendre la cartographie: software.intel.com/en-us/articles/… voir également software.intel.com/en-us/ blogs / 2009/12/21 /… et ses liens associés.
BradC

@Jeff Atwood, @BradC: Lordy, difficile à trouver. Voyez ceci: il s'appuie sur les recommandations d'Intel. SQL Server utilisera l'énumération Windows sous-jacente download.microsoft.com/download/5/7/7/… .
gbn

2

Malheureusement, je ne pense pas que vous obtiendrez une réponse plus définitive que "essayez de désactiver l'hyperthreading et voyez si cela aide".

Malgré la réponse utile de Jonathan dans mon fil d'origine (que vous avez lié dans votre question), je n'ai jamais pu obtenir de preuves définitives de l'impact de HT sur les serveurs spécifiques sur lesquels j'étudiais. Dans mon cas, les serveurs étaient déjà programmés pour un remplacement, donc nous laissons simplement ces remplacements "s'occuper du problème" pour ainsi dire.

Mon conseil:

Essayez un paramètre MAX Degree of Parallelism au niveau du serveur de 1 . Le parallélisme sur SQL est de toute façon le plus utile pour les requêtes plus grandes et plus longues, et votre charge (je suppose) consiste en un nombre massivement élevé de requêtes plus petites. Cela devrait éliminer complètement les attentes de CXPACKET. Cela pourrait allonger légèrement certaines requêtes individuelles, mais devrait permettre davantage de "débit" du nombre total de requêtes sur le serveur.

J'ai eu de bons résultats en faisant cela sur des serveurs OLTP. D'autres types de serveurs (serveurs de rapports, serveurs de traitement, entreposage de données) ont certainement besoin d'un ensemble MAXDOP supérieur.

Et juste pour être clair, ce paramètre permettrait toujours à SQL d'utiliser plusieurs threads pour chaque table individuelle dans un JOIN, de sorte que vous n'éliminez pas vraiment complètement le parallélisme.

Cela vaut au moins la peine d'essayer, car ce changement de paramètre prend effet immédiatement et ne vous oblige même pas à redémarrer le service SQL: http://msdn.microsoft.com/en-us/library/ms181007.aspx
Cela signifie que vous pouvez basculer il revient immédiatement si les choses ont commencé à aller en enfer.

Désactiver l'hyperthreading dans le BIOS nécessiterait un redémarrage complet du serveur, c'est donc un peu plus risqué.


0

Pour mémoire, nous avons également eu de mauvaises performances inattendues après une mise à niveau du serveur. Cela s'est avéré être dû à des problèmes d'économie d'énergie du BIOS et du processeur. Le paramètre par défaut sur le serveur (HP) était d'ignorer le contrôle du système d'exploitation sur la vitesse du processeur et d'utiliser son propre algorithme. La modification de ce contrôle par le système d'exploitation et la mise à jour du BIOS ont entraîné des améliorations significatives. Il y avait des notes de publication (que je ne peux pas les trouver maintenant) qu'il y avait un bug du BIOS qui bloquait le processeur à l'état de performance le plus bas.

/server//a/196329/6390

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.