Der beste Weg, um eine DB-Tabelle als eine Warteschlange (eine.k.eine batch-queue oder Warteschlange)
Habe ich ein Datenbanken-Tabelle mit ~50K Zeilen, jede Zeile steht für eine Aufgabe, die getan werden müssen. Ich habe ein Programm, dass Extrakte einen job aus der DB, macht den job und legt das Ergebnis wieder in die db. (das system läuft jetzt)
Nun möchte ich, dass es mehr als eine Bearbeitung der Aufgabe zu tun, die Arbeitsplätze aber sicher sein, dass keine Aufgabe zweimal (als performance-Bedenken nicht, dass dies andere Probleme verursachen). Denn der Zugang ist durch eine gespeicherte Prozedur, meine aktuelle ist zwar zu ersetzen, sagte gespeicherte Prozedur mit etwas, das so ähnlich aussieht, wie diese
update tbl
set owner = connection_id()
where available and owner is null limit 1;
select stuff
from tbl
where owner = connection_id();
BTW; Arbeiter Aufgaben drop könnte es eine Verbindung zwischen einen job zu bekommen und das übermitteln der Ergebnisse. Auch glaube ich nicht erwarten, dass die DB zu kommen sogar in die Nähe der Flaschenhals, es sei denn, ich mess das Teil nach oben (~5 jobs pro minute)
Gibt es irgendwelche Probleme mit diesem? Gibt es einen besseren Weg, dies zu tun?
Hinweis: die "Datenbank-IPC-anti-pattern" ist nur geringfügig apropos, weil hier
- Das werde ich nicht tun IPC (es ist kein Prozess der Generierung der Zeilen, Sie alle existieren bereits jetzt) und
- der primäre Kritikpunkt beschrieben, die für das anti-pattern ist, dass es Ergebnisse in unnötige Last auf dem DB-Prozesse zu warten, für Nachrichten (in meinem Fall, wenn es keine Meldungen gibt, kann alles Herunterfahren, da alles getan ist)
- Recht - schlecht = synchrone IPC mit der Blockierung auf ein dbms WÄHLEN Sie als gelesen. Du bist vermutlich tun dies als eine Strategie für die Einführung von Asynchronität.
- BTW, wenn Sie wollen, um den Leser(s) auf einen timer, ist es nützlich, Sie zu haben, prüfen nur selten, aber wenn Sie Arbeit finden, können Sie abtropfen lassen, die Warteschlange vor dem schlafen wieder.
- Beachte mein edit: wenn Sie keine Arbeit finden, Sie werden nie Arbeit finden. Aber wenn das nicht stimmt...
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hier ist, was ich verwendet habe, erfolgreich in der Vergangenheit:
MsgQueue Tabelle schema
Ihre message-Typen sind, was Sie erwarten würden - Nachrichten, die konform zu einem Vertrag zwischen dem Prozess(en) einfügen und die Prozess(E) Lesen, strukturierten, XML-oder anderen Wahl der Darstellung (JSON wäre praktisch, in einigen Fällen, zum Beispiel).
Dann 0-zu-n-Prozesse einsetzen, und 0-zu-n-Prozesse kann das Lesen und die Verarbeitung der Nachrichten, Jede Lesung verarbeitet normalerweise eine einzelne Nachricht geben. Mehrere Instanzen eines Prozesses geben können ausgeführt werden für den Lastenausgleich.
Den Leser zieht eine Meldung und ändert den Status auf "Ein"ktiven, während es arbeitet. Wenn es fertig ist ändert er den Status auf "C"omplete. Sie können die Nachricht löschen, oder nicht, je nachdem, ob Sie möchten, halten Sie die audit-trail. Nachrichten von Staats = 'N' gezogen sind, in MsgType/Timestamp um, so gibt es einen index für MsgType + Staat + CreateTime.
Varianten:
Staat für "E"rror.
Spalte für Reader-Prozess-code.
Zeitstempel für die Zustandsübergänge.
Diese hat eine nette, skalierbare, sichtbaren, einfachen Mechanismus für das tun eine Reihe von Dingen, wie Sie beschreiben. Wenn Sie ein grundlegendes Verständnis von Datenbanken, es ist ziemlich narrensicher und erweiterbar.
Code aus den Kommentaren:
Der beste Weg, um implementieren Sie eine Warteschlange in eine relationale Datenbank-system zu verwenden
SKIP GESPERRT
.SKIP LOCKED
ist eine Sperre übernahme-option das gilt sowohl für lese - /Aktie (FOR SHARE
) oder schreib - /EXKLUSIVER (FOR UPDATE
) sperrt und ist breit abgestützt heute:Nun, betrachten wir die folgenden
post
Tabelle, die verwendet werden, als eine job-queue:Den
status
Spalte als Enum, dass die Werte der ANHÄNGIGEN (0), GENEHMIGT (1) oder SPAM (2).Wenn wir mehrere gleichzeitige Benutzer versuchen, moderieren die
post
records, brauchen wir einen Weg, um Ihre Arbeit zu koordinieren, um zu vermeiden, dass zwei Moderatoren überprüfen Sie die gleichenpost
Zeile.So,
SKIP LOCKED
ist genau das, was wir brauchen. Wenn zwei gleichzeitige Benutzer, Alice und Bob, führen Sie die folgende SELECT-Abfragen, die Sperre der post-Datensätze, die ausschließlich während auch das hinzufügen derSKIP LOCKED
option:Können wir sehen, dass Alice können wählen Sie die ersten beiden Einträge, während Bob wählt die nächsten 2 Datensätze. Ohne
SKIP LOCKED
Bob-lock-übernahme-Anforderung blockiert, bis Alice hebt die Sperre auf die ersten 2 Einträge.Weitere details über
SKIP LOCKED
, check-out dieser Artikel.Nur als eine mögliche Technologie ändern, sollten Sie überlegen, mit MSMQ oder etwas ähnliches.
Ihrer jobs /threads könnte die Abfrage des messaging-Warteschlange, um zu sehen, wenn Sie einen neuen job zur Verfügung Stand. Denn der Akt des Lesens einer Nachricht entfernt es vom stack zu erhalten, sind Sie dafür, dass nur eine Stelle /thread würde die Nachricht bekommen.
Natürlich, dies wird vorausgesetzt, Sie arbeiten mit einer Microsoft-Plattform.
Anstatt owner = null, wenn es nicht im Besitz, sollten Sie legen Sie es auf eine gefälschte niemand Datensatz statt. Die Suche nach null nicht begrenzt, der index, Sie könnten am Ende mit einem table scan. (dies ist für oracle -, SQL-server anders sein kann)
Sie versuchen, zu implementieren, de "- Datenbank als IPC" antipattern. Schauen Sie, um zu verstehen, warum sollten Sie erwägen, überarbeitung Ihrer software richtig.