Das CAC wird häufig gebeten, Probleme mit VOS-Warteschlangen zu untersuchen. Hier sind ein paar interessante, zusammen mit einigen Lösungen und Empfehlungen, die ich gerne mit Ihnen teilen möchte.
Problem 1: Vor kurzem kam ein Kunde mit einem Problem zu uns. Ein Anforderer war nicht in der Lage, eine Nachricht zu einer Nachrichtenwarteschlange hinzuzufügen, da er den Fehlercode e$max_file_exceeded erhielt. Seltsamerweise war die Warteschlange leer, wie der Befehl list_messages zeigte.
Bei der Untersuchung der Warteschlange wurde festgestellt, dass sich die Anzahl der für diese Warteschlange verwendeten Festplattenblöcke der maximalen Dateigröße für eine Datei ohne Ausdehnung näherte.
Name: %s1#d01>AppData>queue.MQ
Dateiorganisation: Nachrichtenwarteschlangen-Datei
zuletzt verwendet am: 11-08-16 14:45:13 edt
zuletzt geändert am: 11-08-16 14:45:13 edt
zuletzt gespeichert am: 10-06-14 21:34:18 edt
erstellt am: 10-06-09 11:03:15 edt
Transaktionsdatei: ja
loggeschützt: nein
Sicherheitsschalter: nein
Audit: nein
dynamische Extents: nein
Extent-Größe: 1
letzte Meldung: 51689380
verwendete Blöcke: 520201
…
Warum war diese Warteschlange sowohl voll als auch leer?
Irgendwann in der Vergangenheit waren die Server, die für den Abfluss der Nachrichten aus der Warteschlange zuständig waren, offline. Dies führte zu einem sehr großen Rückstau an Nachrichten. Diese Nachrichten wurden schließlich von den Servern abgearbeitet und aus der Warteschlange gelöscht. Wenn Nachrichten aus einer Warteschlange gelöscht werden, wird ein Schlüssel zum Index _record_index der Warteschlange hinzugefügt, und der Schlüsselwert gibt die Anzahl der Bytes der gelöschten Nachricht(en) an. Wenn eine neue Nachricht zu einer Nachrichten-Warteschlange hinzugefügt wird, versucht das Dateisystem, eine zuvor gelöschte Nachricht zu finden, die genau die Größe der neuen Nachricht hat. Wenn keine vorhanden ist, wird die neue Nachricht in den jungfräulichen Speicherplatz am Ende der Warteschlange geschrieben.
In diesem Fall war nicht genügend freier Platz in der Warteschlange vorhanden, um die neue Nachricht aufzunehmen, und es gab keine bereits vorhandene gelöschte Nachricht mit der richtigen Größe.
Die Moral von der Geschichte ist, dass es eine gute Idee ist, die Anzahl der eindeutigen Nachrichtenlängen in einer bestimmten Warteschlange zu begrenzen. Anstatt jede Nachricht die genaue Anzahl von Bytes verwenden zu lassen, die sie benötigt, runden Sie den Wert auf eine Standardgröße auf. Durch diese Technik erhöhen Sie die Chance, dass eine neue Nachricht den Speicherplatz einer zuvor gelöschten Nachricht wieder verwenden kann.
Problem 2: Kürzlich ergab sich eine weitere Situation bezüglich der Leistung von Nachrichten-Warteschlangen. Ein Kunde stellte fest, dass das Leeren einer Nachrichten-Warteschlange mit mehr als 400.000 Nachrichten unangemessen viel Zeit in Anspruch nahm.
Sie hatten vor kurzem ein Problem damit, dass ihre Serverprozesse nicht in der Lage waren, Nachrichten in einer Nachrichtenwarteschlange zeitgerecht zu verarbeiten. Glücklicherweise waren die Anforderer am Laufen gehalten worden, so dass keine Daten verloren gingen. Als das Serverproblem behoben war, dauerte es viele Stunden, bis sie den Rückstand bei den Anfragen aufgeholt hatten und dann mit der Verarbeitung der jüngsten Transaktionen beginnen konnten. Der Kunde wollte wissen, warum dies geschah und wie es entweder verhindert oder in zukünftigen Situationen beschleunigt werden kann.
Wenn eine Nachricht in einer Nachrichtenwarteschlange gelöscht wird, wird dem vom System gepflegten _record_index ein Schlüssel hinzugefügt, wobei der Wert des Schlüssels die Nachrichtenlänge ist. Wenn die zu löschende Nachricht die gleiche Länge hat wie eine zuvor gelöschte Nachricht, wird die unbenutzte Datenposition als doppelter Eintrag auf dem Schlüssel mit dieser Nachrichtengröße am Ende der Liste der doppelten Werte gespeichert. Wenn es also Hunderttausende von gelöschten Nachrichten gibt, die alle die gleiche Größe haben (oder die Menge der Längen der gelöschten Nachrichten klein ist), ist die Liste der doppelten Schlüssel sehr lang und die Zeit zum Löschen einer einzelnen Nachricht steigt linear an.
Umgekehrt wird, wenn eine Nachricht zur Warteschlange hinzugefügt wird und ein _record_index-Schlüssel für die Nachrichtenlänge existiert, der Platz, der durch den zuletzt gelöschten Datensatz belegt ist, wieder verwendet, um die Daten für die neue Nachricht zu enthalten. Dieser Wert muss dann aus dem Schlüsselwert, der die Nachrichtenlänge enthält, gelöscht werden. Somit steigt die Zeit zum Hinzufügen einer Nachricht linear an; je mehr gelöschte Nachrichten, desto länger dauert es, eine neue Nachricht hinzuzufügen.
Die Moral von der Geschicht' ist, dass systemgepflegte Daten in Nachrichten-Warteschlangen ein Gedächtnis haben; die Warteschlangen merken sich die Positionen und Größen aller vorherigen Nachrichten. Diese Informationen bleiben auch dann erhalten, wenn die Warteschlange geleert wird. Versuchen Sie zu vermeiden, dass Ihre Nachrichten-Warteschlangen zu groß werden (zehn- oder hunderttausende von Plattenblöcken). Andernfalls werden Sie feststellen, dass die Kosten für das Hinzufügen und Löschen von Nachrichten zu einer Warteschlange mit der Zeit wachsen können.
Die Lösungen für diese beiden Situationen sind die gleichen.
Lösung A: Eine Nachrichtenwarteschlange kann abgeschnitten werden, während sie geöffnet ist. Dies kann mit der Routine s$truncate_queue erreicht werden. Es gibt jedoch 4 Bedingungen, die erfüllt sein müssen:
1: Es dürfen keine Requester vorhanden sein, die die Nachrichtenwarteschlange offen halten
2: die Nachrichtenwarteschlange muss von allen Nachrichten geleert werden
3: diese Routine muss von einem Server aufgerufen werden
4: die Warteschlange kann keine Transaktionsdatei sein
Wenn die ersten 3 Bedingungen nicht erfüllt sind, gibt s$truncate_queue e$no_truncate_queue zurück. Wenn die letzte Bedingung nicht erfüllt ist, gibt s$truncate_queue e$invalid_io_operation zurück.
Lösung B: Wenn das Anwendungsdesign mehrere Server zulässt, können Sie die vorhandene Nachrichtenwarteschlange in regelmäßigen Abständen umbenennen, eine neue Nachrichtenwarteschlange mit dem richtigen Namen erstellen, einen neuen Satz von Servern starten und die Anforderer abweisen. Wenn die Server starten, beginnen sie mit der Verarbeitung in einer neuen, aber leeren Nachrichten-Warteschlange. Wenn die Anforderer starten, fügen sie ihre Anforderungen in die neue, leere Nachrichten-Warteschlange ein. Der ursprüngliche Satz von Servern kann in Betrieb bleiben und den Rückstau an Anfragen verarbeiten, bis die Warteschlange leer ist. Dann kann der alte Satz von Servern gestoppt und die alte Nachrichten-Warteschlange gelöscht werden.
Zusätzlich kann eine Lösung für das Problem 1 darin bestehen, eine auf dem Extent basierende Meldungswarteschlange zu verwenden. Das würde es erlauben, zusätzliche Nachrichten in die Warteschlange zu stellen, da die maximale Dateigröße um einen Faktor der Extent-Größe größer wäre. Durch die Verwendung von extent-basierten Nachrichten-Warteschlangen wird die Leistung jedoch noch schlechter als normal, wenn die Nachrichten-Warteschlange jemals eine große Anzahl von Nachrichten zu einem beliebigen Zeitpunkt enthält.
Wie bereits erwähnt, wird durch die Begrenzung der Anzahl der eindeutigen Nachrichtenlängen in einer bestimmten Warteschlange die Wahrscheinlichkeit erhöht, dass eine neue Nachricht den durch eine zuvor gelöschte Nachricht freigegebenen Platz wieder verwenden kann. Dies hilft, beide in diesem Beitrag erwähnten Probleme zu lösen.