Frage

Vor kurzem hatte ich mit einem Problem beschäftigen, die ich mir vorgestellt wäre ziemlich häufig: eine Datenbanktabelle mit einer großen (Mio. +) Anzahl der Zeilen gegeben werden verarbeitet und verschiedenen Prozessoren in verschiedenen Maschinen / Threads ausgeführt wird, wie man sicher erlauben jeder Prozessor Instanz ein Stück Arbeit zu bekommen (100 Titel sagen), ohne sie zu stören?

Der Grund, warum ich auf einmal ein Stück bin immer ist aus Performance-Gründen - ich will nicht für jedes Element in die Datenbank gehen

.
War es hilfreich?

Lösung

Es gibt ein paar Ansätze - Sie jeden Prozessor ein Token zuordnen könnten, und haben eine SPROC, die dieses Token gegen die nächsten [n] verfügbare Artikel einstellt; vielleicht so etwas wie:

(Anmerkung - muss geeignete Isolation-Ebene, vielleicht serializable: SET TRANSACTION ISOLATION LEVEL SERIALIZABLE)

(herausgegeben TSQL zu beheben)

UPDATE TOP (1000) WORK
SET [Owner] = @processor, Expiry = @expiry
OUTPUT INSERTED.Id -- etc
WHERE [Owner] IS NULL

Sie würden wollen auch ein Timeout (@expiry) auf diesem, so dass, wenn ein Prozessor Sie Arbeit nicht verlieren geht. Sie würden auch eine Aufgabe müssen die Eigentümer auf die Dinge zu löschen, die Vergangenheit ihrer Expiry sind.

Andere Tipps

Sie können eine spezielle Tabelle haben Arbeit anstehen, wo die Verbraucher löschen (oder Markierung) arbeiten, wie behandelt wird, oder eine Middleware-Queuing-Lösung, wie MSMQ oder ActiveMQ verwendet werden.

Middleware kommt mit seinen eigenen Problemen so, wenn möglich, ich mit einem speziellen Tisch bleiben würde (halten Sie es so klein wie möglich, hoffentlich nur mit einer ID, so dass die Arbeiter auf den Rest der Informationen, die von sich selbst holen können der Rest der Datenbank und nicht in der Warteschlange Tisch zu lange sperren).

Sie würden diese Tabelle in regelmäßigen Abständen aufzufüllen und lassen Prozessoren greifen, was sie von oben brauchen.

Verwandte Fragen auf SQL-Tabelle Warteschlangen:

Queue mit Tabelle

Arbeiten der SQL, um eine Prioritätswarteschlange abzufragen Tabelle

Verwandte Fragen auf Warteschlangen-Middleware:

Aufbau eine hohe Leistung und automatisch backupped Warteschlange

Messaging Plattform

Sie hat nicht gesagt, welcher Datenbankserver Sie verwenden, aber es gibt ein paar Optionen.

MySQL enthält eine Erweiterung zu SQL99 der INSERT die Anzahl der Zeilen zu beschränken, die aktualisiert werden. Sie können jeder Arbeiter einen eindeutigen Token zuordnen, aktualisieren Sie eine Anzahl von Zeilen, dann dieses Arbeitnehmers Charge erhalten Abfrage zu. Marc verwendet, um die UPDATE TOP Syntax, aber nicht den Datenbankserver angeben.

Eine weitere Option ist eine Tabelle zum Verriegeln verwendet zu bezeichnen. Nicht die gleiche Tabelle mit den Daten verwenden, da Sie es nicht wollen, zum Lesen zu sperren. Ihre Sperrtabelle wahrscheinlich braucht nur eine einzige Zeile, mit der nächsten ID benötigt Arbeit. Ein Arbeiter sperrt die Tabelle, die aktuelle ID bekommt, erhöht er durch, was auch immer Ihre Chargengröße ist, aktualisiert die Tabelle, dann die Sperre freigibt. Dann kann es gehen, um die Datentabelle abfragen, und ziehen Sie die Zeilen, die es vorbehalten. Diese Option nimmt die Datentabelle eine monoton steigende ID hat, und ist nicht sehr fehlertolerant, wenn ein Arbeiter stirbt oder sonst kann keine Partie beenden.

Ganz ähnlich auf diese Frage: SQL Server-Prozess Queue Race-Bedingung

Sie führen eine Abfrage eine 100-Zeilen zu einem bestimmten processorID zuzuweisen. Wenn Sie diese Sperrhinweise verwenden, dann ist es „sicher“ in der Gleichzeitigkeit Sinn. Und es ist eine einzelne SQL-Anweisung ohne SET-Anweisungen erforderlich.

Dies wird von der anderen Frage wird:

UPDATE TOP (100)
    foo
SET
    ProcessorID = @PROCID
FROM
    OrderTable foo WITH (ROWLOCK, READPAST, UPDLOCK)
WHERE
    ProcessorID = 0    --Or whatever unassigned is
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top