Wie kann ein Cluster eine Aufgabe nur einmal ausführen?

13

Wenn Sie eine Aufgabe hatten, die Sie nur einmal auf einem Cluster von Servern ausführen wollten, was wäre der beste Weg, um dies in regelmäßigen Abständen zu erreichen? In diesem Fall besteht die Definition von Cluster aus zwei oder mehr identischen Servern mit verteilten Sitzungen, die sich hinter einem Lastenausgleich befinden.

Anwendungsfall: Sie haben eine Aufgabe, deren Ausführung teuer ist und die nur einmal pro Stunde ausgeführt werden sollte. Dieser Job kann beispielsweise eine Reihe von Datensätzen durchlaufen und deren Status aktualisieren.

  • Im schlimmsten Fall werden Ihre Daten ungültig, wenn der Job zweimal ausgeführt wird.
  • Das beste Szenario ist, dass der Job auf allen Servern Ressourcen verbraucht.

Zusammenfassung der Anforderungen:

  1. Der Job muss weiterhin ausgeführt werden, auch wenn einer der Knoten inaktiv ist.
  2. Der Job darf nur einmal pro Zeitplan ausgeführt werden.
  3. Wenn mehrere Jobs gleichzeitig oder zu überlappenden Zeiten geplant sind, wird die Anzahl der ausgeführten Jobs gleichmäßig auf die Server verteilt.
  4. Die Maschinen müssen dieselbe Codebasis haben und über NTP synchronisiert werden.
  5. Die Konfiguration kann je nach Umgebungsvariablen zwischen Knoten und Knoten unterschiedlich sein.
  6. Der Job muss pünktlich oder innerhalb eines bestimmten Intervalls der zugewiesenen Zeit beginnen. (sagen wir zum Beispiel 5 Minuten)

Mögliche Lösungen

  • Legen Sie einen Knoten als Masterknoten fest. Dies funktioniert nicht, da der oben angegebene Wert 1 verletzt.
  • Fordern Sie den Load Balancer an, um den Job zu starten. Leider hat dies den Nebeneffekt, dass mehrere Jobs, die gleichzeitig ausgeführt werden, möglicherweise alle auf demselben Computer ausgeführt werden.

Dies müsste in Java in einem Servlet-Container ausgeführt werden. Es codiert jedoch nicht die Jobs, die ich suche.

Dies ist sicherlich ein gelöstes Problem mit der bekannt besten Lösung.


Verwandte Frage. /programming/5949038/schedule-job-executes-twice-on-cluster

Dies ist kein Duplikat, da die Lösung gemäß den oben angegebenen fünf Anforderungen nicht ausreicht. Die am besten bewertete Lösung weist ein Rassenproblem auf und die zweite Lösung verstößt gegen Anforderung 3

Wir s
quelle

Antworten:

16

Haben Sie eine gemeinsame Datenbank? Ich habe dies in der Vergangenheit mit einer Datenbank als Schiedsrichter gemacht.

Grundsätzlich wird jeder "Job" in der Datenbank als Zeile dargestellt. Sie planen einen Job, indem Sie der Datenbank eine Zeile mit der gewünschten Ausführungszeit hinzufügen. Dann führt jeder Server Folgendes aus:

SELECT TOP 1 *
FROM jobs
WHERE state = 'NotRun'
ORDER BY run_time ASC

Auf diese Weise wählen sie alle den Job aus, der als nächstes ausgeführt werden soll . Sie schlafen alle, damit sie aufwachen, wenn der Job eigentlich laufen soll. Dann machen sie alle Folgendes:

UPDATE jobs
SET state = 'Running'
WHERE job_id = :id
  AND state = 'NotRun'

Wo :idist die ID des Jobs, den Sie im obigen Schritt erhalten haben? Da das Update atomar ist, aktualisiert nur einer der Server die Zeile. Sie können anhand des Statuscodes "Anzahl der Zeilenaktualisierungen" der Datenbank feststellen, ob Sie der Server waren, der die Zeile tatsächlich aktualisiert hat, und daher, ob Sie der Server sind das wird den Job ausführen.

Wenn Sie nicht "gewonnen" haben und den Job nicht ausführen, kehren Sie sofort zu Schritt 1 zurück. Wenn Sie "gewonnen" haben, planen Sie die Ausführung des Jobs in einem anderen Thread und warten Sie einige Sekunden, bevor Sie zu Schritt 1 zurückkehren. Auf diese Weise können Server, die den Job dieses Mal nicht erhalten haben, mit größerer Wahrscheinlichkeit einen Job abholen das soll sofort laufen.

Dean Harding
quelle
1
Welches Isloationslevel benutzt du hier? Festgeschrieben oder serialisiert lesen?
Maverick Riz
2

Mehrere App-Server verfügen über eine Funktion für "clusterweite Singleton-Dienste".

Beispielsweise verfügt Weblogic über eine Singleton-Dienstfunktion, die über die Webadministrationskonsole konfiguriert wird.

Sie müssen eine Klasse schreiben, die weblogic.cluster.singleton.SingletonService implementiert, und sie verwenden, um den Dienst in der Administratorkonsole zu deklarieren. Der Cluster sorgt dafür, dass die Klasse instanziiert wird und Sie benachrichtigt werden, wenn der Dienst gestartet oder gestoppt wird. Die SingletonService-Schnittstelle verfügt über eine activate () - und eine disable () -Methode.

Weblogic-Aufrufe activate (), wenn der Dienst zum ersten Mal auf einem der Knoten des Clusters aufgerufen wird. Wenn der ausgewählte Knoten ausfällt, "verschiebt" der Admin-Server den Dienst auf einen anderen Server und ruft dort activate () auf.

http://docs.oracle.com/cd/E12839_01/apirefs.1111/e13952/taskhelp/clusters/ConfigureSingletonService.html

Alfred Faltiska
quelle