web-dev-qa-db-fra.com

Étrange problème de performances avec SQL Server 2016

Nous avons une seule instance de SQL Server 2016 SP1 exécutée sur une machine virtuelle VMware. Il contient 4 bases de données, chacune pour une application différente. Ces applications sont toutes sur des serveurs virtuels séparés. Aucun d'entre eux n'est encore utilisé en production. Les personnes qui testent les applications signalent cependant des problèmes de performances.

Ce sont les statistiques du serveur:

  • 128 Go RAM (mémoire maximale de 110 Go pour SQL Server)
  • 4 cœurs à 4,6 GHz
  • Connexion réseau de 10 Go
  • Tout le stockage est basé sur SSD
  • Les fichiers programme, les fichiers journaux, les fichiers de base de données et tempdb se trouvent sur des partitions distinctes du serveur
  • asd

Les utilisateurs effectuent un accès à un seul écran via une application basée sur C++ ERP.

Lorsque je teste le serveur SQL avec le ostress de Microsoft en utilisant de nombreuses petites requêtes ou une grande requête, j'obtiens des performances maximales. La seule chose qui limite est le client, car il ne peut pas répondre assez rapidement.

Mais lorsqu'il n'y a pratiquement pas d'utilisateurs, SQL Server ne fait pratiquement rien. Pourtant, les gens doivent attendre indéfiniment juste pour enregistrer quoi que ce soit dans l'application.

Selon la requête " Dites-moi où ça fait mal " de Paul Randal, 50% de tous les événements d'attente sont ASYNC_NETWORK_IO.

Cela peut signifier soit un problème de réseau, soit un problème de performances avec le serveur d'applications ou le client. Aucun d'entre eux n'utilise même ses ressources à distance à pleine capacité. La plupart du temps, le CPU est d'environ 26% sur toutes les machines (client, serveur d'applications, serveur db).

La latence de la connexion réseau est d'environ 1 à 3 ms. Le IO du serveur db est à une vitesse d'écriture maximale de 20 Mo/s lors d'une utilisation normale avec l'application (la moyenne est de 7 à 9 Mo/s). Lorsque je teste le stress, je me déplace autour de 5 Go/max s.

La taille du cache tampon est de 60 Go pour la base de données de notre système ERP, 20 Go pour notre logiciel de financement, 1 Go pour le logiciel d'assurance qualité, 3 Go pour le système d'archivage de documents.

J'ai donné au compte SQL Server le droit d'utiliser Instant File Initialization . Cela n'a pas du tout augmenté les performances.

L'espérance de vie de la page est d'environ 15k + lors d'une utilisation normale. Chute à environ 0,05 km à la fin des tests de résistance, ce qui est prévisible. Les lots/s se situent autour de 2 à 8 000, selon la charge de travail.

Je dirais que l'application ERP est juste mal écrite, mais je ne peux pas car toutes les applications sont affectées. Même avec une charge de travail minimale.

Pourtant, je ne peux pas déterminer exactement ce qui cause cela. Y a-t-il des conseils, des astuces, des didacticiels, des applications, des documents sur les meilleures/pires pratiques ou toute autre chose que vous avez en tête concernant ce problème?

Ce sont les résultats de sp_BlitzFirst:

enter image description here

enter image description here

Je l'ai couru 600 secondes. Je l'ai démarré pendant une charge de travail élevée de l'application. 1/3 du temps c'est ASYNC_NETWORK_IO. J'ai également testé la connexion réseau avec NTttcp, PsPing, ipferf3 et pathping. Rien d'inhabituel. Les temps de réponse sont au maximum de 3 ms, en moyenne 0,3 ms. Le débit est d'environ 1000 Mo/s.

Mon enquête aboutit toujours à ASYNC_NETWORK_IO étant la première attente.

Nous avons étudié le résultat de la désactivation du Large-Receive-Offload fonctionnalité dans VMware. Nous testons toujours, mais les résultats semblent contradictoires. Notre premier "benchmark" a abouti à une durée de 19 minutes (le meilleur résultat est 13 minutes, ce qui n'est atteint que lorsque l'application s'exécute sur le VM avec SQL Server lui-même). Le deuxième résultat est 28 minutes, ce qui est vraiment mauvais.

Le premier résultat de notre "benchmark" était de 19 minutes. Ce qui est bon. Parce que le résultat supérieur était de 13 minutes (ce qui n'est possible que lorsque les tests d'application sur le VM avec le serveur SQL lui-même). Cela fait fortement allusion à un problème lié au réseau. Ou un problème avec le VMware configuration.

Je suis actuellement perdu sur les méthodes à utiliser, pour le clouer au goulot d'étranglement.

Les performances maximales avec l'application ne sont réalisables que lorsque l'application s'exécute sur le VM avec SQL Server lui-même. Si l'application est exécutée sur un autre VM ou bureau virtuel la durée de notre benchmark est triplée (de 13 minutes à 40 minutes ou plus). Tous les points de terminaison (VM de SQL Server, VM du serveur d'application et du bureau virtuel) utilisent le même matériel physique. Nous avons déplacé tous les autres points de terminaison vers un autre matériel.

EDIT: On dirait que le problème est de retour. Après avoir réglé le mode d'économie d'énergie de équilibré à haute performance, nous avons amélioré considérablement les temps de réponse. Mais aujourd'hui, j'ai de nouveau exécuté sp_BlitzFirst, avec un échantillon de 300 secondes. Voici le résultat:

This is the result

Il affiche plus de secondes d'attente pour ASYNC_NETWORK_IO que les secondes que sp_blitzfirst a exécutées.

14
Emptyslot

Pour répondre à ma propre question: la principale raison pour laquelle ASYNC_NETWORK_IO apparaît sur notre serveur SQL en tant que premier type d'attente, est que le energy saving le paramètre du serveur Windows a été défini sur 'balanced' au lieu de 'high performance'. Nous avons ensuite parlé à certains administrateurs de vm ware, et ils ont tous dit que ce paramètre tue les performances.

Les solutions pour cela sont soit:

  • N'installez pas le contrôle d'énergie lors de l'installation du serveur Windows
  • Définissez le mode d'économie d'énergie sur hautes performances pour tous les serveurs via une stratégie de groupe

Tous les autres problèmes/statistiques concernant ASYNC_NETWORK_IO sont liés à notre application ERP mal écrite. Merci à tous ceux qui m'ont aidé à résoudre ce problème, vos commentaires, suggestions et conseils ont été très bienvenus et utiles!

6
Emptyslot

Si votre attente principale est ASYNC_NETWORK_IO, le problème ne vient pas de SQL Server. Cela est presque toujours dû à un goulot d'étranglement de l'application. Je ne parle pas d'un goulot d'étranglement sur le serveur d'applications, mais plutôt d'un goulot d'étranglement dans l'application.

Le goulot d'étranglement de l'application est généralement dû au traitement ligne par ligne pendant que SQL Server envoie les données:

  • L'application demande des données à SQL Server
  • SQL Server envoie les données rapidement
  • L'application indique à SQL Server d'attendre pendant le traitement de chaque ligne
  • SQL Server enregistre le temps d'attente sur ASYNC_NETWORK_IO pendant que l'application lui demande d'attendre

Au lieu de cela, l'application doit consommer toutes les données de SQL Server et ALORS faire son traitement ligne par ligne. SQL Server est hors de vue à ce stade.

sp_BlitzFirst production

Le LCK_M_S l'attente n'est pas élevée. Il ne contient que 2 secondes de l'échantillon de 30 secondes et sa moyenne n'est que de 400 ms. C'est très, très peu susceptible d'être le problème. ASYNC_NETWORK_IO est votre première attente dans cet exemple. Encore un problème d'application. Si vous voulez de l'aide avec les choses LCK, nous aurions besoin de voir les requêtes impliquées.

Même ASYNC_NETWORK_IO n'est pas si mal dans cet échantillon. Mes yeux deviennent grands lorsque le temps d'attente est égal ou supérieur à la taille de l'échantillon. C'est alors que je creuse.

Tout votre problème est ASYNC_NETWORK_IO. Ce n'est pas un problème SQL Server. C'est un problème avec l'application (faisant le traitement ligne par ligne pendant que SQL Server envoie les données), le serveur d'application (vous avez déjà dit que ça va) ou le réseau (vous avez dit que le réseau allait bien). Le problème est donc lié à l'application. L'application C++ doit être corrigée.

18
Tara Kizer