Liés à: 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 X547 vers un X556 . 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 DEMANDE_POUR_DEADLOCK_SEARCH 559393 2799053973 5180 2799053973 SOS_SCHEDULER_YIELD 152289883 18994868813813818816868818889 SLEEP_TASK 170743505 1525669557 1406 76485386 LATCH_EX 97301008 810738519 1107 55093884 LOGMGR_QUEUE 16525384 2798527632 20751319 4083713 WRITELOG 16850119 18328365 1193 2367880 [.________. 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_S]. 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 connaissons 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 DB précédent et le CPU est vraiment élevé.
La désactivation de l'hyperthreading contribuera-t-elle à réduire notre utilisation du processeur et à augmenter le débit?
Je pense toujours que tester votre charge de travail spécifique, selon la réponse d'origine, 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 d'essayer et de voir.
Je suis d'accord que
Il semble que nous devrions régler deux choses:
MAXDOP (degrés maximum de parallélisme). Tout ce que je lis indique qu'avoir ce illimité est probablement une mauvaise idée, et le documentation 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 supérieur à 8
n'est généralement pas recommandé. Je l'ai donc réglé sur 4
pour l'instant. Il était initialement nul (sans limite).
Seuil de coût pour le parallélisme. Apparemment, la valeur par défaut de 5
ici est considéré comme une valeur par défaut assez faible selon quelques articles SQL MVP que j'ai trouvés - nous pouvons le régler pour réduire le parallélisme même tenté 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.
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 trop, 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 RAM car elles ont besoin de plus de 1 Mo mais de moins de 3 Mo). Désactiver HT aidera probablement, mais je reviens à 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 Le processeur de 12 Mo de cache est 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.
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 ça, 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.
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 avec les 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 depuis 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
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 cela affecte les performances, il le fait 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 (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: n test de Slava Oks
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 être remplacés, nous avons donc simplement laissé ces remplaçants "s'occuper du problème" pour ainsi dire.
Mon conseil:
Essayez un paramètre de degré de parallélisme MAX 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 rallonger un peu certaines requêtes individuelles, mais devrait permettre davantage de "débit" du nombre total de requêtes sur le serveur.
J'ai obtenu de bons résultats en faisant cela sur les serveurs OLTP. D'autres types de serveurs (serveurs de rapports, serveurs de traitement, entreposage de données) ont certainement besoin de l'ensemble MAXDOP plus élevé.
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 pourriez le réactiver immédiatement si les choses commençaient à 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é.
Pour mémoire, nous avons également eu des 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. Le changement en contrôle du 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.