Nous essayons de faire fonctionner Service Broker dans notre environnement afin de résoudre une analyse de rentabilisation. Je ne sais pas si le titre du message est bon, mais ma question est ci-dessous. Mais ce n'est peut-être pas une bonne question, alors après c'est ce que nous faisons et pourquoi je pense que c'est la bonne question.
Combien de messages doivent être envoyés lors d'une conversation avant de mettre fin à la conversation?
Nous voulons utiliser Service Broker afin de mettre à jour de manière asynchrone une table de résultats. Le tableau des résultats est aplati et rapide. Nous avons des déclencheurs sur les tables de base qui envoient un message avec leur table et leur clé primaire. Nous avons trois files d'attente:
- Faible latence - l'objectif est de 15 secondes à traiter. Il gère les éléments qui changent par rapport à un élément spécifique.
- Bulk Queue - l'objectif est de 5 minutes à traiter. Il gère quand quelque chose change qui affecte plusieurs centaines (ou milliers) d'éléments. Il éclate la liste des éléments qui ont été affectés et les alimente dans la file d'attente à faible latence différée
- Faible latence différée - l'objectif est de 30 minutes à traiter. Cela traite les éléments mais uniquement à partir de la file d'attente en bloc.
Fondamentalement, si les informations d'un client sont mises à jour; cela affecte de nombreux produits et est envoyé à la file d'attente en bloc pour un traitement plus lent. Cependant, si un produit est mis à jour, il est envoyé à la file d'attente à faible latence.
Nous réutilisons des conversations similaires au blog de Remus Rusanu http://rusanu.com/2007/04/25/reusing-conversations/ , à l'exception que nous le faisons en fonction du module de la clé primaire. Cela a l'avantage secondaire de faciliter la déduplication des clés primaires.
Nous réutilisons donc les conversations et respectons nos directives. Avec deux threads, j'ai pu graver 125 messages / seconde (baisse artificielle de plusieurs milliers de messages), ce qui est plus que capable de suivre la production (environ 15 messages / sec).
Cependant, le problème que nous rencontrons est qu'après une période de temps, ~ 4 heures ou 120 000 messages, nous avons commencé à voir des blocs et des conflits élevés sur sysdesend et la table de file d'attente. Les verrous sont LCK_M_U et sont des verrous KEY. Parfois, le hobt se résout en sysdesend et d'autres fois en table de file d'attente spécifique (queue_).
Nous avons un processus en place qui mettra fin aux conversations après 24 heures ou 30 minutes d'inactivité, nous pourrions donc simplement augmenter le temps avant de parcourir les conversations.
Nous utilisons SQL 2016 Enterprise (13.0.4001.0)
- Déclencher des incendies (envoyer à faible latence ou en masse)
- Recherchez ou créez une poignée de conversation.
- envoyer le message
- Procédure activée dans la file d'attente
- Mettre à jour le tableau des résultats
Le processus de nettoyage s'exécute toutes les 10 minutes pour voir s'il y a des conversations inactives. s'il les trouve plus de trois fois de suite, il le marque comme inactif et met fin aux conversations.
Veuillez me faire savoir s'il y a des détails supplémentaires qui pourraient être bénéfiques. Je n'ai pas beaucoup d'expérience avec Service Broker, donc je ne sais pas si nos messages / sec sont faibles, élevés ou indifférents.
MISE À JOUR
Nous avons donc réessayé aujourd'hui et avons rencontré le même problème. Nous avons changé la durée de vie de la conversation à 2 heures et cela n'a eu aucun effet. Nous avons donc mis en œuvre l'astuce 150; qui avait le même problème.
Des tonnes d'attente sur SEND CONVERSATION, en attente sur sysdesend. Quelqu'un a-t-il d'autres idées?
MISE À JOUR 2
Nous avons effectué le test plus longtemps aujourd'hui et pendant l'une des périodes d'échantillonnage de 17 minutes, nous avons traité 41 000 messages sur 4 poignées de conversation. Nous avons pu suivre, sauf vers la fin, lorsque les verrous du sysdesend et de la table de file d'attente sont devenus trop importants et nous avons commencé à dériver derrière avant de l'arrêter. Nous semblons n'avoir aucun problème à traiter les messages, sans que des choses entrent dans la file d'attente, nous pouvons les retirer et les traiter au moins 5 fois cette vitesse. Notre vitesse semble être limitée en fonction de l'ajout de messages.
Lors d'un test ultérieur, nous avons supprimé l'un des déclencheurs qui représentaient 80% des messages. Même avec cette charge très réduite, nous avons commencé à voir les mêmes attentes.
MISE À JOUR 3
Merci, Remus pour vos conseils (et merci d'avoir posté d'excellents articles de blog sur le sujet, ils ont contribué à ce point).
Nous l'avons couru à nouveau aujourd'hui et nous avons fait mieux (comme nous y sommes allés plus longtemps avant de voir les attentes et encore plus longtemps avant qu'il ne nous paralyse). Donc, les détails.
Nous avons changé: * Augmentation du nombre de conversations maintenues par thread de 1: 1 à 2: 1. Fondamentalement, nous avions 8 poignées de conversation pour 4 threads.
- consolidé la file d'attente en masse (car un message entrant peut signifier des centaines de messages sortants) pour se regrouper en moins de messages plus volumineux.
Remarques sur cette tentative:
désactivation de la procédure d'activation de la file d'attente cible. aucun changement dans le blocage (nous avons attendu 5 minutes) et les messages ont été envoyés à sys.transmission_queues.
surveillance de sys.conversation_endpoints. Ce nombre est passé de 0 à 13K très rapidement, puis a augmenté plus lentement tout au long de la journée pour atteindre environ 25K après environ 5 heures. Le blocage n'a commencé à se produire qu'après avoir atteint 16K +/-
Je suis entré dans le DAC et j'ai exécuté les commandes DBREINDEX pour les files d'attente, bien que, à partir d'une requête, les enregistrements fantômes n'aient jamais dépassé 200 ou plus avant le nettoyage et que le nombre soit tombé à 0.
sysdesend et sysdercv avaient des comptes identiques de 24 932 lorsque j'ai terminé le test.
nous avons traité environ 310 000 messages en 5 heures.
Nous sommes allés si longtemps avant que les choses ne s'effondrent que je pensais vraiment que nous réussirions cette fois. Demain, nous essaierons de forcer les messages à passer par le fil.
sys.conversation_endpoints
pendant le test (constant ou augmente, et quelle est sa taille lorsque le blocage se produit). 2) Lorsque le blocage se produit, la désactivation de la file d'attente cible fait-elle une différence dans le blocage de SEND (la désactivation de la file d'attente doit acheminer SEND vers sys.transmission_queue). et 3) Forcer les messages à passer au fil, même localement (configurer un point de terminaison SSB, ajouter des routes) change le comportement à long terme
ALTER QUEUE ... REBUILD
fait-elle une différence une fois que le blocage commence?
we started seeing blocks and high contention on sysdesend and the queue table.
-> Quel est le type d'attente -PAGELATCH_EX/SH and WRITELOG
? Avez-vous utilisé le truc 150 ? Si les tables système sont votre point de contention, l'astuce 150 sera très utile.