Re: Job Scheduler (was: Re: File-Locking in Shellscripten auf NFS)

Autor: Raphael Eiselstein <rabe_at_uugrn.org>
Datum: Sat, 18 Dec 2010 00:16:00 +0100
On Fri, Dec 17, 2010 at 08:49:55PM +0100, Markus Hochholdinger wrote:
> Hi,
> 
> Am 17.12.2010 um 18:39 Uhr schrieb Thomas Stiefel <Tom_at_vtux.de>:
> > ich bin neu hier und wollte auch mal meinen Senf dazu geben ;-)
> 
> aber immer doch :-)
> 
> 
> > On Thu, Dec 09, 2010 at 10:23:03AM +0100, Alexander Holler wrote:
> > > > Gibt es eine *einfache* Lösung basierend auf NFS?
> > >  Ich würde das eigentliche Problem beseitigen. D.h. die offensichtlich
> > >  zentrale Aufgabe (sonst wäre Mehrfachausführung ja wohl kein
> > >  Problem), zentral erledigen lassen, oder die Problemstellung so
> > >  angehen, daß Mehrfachausführung kein Problem ist.
> > Ich sehe das genauso. Wenn es schon einen zentralen Server gibt, der für
> 
> Ist die Frage ob es "EIN" zentraler NFS-Server ist oder ob einfach nur der 
> Dienst nfs "hochverfügbar" ist!?

Ich gehe von einem hochverfügbaren Dienst mit NFS aus, d.h. ein
NFS-Serverpaar, das mit zB Heartbeat und drbd hochverfügbar NFS
anbietet, nur um mal eine Technologie zu nennen.
 
> Ist halt die Frage ob der nfs-Server dafür ausgerüstet ist diese Aufgabe zu 
> erledigen? Evtl. gab es ja einen Grund dieses Script auf andere Server 
> auszulagern?

Man kann auch NFS aus Kisten heraus anbieten, die kein (extern
erreichbares) unixoides Betriebssystem im innern haben. 
 
> > Mi rsync und SSH-Keys ist sowas total easy einzurichten und das benutze
> > ich eigentlich schon seit Jahren immer wieder in dieser Art.
> Ich denke das würde Raphael hinbekommen, wenn er das benötigt ;-)

Es gibt im konkreten Setup mehrere hochverfügbare NFS-Quellen, die
allesamt auf mehreren unabhängigen Servern gemountet sind. Diese Server
bieten irgendwelche Dienste an, hier zB im Rahmen eines Datawarehouses
den Import und Export von Daten (in Dateiform) durchführen. 

Da Daten (Dateien) kontinuierlich beschafft und verarbeitet werden müssen, 
sollte unter keinen Umständen die Beschaffung (Import) von Daten 
unterbrochen werden. Um das zu gewährleisten betreibe ich mehrere Rechner, 
die bestimmte Copy-Jobs ausführen. Ich nehme dafür mehrere Server nicht, 
weil es zuviel Last wäre für nur einen, sondern weil ich damit eine 
Ausfallsicherheit bekomme und zusätzlich im Normalbetrieb keine Bottlenecks 
habe. 

Ausserdem laufen auf diesen "Beschaffungsservern" nicht nur Copy-Jobs, die 
aktiv Daten abholen sondern auch plain rsync-daemons, die Daten annehmen, 
also per "Push" von extern bekommen (oder zur Abholung anbieten). Da die 
Quellen sich schlecht syncronisieren lassen und es teilweise zu sehr 
vielen parallelen Transfers kommt, werden eingehende rsync-Verbindungen 
über einen LoadBalancer (IPVS, direct routing) auf mehrere rsync-daemons 
verteilt, die alle die gleiche rsyncd.conf haben und zudem jeweils alle
NFS-Quellen und -Senken gemountet haben. 

Datenexporte laufen ebenfalls als Copy-Job (per rsync, cron) oder werden
per rsyncd, httpd und sftp  für bestimmte Mandanten zur Abholung
angeboten, auch hier per IPVS-Loadbalancer, auf dem ein ldirectord
regelmäßig prüft, dass die dahinter liegenden Dienste auch wirklich
erreichbar sind und Zugriffe nur an "lebende Dienste" durchleitet.

Es gibt in diesem Spiel also keine Funktion und keinen Dienst, der 
ausschließlich auf nur einem Server verfügbar ist. 

Da es wie erwähnt eben diese CopyJobs gibt, die per cron aufgerufen
werden, ist es nicht weiter schlimm, wenn der gleiche Job auf 2 Servern
gleichzeitig ausgeführt wird, das erzeugt schlimmstenfalls einfach
sinnlosen Traffic oder I/O auf den Storages hinter den NFS-Servern.

Ich suche also nach einer Möglichkeit in diesem vorne und hinten und in
der Mitte redundant ausgelegten System wiederkehrende Jobs verteilt auf
mehreren Systemen auszuführen und dabei sicherstellen, dass identische
Jobs sowohl pro System aber auch im gesamten Verbund nie parallel
ausgeführt werden. 

PID-Files oder Lock-Files auf der gemeinsamen NFS-Ressource könnten da 
helfen, aber wenn ein CopyJob einmal abstürzt, hinterlässt er dann 
PID-Files mit nicht mehr gültigen PIDs oder Lockfiles, die ihren Lock 
nicht verlieren. Also suche ich nach einer Möglichkeit zweifelsfrei 
und mit geringem technischen Aufwand herauszufinden, ob PID/Lockfiles 
noch "gültig" sind.

Oder, weil cron hier eher das Problem darstellt: Einen verteilten
Job-Scheduler, der ohne zentrale Instanz auskommt und trotzdem dafür
sorgt, dass konkrete Jobs nie mehr als einmal parallel ausgeführt werden
*und* eine Fehlerbehandlung ermöglicht, wenn ein Job einmal unsauber
abgebrochen ist, etwa weil Quelle oder Ziel plötzlich nicht mehr
verfügbar sind (Timeout).

Ich könnte mir vorstellen, dass ich anstelle von cron einen Dienst
verwende (nehmen wir einfach mal sshd, aber das ist nur ein Beispiel),
der von aussen angesprochen wird. Das Ganze ist verteilt auf sagen wir 3
Systeme. Für jeden "Job" gibt es beispielsweise einen eigenen TCP-Port,
also zB 4711, 4712, 4713, 4714, ... auf allen 3 Systemen jeweils alle
oder eine beliebige Teilmenge der "Ports".

Durch einen authentifizierten Connect auf diesen Port wird der damit
assoziierte Job ausgeführt. Das ganze wird dann über einen Loadbalancer
angesprochen, der einen eingehenden Request zB für 4714/tcp auf
ServerB:4714 durchreicht, während er zufällig einen parallel eingehenden
Request auf :4712 auf ServerC:4712 durchreicht.

Jetzt bräuchte ich "nur" noch einen zentralen Dienst, der via LoadBalancer
für die verschiedenen konfigurierten Jobs die jeweiligen Zugriffe
startet und somit auf einem der Server{A,B,C} den entsprechenden Job
dann triggert.

Aber hier ist genau wieder der Knackpunkt: Ich brauche hierfür eine
singuläre Instanz, die selbst wieder hochverfügbar aufgebaut sein muss.
Aber genau das erwarte ich von einem Jobscheduler, dass er konfigurierte
Jobs sicher zur Ausführung bringt (und überwacht), auch wenn das Blech
auf dem der Scheduler installiert ist mal wackelt.

Ein Scheduler bringt leider eine gewisse Komplexität mit, die ich durch
"kooperatives Multitasking" der verteilten Cronjobs gerne durch
"intelligente Lockfiles" an zentraler Stelle gelöst hätte, also 
Lockfiles, die von selbst verschwinden, wenn der assoziierte Prozess 
"weg" ist (egal ob regulär beendet, durch kill -9 abgeschossen oder 
durch spontanen Stromausfall).

Alternatives Konzept: ein verteilter cron-daemon, der sich per multicast 
über mehrere Systeme hinweg synct und "abstimmt", sodass auf jedem System
immer bekannt ist, welche Jobs derzeit aktiv laufen und entsprechend
nicht neu ausgeführt werden sollen/dürfen. Das wäre ausfallsicher und
kommt ohne zentrale Instanz ("Master") aus. 

Statt einer Alternative für cron könnte hier auch ein wrapper verwendet 
werden, der per multicast das Äquivalent eines PID/Lockfiles pro Job 
implementiert, sodass ein cronjob ganz traditionell über /etc/crontab 
oder /etc/cron.d/ so aussehen könnte:

-----------------------------
10 8-18 * * * jobuser runjob --jobname importABC --parallel=2 /opt/jobs/bin/importABC.sh
-----------------------------

... wobei "importABC" der symbolische Name für den Job ist, den es im
Netz als "läuft derzeit bei mir" zu markieren gilt bzw. geprüft werden
kann, ob unter diesem Namen die maximale Anzahl der parallelen Jobs
(einer Klasse) bereits erreicht ist, zum Beispiel wenn man eine 2-aus-3
Ausfallsicherheit haben möchte. 

Dieser "runjob"-Wrapper würde also dafür sorgen, dass beliebige Jobs
nicht kollidieren, obwohl sie potenziell zeitgleich auf verschiedenen
Systemen gestartet werden könnten.

Die Idee eines einfachen runjob-Wrappers, der sich per multicast mit
seinen (allen) Nachbarn synct, noch mit die beste weil einfachste
Lösung ("KISS Prinzip"). Das wäre dann auch nicht beschränkt auf cronjobs, 
sondern könnte auch aus anderen Konstrukten her in einer Form verwendet 
werden, dass bestimmte Prozesse sich über Systemgrenzen hinweg "abstimmen".

Einzig: Ich kenne so ein Tool bisher nicht und kann mir sowas auch nicht
mal eben selbst programmieren. Ideen anyone?

Gruß
Raphael

-- 
Raphael Eiselstein <rabe@uugrn.org>               http://rabe.uugrn.org/
xmpp:freibyterægmx.de  | https://www.xing.com/profile/Raphael_Eiselstein   
GnuPG:                E7B2 1D66 3AF2 EDC7 9828  6D7A 9CDA 3E7B 10CA 9F2D
.........|.........|.........|.........|.........|.........|.........|..


-- 
UUGRN e.V. http://www.uugrn.org/
http://mailman.uugrn.org/mailman/listinfo/uugrn
Wiki: https://wiki.uugrn.org/UUGRN:Mailingliste
Archiv: http://lists.uugrn.org/

Empfangen am 18.12.2010

Dieses Archiv wurde generiert von hypermail 2.2.0 : 18.12.2010 CET