Service Broker - Gesprächslebensdauer?

9

Wir versuchen, Service Broker in unserer Umgebung zum Laufen zu bringen, um einen Business Case zu lösen. Ich weiß nicht, ob der Nachrichtentitel gut ist, aber meine Frage ist unten. Aber es ist vielleicht keine gute Frage, also ist es danach, was wir tun und warum ich denke, dass es die richtige Frage ist.

Wie viele Nachrichten sollten in einem Gespräch gesendet werden, bevor das Gespräch beendet wird?

Wir möchten Service Broker verwenden, um eine Ergebnistabelle asynchron zu aktualisieren. Die Ergebnistabelle ist abgeflacht und schnell. Wir haben Trigger für die Basistabellen, die eine Nachricht mit ihrer Tabelle und ihrem Primärschlüssel senden. Wir haben drei Warteschlangen:

  • Geringe Latenz - Ziel ist die Verarbeitung von 15 Sekunden. Es behandelt Elemente, die sich in Bezug auf ein bestimmtes Element ändern.
  • Massenwarteschlange - Ziel ist 5 Minuten zu verarbeiten. Es behandelt, wenn sich etwas ändert, das viele hundert (oder Tausende) Elemente betrifft. Es bricht die Liste der betroffenen Elemente auf und leitet sie an die Warteschlange für verzögerte niedrige Latenz weiter
  • Aufgeschobene niedrige Latenz - Ziel ist die Verarbeitung von 30 Minuten. Dadurch werden Elemente verarbeitet, jedoch nur aus der Massenwarteschlange.

Grundsätzlich, wenn die Informationen eines Kunden aktualisiert werden; Dies betrifft viele Produkte, sodass sie zur langsameren Verarbeitung an die Massenwarteschlange gesendet werden. Wenn ein Produkt jedoch aktualisiert wird, wird es an die Warteschlange mit geringer Latenz gesendet.

Wir verwenden Konversationen ähnlich wie Remus Rusanus Blog http://rusanu.com/2007/04/25/reusing-conversations/ , mit der Ausnahme, dass wir dies basierend auf dem Modul des Primärschlüssels tun. Dies hat den Nebeneffekt, dass die Deduplizierung von Primärschlüsseln unterstützt wird.

Wir verwenden Gespräche also wieder und halten uns an unsere Richtlinien. Mit zwei Threads konnte ich 125 Nachrichten / Sekunde durchbrennen (künstlicher Tropfen von mehreren tausend Nachrichten), was mehr als in der Lage ist, mit der Produktion Schritt zu halten (ca. 15 Nachrichten / Sek.).

Das Problem, das wir haben, ist jedoch, dass nach einer Zeitspanne von ~ 4 Stunden oder 120.000 Nachrichten Blöcke und hohe Konflikte bei sysdesend und der Warteschlangentabelle auftreten. Die Sperren sind LCK_M_U und KEY-Sperren. Manchmal wird der Hobt in sysdesend und manchmal in die spezifische Warteschlangentabelle (queue_) aufgelöst.

Wir haben einen Prozess eingerichtet, der Gespräche bereits nach 24 Stunden oder 30 Minuten Inaktivität beendet, sodass wir die Zeit vor dem Überfahren von Gesprächen verlängern können.

Wir verwenden SQL 2016 Enterprise (13.0.4001.0)

  1. Auslöser auslösen (entweder an niedrige Latenz oder an Bulk senden)
  2. Nachschlagen oder Konversationshandle erstellen.
  3. Nachricht senden
  4. Warteschlangenaktivierte Prozedur
  5. Ergebnis-Tabelle aktualisieren

Der Bereinigungsprozess wird alle 10 Minuten ausgeführt, um festzustellen, ob Gespräche im Leerlauf stattfinden. Wenn sie mehr als dreimal hintereinander gefunden werden, werden sie als inaktiv markiert und die Konversationen beendet.

Bitte lassen Sie mich wissen, ob zusätzliche Details von Vorteil sind. Ich habe nicht viel Erfahrung mit Service Broker, daher weiß ich nicht, ob unsere Nachrichten / Sek. Niedrig, hoch oder gleichgültig sind.

AKTUALISIEREN

Also haben wir es heute noch einmal versucht und sind auf das gleiche Problem gestoßen. Wir haben die Gesprächslebensdauer auf 2 Stunden geändert, was keine Auswirkungen hatte. Also haben wir dann den 150-Trick implementiert; das hatte das gleiche Problem.

Tonnenweise Wartezeiten bei SEND CONVERSATION, die auf sysdesend warten. Hat jemand weitere Ideen?

UPDATE 2

Wir haben den Test heute länger durchgeführt und für einen der Beispielzeiträume von 17 Minuten 41.000 Nachrichten auf 4 Konversationshandles verarbeitet. Wir konnten mithalten, außer gegen Ende, als die Schlösser des Systems und der Warteschlangentabelle zu groß wurden und wir anfingen, hinterher zu driften, bevor wir sie stoppten. Wir scheinen kein Problem damit zu haben, Nachrichten zu verarbeiten. Ohne dass Dinge in die Warteschlange gelangen, können wir sie abziehen und mindestens fünfmal so schnell verarbeiten. Unsere Geschwindigkeit scheint aufgrund des Hinzufügens von Nachrichten begrenzt zu sein.

Bei einem späteren Test haben wir einen der Auslöser entfernt, auf die 80% der Nachrichten entfielen. Trotz dieser stark reduzierten Last sahen wir die gleichen Wartezeiten.

UPDATE 3

Vielen Dank, Remus, für Ihren Rat (und vielen Dank, dass Sie so hervorragende Blog-Artikel zu diesem Thema veröffentlicht haben, dass sie maßgeblich dazu beigetragen haben, diesen Punkt zu erreichen).

Wir haben es heute wieder laufen lassen und es besser gemacht (da wir länger gegangen sind, bevor wir die Wartezeiten gesehen haben und noch länger, bevor es uns verkrüppelt hat). Also die Details.

Wir haben Folgendes geändert: * Die Anzahl der gepflegten Konversationen pro Thread wurde von 1: 1 auf 2: 1 erhöht. Grundsätzlich hatten wir 8 Konversationshandles für 4 Threads.

  • Konsolidierung der Massenwarteschlange (da eine eingehende Nachricht Hunderte von ausgehenden Nachrichten bedeuten kann) zur Konsolidierung in weniger, größeren Nachrichten.

Anmerkungen zu diesem Versuch:

  • Deaktivieren der Aktivierungsprozedur für die Zielwarteschlange. Keine Änderung beim Blockieren (wir haben 5 Minuten gewartet) und die Nachrichten wurden an sys.transmission_queues gesendet.

  • Überwachung von sys.conversation_endpoints. Diese Zahl stieg sehr schnell von 0 13K und stieg dann im Laufe des Tages langsamer an und endete nach ~ 5 Stunden bei 25K. Das Blockieren begann erst, als es 16K +/- erreichte.

  • Ich ging in den DAC und führte die DBREINDEX-Befehle für die Warteschlangen aus, obwohl nach einer Abfrage die Geisteraufzeichnungen vor der Bereinigung nie über 200 lagen und die Anzahl auf 0 sanken.

  • sysdesend und sysdercv hatten identische Zahlen von 24.932, als ich den Test beendete.

  • Wir haben ~ 310K Nachrichten in 5 Stunden verarbeitet.

Wir gingen so lange, bis die Dinge auseinander fielen, dass ich wirklich dachte, wir würden es diesmal schaffen. Morgen werden wir versuchen, die Nachrichten zu zwingen, durch den Draht zu gehen.

Jonathan Fite
quelle
1
we started seeing blocks and high contention on sysdesend and the queue table.-> Was ist der Wartetyp - PAGELATCH_EX/SH and WRITELOG? Hast du den 150er Trick benutzt ? Wenn Systemtabellen Ihr Streitpunkt sind, ist der 150-Trick sehr nützlich.
Kin Shah
@kin, ich habe die Frage aktualisiert, aber die Sperrtypen sind LCK_M_U oder LCK_M_X. Ich hatte über den 150-Trick gelesen, hoffte aber, dass er 2016 unnötig war (da sie auch das Problem mit dem Tempdb-Leck gelöst hatten), aber auch, weil es wie ein solcher Hack aussieht. Wir werden einen weiteren Versuch unternehmen, in die Produktion zu gehen (dies begegnet uns leider nur bei Produktionsauslastungen) und werden zuerst Gespräche mit einer kürzeren Lebensdauer versuchen. Ich werde hier mit Ergebnissen aktualisieren. Als nächstes folgt der 150-Trick, auf den Sie verwiesen haben.
Jonathan Fite
Ich habe @RemusRusanu auf Twitter gefragt - er ist DER Experte für Service-Broker-Sachen :-)
Kin Shah
Dies habe ich noch nie gesehen (Verschlechterung von SEND nach langer Laufzeit). 1) Bitte sagen Sie mir, wie viele Zeilen sys.conversation_endpointswährend des Tests vorhanden sind (konstant oder steigend und wie groß sie sind, wenn die Blockierung auftritt). 2) Wenn Blockieren auftritt, wird der Deaktivierung Zielwarteschlange einen Unterschied in SEND machen Blocking (Deaktivieren der Warteschlange sollte Route SEND sys.transmission_queue). und 3) Das Erzwingen, dass die Nachrichten auch lokal an die Leitung gesendet werden (SSB-Endpunkt einrichten, Routen hinzufügen), ändert das Verhalten auf lange Sicht
Remus Rusanu
Noch ein paar Gedanken: 4) Wenn das Blockieren auftritt, macht das Stoppen des EMPFANGS auf dem Ziel einen Unterschied (deaktivieren Sie den aktivierten Prozess, falls vorhanden) und 5) wie viele Geisteraufzeichnungen befinden sich in der Zielwarteschlange? Macht das Laufen ALTER QUEUE ... REBUILDeinen Unterschied, sobald das Blockieren beginnt?
Remus Rusanu

Antworten:

3

Ich weiß, dass es eine schlechte Form ist, Ihre eigene Frage zu beantworten, aber ich wollte dies für alle schließen, die interessiert waren. Wir haben es endlich geschafft, das Problem zu lösen oder es zumindest so weit zu lösen, dass es unseren Anforderungen entspricht. Ich möchte allen danken, die Kommentare abgegeben haben. Remus Rusanu und Kin waren sehr hilfreich.

Unsere Datenbank ist ziemlich voll und befindet sich im RCSI-Modus. Wir haben mehrere (Tausende) mobile Geräte, die ihre Standortinformationen alle 45 Sekunden aktualisieren. Durch diese Aktualisierungen werden die Informationen mehrerer Tabellen aktualisiert (schlechtes Design, da ich die flüchtigen Informationen auf eine einzelne Tabelle beschränkt und sie dann für die Ergebnisse zusammengefügt hätte). Diese Tabellen sind dieselben, für die wir versucht haben, asynchron Berichtsinformationen zu generieren, anstatt dass die Endbenutzer direkt mit den Basistabellen verglichen werden.

Wir hatten anfangs die Trigger, die in jeder Update / Insert-Anweisung einen Cursor über die geänderten Datensätze bewegten (sollte in den meisten Fällen eine Zeile gewesen sein) und jeden Primärschlüssel in einer Nachricht an den Service Broker gesendet haben. Innerhalb des Service Brokers, insbesondere der Massenwarteschlange, befanden sich weitere Cursor, die die Upsert-Prozedur für den Bericht ausführten (eine Ausführung pro Primärschlüssel).

Was hat uns endlich zum Arbeiten gebracht:

  • Wir haben die Cursor entfernt und beschlossen, größere Nachrichten zu senden. Immer noch eine Nachricht pro Benutzertransaktion pro Tabelle, aber wir senden jetzt Nachrichten mit mehr als einem Primärschlüssel.

  • Der Massenprozessor sendet auch mehrere Schlüssel pro Nachricht, wodurch die Anzahl der SEND CONVERSATIONS, die beim Mischen von Nachrichten in die andere Warteschlange ausgeführt wurden, entsprechend reduziert wurde.

  • Bei der volatilsten Tabelle (unserer Datentabelle für mobile Geräte) wurden die Auslöser entfernt. Wir haben das Upsert-Verfahren so aktualisiert, dass es die entsprechenden Fremdschlüssel enthält, und jetzt verbinden wir uns einfach wieder mit dieser Tabelle, wenn wir den Benutzern Ergebnisse abrufen. Diese Tabelle trug leicht 80% der Nachrichten bei, die wir an einem Tag verarbeiten mussten.

Wir verarbeiten ~ 1 Million Nachrichten pro Tag (ohne die Mobile-Tabelle) und die überwiegende Mehrheit (99% +) unserer Nachrichten wird innerhalb unseres Ziels verarbeitet. Wir haben immer noch gelegentliche Ausreißer, aber angesichts der Seltenheit, dass dies als akzeptabel angesehen wird.

Ausschlaggebende Faktoren:

  • Ich habe einen Fehler in der zuvor erwähnten Konversationsbereinigungsprozedur gefunden, der dazu führte, dass Konversationen nicht ordnungsgemäß bereinigt und vorzeitig beendet wurden. Dies hat nun dazu geführt, dass unsere Sysdesend-Zahl nie mehr als ein paar Tausend beträgt (das meiste davon stammt aus der Verwendung des 150-Tricks).

  • Die Cursor in den Triggern schienen mehr Sperren zu haben als erwartet (selbst bei statischen, forward_only). Das Entfernen dieser Sperren scheint die Sperren, die wir in SEND CONVERSATION sehen, vorübergehender gemacht zu haben (oder zumindest die Zeiten, die wir sehen, sind viel niedriger).

  • Wir haben im Wesentlichen zwei Lösungen nebeneinander ausgeführt (das Service Broker-Lösungs-Backend (zum Testen unter Produktionslast)) und die aktuelle Lösung (schreckliche Abfrage, die viele Tabellen umfasst).

Als Nebeneffekt hat dies ein Ghost Record Cleanup-Problem aufgedeckt, und obwohl es nicht in den Service Broker-Tabellen (System oder Warteschlange) enthalten war, ist es in unserem System ziemlich weit verbreitet und die Symptome stimmen sehr gut mit unserer "nicht klaren Ursache" überein. Probleme, die wir manchmal erleben. Die Untersuchung ist noch nicht abgeschlossen. Wir versuchen, die Tabellen zu finden, die dazu beitragen, und wir werden ihre Indizes wahrscheinlich nur routinemäßig neu erstellen.

Vielen Dank noch mal.

Jonathan Fite
quelle