Nous sommes occupés à tester en charge un système OLTP que nous avons développé dans .NET 4.0 et exécutons SQL Server 2008 R2 à l'arrière. Le système utilise des files d'attente SQL Server Service Broker, qui sont très performantes, mais nous connaissons une tendance particulière lors du traitement.
SQL Server traite les demandes à une vitesse fulgurante pendant 1 minute, suivie par environ 20 secondes d'activité d'écriture sur disque accrue. Le graphique suivant illustre le problème.
Yellow = Transactions per second
Blue = Total CPU usage
Red = Sqlsrv Disk Write Bytes/s
Green = Sqlsrv Disk Read Bytes/s
Pendant le dépannage, nous avons essayé ce qui suit sans aucun changement significatif dans le modèle:
- Agent SQL Server arrêté.
- Tué presque tous les autres processus en cours d'exécution (pas d'A / V, SSMS, VS, Windows Explorer, etc.)
- Suppression de toutes les autres bases de données.
- Désactivé tous les minuteurs de conversation (nous n'utilisons aucun déclencheur).
- Déplacé d'une approche basée sur la file d'attente de messages vers une conception de surveillance de table simple / brute.
- Utilisé différentes charges de légères à lourdes.
- Correction de tous les blocages.
Il semble que SQL Server puisse créer son cache et l'écrire sur le disque à des intervalles temporels spécifiques, mais je ne trouve rien en ligne pour soutenir cette théorie.
Ensuite, je prévois de déplacer la solution vers notre environnement de test dédié pour voir si je peux reproduire le problème. Toute aide dans l'intervalle serait grandement appréciée.
Mise à jour 1 Comme demandé, ci-joint un graphique qui inclut les pages de point de contrôle / s , l' espérance de vie de la page et certains compteurs de latence de disque.
Il semble que le point de contrôle (ligne bleu clair) soit à l'origine de la baisse des performances (ligne jaune) que nous observons. ^
La latence du disque reste relativement cohérente pendant le traitement et l'espérance de vie de la page ne semble pas avoir d'effet notable. Nous avons également ajusté la quantité de RAM disponible pour SQL Server, ce qui n'a pas non plus eu un grand effet. La modification du modèle de récupération de SIMPLE
à FULL
n'a également fait aucune différence.
Mise à jour 2 En modifiant «l'intervalle de récupération» comme suit, nous avons réussi à réduire l'intervalle auquel les points de contrôle se produisent:
EXEC sp_configure 'show advanced options',1
GO
RECONFIGURE
GO
EXEC sp_configure 'recovery interval', '30'
GO
RECONFIGURE
GO
EXEC sp_configure 'show advanced options',0
GO
RECONFIGURE
Je ne sais pas si c'est une mauvaise pratique?
la source
FULL
ouBULK_LOGGED
, elle se comporte toujours comme si elle se trouvaitSIMPLE
jusqu'à ce que vous effectuiez une sauvegarde complète.Réponses:
D'autres ont déjà signalé le coupable: SQL Server accumule les mises à jour en mémoire (dans le pool de mémoire tampon) et ne les vide que périodiquement (aux points de contrôle). Les deux options proposées (-k et intervalle de point de contrôle) sont complémentaires:
Mais je n'ai pas répondu seulement pour régurgiter les bons commentaires que vous avez reçus faites loin :)
Ce que vous voyez est, malheureusement, un comportement très typique du traitement en file d' attente . Que vous utilisiez des files d'attente Service Broker ou que vous optiez pour l' utilisation de tables à l' approche des files d'attente , le système est très sujet à ce type de comportement. En effet, le traitement basé sur la mise en file d'attente est lourd en écriture, encore plus en écriture que le traitement OLTP. Les deux enqueue et dequeue primitives sont des opérations d'écriture et il y a des opérations presque pas lus. Autrement dit, le traitement de la file d'attente générera le plus d'écritures (= la plupart des pages sales et la plupart des journaux) par rapport à toute autre charge de travail, même OLTP (c'est - à-dire charge de travail de type TPC-C ).
Très important, les écritures d'une charge de travail de file d'attente suivent un modèle d'insertion / suppression: chaque ligne insérée est très rapidement supprimée. Ceci est important à distinguer d'un modèle en ajout uniquement d'une charge de travail ETL (insert heavy). Vous nourrissez essentiellement la tâche de nettoyage des fantômes avec un repas complet, et vous pouvez facilement le dépasser. Réfléchissez à ce que cela signifie:
Oui, cela signifie vraiment que vous pouvez finir par écrire une page trois fois sur le disque, dans trois demandes d'E / S différentes, pour chaque message que vous traitez (pire cas). Et cela signifie également que les entrées-sorties aléatoires des points de contrôle seront vraiment aléatoires car le point d'écriture de la page sera à nouveau visité par ces têtes mobiles entre deux points de contrôle (comparer avec de nombreuses charges de travail OLTP ont tendance à regrouper les écritures sur certains `` points chauds '', pas de files d'attente ...).
Vous avez donc ces trois points d'écriture, en course pour marquer la même page encore et encore. Et c'est avant que nous considérions les fractionnements de page, quel traitement de file d'attente peut également être sujet à cause de l'ordre d'insertion des clés. En comparaison, les charges de travail OLTP `` typiques '' ont un rapport lecture / écriture beaucoup plus équilibré et les écritures OLTP sont réparties sur les insertions / mises à jour / suppressions, souvent avec des mises à jour (changements de `` statut '') et des insertions qui prennent la part du lion. Les écritures de traitement de file d'attente sont exclusivement insérées / supprimées avec, par définition, une répartition 50/50.
Certaines conséquences s'ensuivent:
Ma recommandation se décline en 3 lettres: S, S et D. Déplacez votre MDF vers un stockage capable de gérer des E / S aléatoires rapides. SSD. Fusion-IO si vous avez l'argent. Malheureusement, c'est l'un de ces symptômes qui ne peut pas être résolu avec une RAM plus bon marché ...
Éditer:
Comme le souligne Mark, vous disposez de deux disques logiques soutenus par un disque physique. Vous avez peut-être essayé de suivre les meilleures pratiques et de diviser le journal sur D: et les données sur C: mais hélas, en vain, C et D sont le même disque. Entre les points de contrôle, vous atteignez un débit séquentiel, mais dès que le point de contrôle démarre, les têtes de disque commencent à se déplacer et votre débit de journal s'effondre, ce qui réduit le débit de l'application entière. Assurez-vous de séparer le journal de base de données afin qu'il ne soit pas affecté par les données d'E / S (disque distinct).
la source
C:
etD:
des disques logiques soutenus par le même disque physique. Je doute que le disque physique soit une batterie de 100 broches courtes, donc c'est probablement la cause première.