Celery: Feature: Beat sollte gleichzeitige Aufrufe vermeiden

Erstellt am 17. Nov. 2010  ·  48Kommentare  ·  Quelle: celery/celery

Wenn der Benutzer dafür sorgen muss, dass in seinem Cluster nur eine Instanz von celerybeat vorhanden ist, entsteht ein erheblicher Implementierungsaufwand (entweder die Schaffung eines einzelnen Fehlerpunkts oder die Ermutigung der Benutzer, ihren eigenen verteilten Mutex zu rollen).

celerybeat sollte entweder einen Mechanismus bereitstellen, um unbeabsichtigte Parallelität zu verhindern, oder die Dokumentation sollte einen Best-Practice-Ansatz vorschlagen.

Celerybeat

Hilfreichster Kommentar

@ankur11 single-beat stellt sicher, dass nur eine Instanz von Selleriebeat ausgeführt wird, synchronisiert jedoch nicht den Zeitplanstatus zwischen den Instanzen.

Wenn ich den Standard-Scheduler mit einer periodischen Aufgabe verwendet habe, die alle 15 Minuten ausgeführt werden soll, und 14 Minuten nach der letzten Ausführung der Aufgabe ein Failover mit Single-Beat hätte, würde die Aufgabe erst 15 Minuten nach dem neuen Sellerie-Beat ausgeführt Instanz gestartet, was zu einer 29-minütigen Lücke führte.

Um den Zeitplanstatus zwischen Instanzen zu teilen, musste ich einen alternativen Scheduler verwenden . django-celery-beat ist die in den Celery-Dokumenten erwähnte Alternative, aber ich bevorzuge Redis als Back-End verwendet habe .

Redbeat enthält sowohl den von Redis unterstützten freigegebenen Zeitplanstatus als auch das Sperren, um sicherzustellen, dass nur eine Instanz Aufgaben plant. Ich brauchte also keinen Single-Beat oder BeatCop, als ich damit begann.

In unserer Implementierung wird celery beat auf allen Instanzen von Supervisord gestartet, mit Redbeat als Scheduler (zB exec celery beat --scheduler=redbeat.RedBeatScheduler --app=myproject.celery:app ). Leider kann ich keinen arbeitsbezogenen Code freigeben, beantworte aber gerne weitere Fragen zur Implementierung im Allgemeinen.

Alle 48 Kommentare

Dies könnte mit kombu.pidbox gelöst werden, so erkennt celeryd dass bereits ein Knoten mit demselben Namen läuft. Da celerybeat zentralisiert ist, könnte es einen festen Knotennamen verwenden.

Als Nebeneffekt werden wir celerybeat mit Fernbedienungsbefehlen steuern können (es könnte beispielsweise einen Befehl geben, um den Zeitplan neu zu laden oder zu sehen, welche Aufgaben in naher Zukunft fällig sind). Das ist ein ziemlich toller Nebeneffekt, wenn Sie mich fragen.

Benötigt mehr Planung, da es einen Anwendungsfall für die Ausführung mehrerer Instanzen im selben Cluster gibt. ZB zum "Sharding" des Zeitplans in mehrere Teile. Für jede Instanz muss mindestens die Möglichkeit bestehen, einen Knotennamen auszuwählen. Verschiebung auf 2.3.0.

Wir hatten ein Problem, bei dem die Box, auf der celerybeat offline ging, ohne dass ein guter Fallback eingerichtet wurde, um eine neue celerybeat Instanz zu starten, die ihren Platz einnimmt. Was ist die empfohlene HA-Methode, um celerybeat auszuführen?

Würde der kombu.pidbox Ansatz es uns ermöglichen, mehrere Instanzen von celerybeat auszuführen, die nur schlafen würden, wenn festgestellt wurde, dass bereits eine Instanz mit dem festen Knotennamen ausgeführt wurde, und abzufragen, um sich selbst zum aktiven hochzustufen? Instanz geht aus?

Das Ausführen mehrerer aktiver Instanzen klingt interessant – welche anderen Vorteile könnte es zusätzlich zur gemeinsamen Nutzung des Zeitplans geben?

+1

+1

Dies ist etwas, das für große Bereitstellungen ein echtes Problem darstellt, bei denen die Belastbarkeit der Planung wichtig ist.

+9999 ;)
Stimmt etwas mit der Verwendung der Lösung kombu.pidbox ? Auch ohne Sharding und ausgefallene Features wäre das toll und sehr praktisch. Im Moment muss ich celerybeat manuell auf einem anderen Host starten.

Pidbox könnte verwendet werden, aber das Problem ist, dass Beat kein Verbraucher ist. Um auf Broadcast-Nachrichten wie "Beliebige Beat-Instanzen hier?" zu antworten. es müsste ständig auf Nachrichten in seiner Broadcast-Warteschlange warten, und das kann es derzeit nicht, weil es damit beschäftigt ist, Nachrichten zu planen.

Technisch könnte es ein zweiter Thread sein, aber das kann die Leistung beeinträchtigen und ist allein für diese Funktion viel Overhead.

Eine zweite Lösung könnte die Verwendung eines Schlosses sein, jedoch mit dem Nachteil, dass es gelöst werden muss. Dh wenn der Beat-Prozess beendet wird, würde die veraltete Sperre einen manuellen Eingriff erfordern, um eine neue Instanz zu starten.

Es könnte auch ein 2-Sekunden-Timeout für die Sperre haben und die Sperre jede Sekunde aktualisieren. Das bedeutet dann, dass eine neue Instanz 2 Sekunden warten müsste, wenn die Sperre gehalten wird.

Eine Sperre in amqp könnte durch das Deklarieren einer Warteschlange erzeugt werden, zB `queue_declare('celerybeat.lock', arguments={'x-expires': 2000}``

+1

Das würde ich gerne sehen

+1

+1

+1 auch

+1

Hat jemand tatsächlich die kombu.pidbox Lösung oder einen anderen Mechanismus implementiert, der dieses Problem löst? Wenn ja, teilen Sie es bitte. Es gibt immer noch viele Leute, die sich fragen, was die beste Vorgehensweise ist.

Hat sich jemand deswegen ganz vom Sellerie abgewendet? Das würde mich auch interessieren.

BEARBEITEN:

Ich fand dieses Wesentliche (https://gist.github.com/winhamwr/2719812) durch eine Google-Diskussion (https://www.google.co.in/search?q=celerybeat+lock&aq=f&oq=celerybeat+lock&aqs= chrome.0.57j62l3.2125j0&sourceid=chrome&ie=UTF-8).

Ich frage mich auch, ob jemand gerade eine gemeinsame Pidfile für celerybeat direkt verwendet hat, vielleicht mit einem EBS auf AWS oder vielleicht in einem S3-Bucket… celerybeat --pidfile=/path/to/shared/volume .

Mir ist aufgefallen, dass der aktuelle Master (3.1 dev) einen Klatschschritt für den Verbraucher hat. Wäre es möglich, die Klatschwarteschlange und die Wahl des Leiters zu nutzen, um die eingebetteten Beat-Prozesse zu koordinieren? Das heißt, jeder Arbeiter würde den eingebetteten Beat-Prozess ausführen, aber nur der Leiter würde die periodische Aufgabe in die Warteschlange stellen. Dies würde wahrscheinlich einen gemeinsam genutzten Zeitplanspeicher annehmen.

@mlavin Das könnte funktionieren, aber nur für

Das Problem bei der pidbox-Lösung besteht darin, dass das celerybeat-Programm dann neu geschrieben werden muss, um Async I/O zu verwenden.
Es kann derzeit nicht sowohl Aufgaben verbrauchen als auch produzieren, da der Scheduler blockiert.

In den meisten Fällen ist dies überhaupt keine erforderliche Funktion, da die meisten Produktionsbereitstellungen einen dedizierten Host für den Beat-Prozess haben und dann die Verwendung von --pidfile ausreicht, um sicherzustellen, dass Sie nicht mehrere Instanzen starten.

Ich habe festgestellt, dass oft Leute, die von diesem Problem betroffen sind, diejenigen sind, die die Option -B in einer Dämonisierung verwenden
Skript und dupliziert dann dieses Setup auf einen anderen Host.

Also ich verstehe, dass es nervig ist, aber ich denke nicht, dass es kritisch ist. Wenn jemand wirklich eine Lösung möchte, kann er sie beitragen oder mich beauftragen / spenden, um sie umzusetzen.

Man kann uWSGI verwenden, um einen Single-Beat-Prozess mit Fallback auf andere Knoten zu haben.

+1 starten wir identische Amazon EC2-Instances und es wäre schön, regelmäßige Aufgaben zu haben, die nur in einem Knoten ausgeführt werden. In der Zwischenzeit werde ich versuchen, uWSGI zu verwenden, danke für den Vorschlag.

+1

+1

Ich habe bei der Arbeit argumentiert, Celerybeat für die Planung zu verwenden, aber kein einsatzbereites HA zu haben, macht es sehr schwierig. Tatsächlich sieht es so aus, als würden wir es deswegen ganz fallen lassen. Einfach gesagt, macht die Ausführung von nur 1 Celerybeat-Instanz dies zu einem Single Point of Failure und ist daher für uns nicht produktionsbereit.

@junaidch Ich denke nicht, dass du deswegen Sellerie fallen lassen solltest. Sie können den Scheduler immer einfach auf jedem Server ausführen und für periodische Aufgaben eine Art Sperrmechanismus verwenden, um sicherzustellen, dass sie sich nicht überschneiden und auch nicht zu oft ausgeführt werden. Darüber hinaus können Sie den Scheduler unterklassen und dort ebenfalls eine Sperre durchführen oder die Sperre auf Taskebene überspringen und stattdessen alles im Scheduler erledigen.

Es wäre schöner, einige integrierte Funktionen in Sellerie zu haben, da dies eine Art Problemumgehung ist, aber dennoch in der Produktion problemlos verwendet werden kann.

Danke @23doors.

Meine Aufgaben behalten bereits eine Redis-Sperre bei, um zu verhindern, dass eine andere Instanz der Aufgabe ausgeführt wird. Wenn ich 2 Beats auf 2 verschiedenen Maschinen laufen lasse und meine Aufgaben für 5-Minuten-Intervalle geplant sind, denke ich, dass das funktioniert, obwohl beide Beats Aufgaben in die Warteschlange schieben. Es wird nur schwieriger, Argumente für die Einführung zu finden, wenn Sie eine Problemumgehung für Ihre Kernfunktionalität implementieren müssen.

Ich werde die Unterklassifizierungsempfehlung untersuchen. Das könnte ein saubererer Ansatz sein.

Danke für die Vorschläge!

Bei Lulu haben wir dies gelöst, indem wir einen einfachen Cluster-Singleton-Manager (namens BeatCop) geschrieben haben. Es verwendet eine auslaufende Redis-Sperre, um sicherzustellen, dass nur ein Celerybeat in einem Autoscaling-Pool von Celery-Workern ausgeführt wird. Wenn diesem Celerybeat etwas passiert (z. B. die Instanz wird skaliert oder stirbt oder Celerybeat stürzt ab), erzeugt ein anderer Knoten automatisch einen neuen Celerybeat. Wir haben BeatCop als Open Source bereitgestellt .

@ingmar, wir haben dies https://github.com/ybrs/single-beat aus den gleichen Gründen geschrieben, als ich das letzte Mal nachgesehen habe, habe ich deinen Kommentar nicht gesehen. wir auch als Opensource veröffentlicht, könnte für einige andere nützlich sein. macht mehr oder weniger dasselbe.

Soweit ich sehen kann, die Hauptunterschiede mit beatcop - wir verwenden pyuv - also ist beatcop portierbarer, denke ich, weniger Abhängigkeiten -, leiten Sie die Kinder stderr und stdout als Eltern um und beenden Sie, wenn das Kind mit dem gleichen Code stirbt, konfigurieren Sie es mit env-Variablen. Daher ist es etwas einfacher, dem Supervisor hinzuzufügen.

hoffe, es könnte für jemand anderen nützlich sein.

+1

+1

Ich erwäge die Verwendung von Consul-Schlüsselwerten als Lock-Controller. Hat jemand diesen Ansatz ausprobiert? Während also eine Instanz arbeitet, würden die anderen "schlafen", bis die Sperre nicht aktualisiert wird, dann würde der Wahlmechanismus des Konsuls entscheiden, wer den zeitgestempelten Schlüsselwert aktualisieren würde. Wer auch immer das Schloss aktualisiert, ist derjenige, der funktioniert.

@ingmar Danke dafür! Ich werde das mit meinem Arbeitercluster versuchen.

+10, da die aktuelle Implementierung einen Single Point of Failure bedeutet, der davon abweicht, warum wir überhaupt eine verteilte Warteschlange verwenden

+1

+1

Sieht so aus, als würde dies in v5.0.0 sein https://github.com/celery/celery/milestones/v5.0.0

+1

Der Abschluss wird, wie bei den derzeitigen Ressourcen, 10 Jahre dauern.

Entschuldigung, aber dies ist ein ernstes Problem für eine sogenannte "verteilte" Warteschlange. So lange die Implementierung auch dauern wird, sollte es irgendwann behoben werden. Ein absolut gültiges Problem zu schließen, weil Sie _jetzt_ nicht über die Ressourcen verfügen, scheint nicht richtig zu sein. Könnten Sie es vielleicht noch einmal öffnen und ein Etikett anbringen, das anzeigt, dass es im Moment niedrige Priorität hat?

Ich weiß, dass mein Grund für die Schließung absurd abrupt war, daher kann ich als Benutzer von Software Ihre Meinung verstehen, aber technisch gesehen ist Beat eher eine Zusatzfunktion. Es ist vollständig vom Rest von Celery entkoppelt und wurde absichtlich so konzipiert, dass es nicht verteilt wird, um die Implementierung einfach zu halten. Es begann als eine nette Möglichkeit, Cronjobs von Python als Bonus für Benutzer zu definieren, die bereits Celery verwenden, dann verwendeten immer mehr Leute Celery als Cron-Ersatz.

Das Thema ist seit SECHS Jahren offen, und obwohl es oft nachgefragt wird und unzählige Unternehmen darauf angewiesen sind, hat noch nie jemand angeboten, für eine Implementierung zu bezahlen.

Es war tatsächlich eines der Themen, von denen ich dachte, dass es für Unternehmen interessant wäre, sie zu sponsern. Zugegeben, es ist nicht üblich, dass Unternehmen anbieten, für Funktionen, Fehlerbehebungen oder sogar für die Hilfe bei der Lösung eines Produktionsproblems zu bezahlen. Ich kann sie wahrscheinlich an einer Hand abzählen (du bist großartig), also weiß ich jetzt, wie naiv diese Idee war :)

Ich habe heute auch ein Duplikat dieser Ausgabe geschlossen, siehe #1495. Es gab Pull-Requests, die versuchten, das Problem zu lösen, und einige sind vielversprechend, aber angesichts des Engagements, das erforderlich ist, um zu beweisen, dass eine bestimmte Implementierung funktioniert, hatte ich immer noch nicht die Zeit, sie richtig zu überprüfen. Vielleicht bringt das jemanden zum Handeln, auch wenn ich es besser finde, als eine Feature-Anfrage sechs Jahre lang offen zu halten, wenn niemand daran arbeitet. Das ist auch eine Art Bärendienst für Benutzer, die dies behoben sehen möchten.

@fragen Fair genug. Es ist wahr, dass verteiltes Cron ein großes kompliziertes Problem ist, wie Sie im anderen Thread sagen. Und es klingt wie etwas, das außerhalb von Celery leben sollte.

Vielen Dank, dass Sie sich die Zeit genommen haben, Ihre Argumentation ausführlich zu erläutern.

@ask Ich habe mich gefragt, ob dieses Problem umgangen werden könnte, indem die Datei celerybeat-schedule (verwendet von celery.beat.PersistentScheduler ) in einem NFS-Volume gefunden wird, das von allen Knoten im Cluster gemeinsam genutzt wird?

Die Klasse PersistentScheduler verwendet shelve als Datenbankmodul, daher sollten gleichzeitige Schreibvorgänge in die Datei celerybeat-schedule durch das Design verhindert werden. Dies ist ein Auszug aus der shelve Dokumentation :

Das Shelve-Modul unterstützt keinen gleichzeitigen Lese-/Schreibzugriff auf Shelfed-Objekte. (Mehrere gleichzeitige Lesezugriffe sind sicher.) Wenn ein Programm ein Regal zum Schreiben geöffnet hat, sollte es kein anderes Programm zum Lesen oder Schreiben geöffnet haben.

Angenommen, wir beginnen Sellerie-Beat wie folgt:

celery -A project-name beat -l info -s /nfs_shared_volume/celerybeat-schedule

wobei /nfs_shared_volume das freigegebene Volume ist (z. B. verwaltet von AWS Elastic File System), können wir erwarten, dass die Zeitpläne nicht durcheinander gebracht werden, selbst wenn auf jedem Knoten im Cluster ein Sellerie-Beat-Prozess ausgeführt wird?

@mikeschaekermann Wenn ich die Dokumente richtig lese, shelve keine Anstrengungen, um gleichzeitige Schreibzugriffe zu verhindern. Es sagt dir nur, dass du es nicht zulassen sollst. In dem von Ihnen zitierten Abschnitt heißt es weiter: "Unix-Dateisperrung kann verwendet werden, um dieses Problem zu lösen, aber dies unterscheidet sich von Unix-Version und erfordert Kenntnisse über die verwendete Datenbankimplementierung."

@ze-phyr-us Ich denke, du hast Recht, und ich habe die shelve Dokumente falsch interpretiert. Trotzdem frage ich mich, ob das Problem gelöst werden würde, wenn das Scheduler Backend atomare Operationen im Zeitplan sicherstellt? @ask unterstützt das Paket django-celery-beat Atomicity, um das Problem zu lösen? Ich habe gesehen, dass es Transaktionen verwendet, um einige der Updates durchzuführen.

Für alle anderen, die hier auf der Suche nach einem verteilten / automatisch skalierenden Sellerie-Beat landen und Redis gerne als Backend verwenden; Ich habe sowohl BeatCop als auch Single-Beat ausprobiert, die oben erwähnt wurden, aber letztendlich RedBeat ausgewählt .

Hallo @ddevlin
Ich habe ähnliche Probleme. Welche Probleme hatten Sie bei der Verwendung von Single-Beat? Wenn es nicht zu viel ist, könnten Sie bitte das Implementierungsbeispiel teilen, wie Sie Redbeat für mehrere Server konfiguriert haben.

@ankur11 single-beat stellt sicher, dass nur eine Instanz von Selleriebeat ausgeführt wird, synchronisiert jedoch nicht den Zeitplanstatus zwischen den Instanzen.

Wenn ich den Standard-Scheduler mit einer periodischen Aufgabe verwendet habe, die alle 15 Minuten ausgeführt werden soll, und 14 Minuten nach der letzten Ausführung der Aufgabe ein Failover mit Single-Beat hätte, würde die Aufgabe erst 15 Minuten nach dem neuen Sellerie-Beat ausgeführt Instanz gestartet, was zu einer 29-minütigen Lücke führte.

Um den Zeitplanstatus zwischen Instanzen zu teilen, musste ich einen alternativen Scheduler verwenden . django-celery-beat ist die in den Celery-Dokumenten erwähnte Alternative, aber ich bevorzuge Redis als Back-End verwendet habe .

Redbeat enthält sowohl den von Redis unterstützten freigegebenen Zeitplanstatus als auch das Sperren, um sicherzustellen, dass nur eine Instanz Aufgaben plant. Ich brauchte also keinen Single-Beat oder BeatCop, als ich damit begann.

In unserer Implementierung wird celery beat auf allen Instanzen von Supervisord gestartet, mit Redbeat als Scheduler (zB exec celery beat --scheduler=redbeat.RedBeatScheduler --app=myproject.celery:app ). Leider kann ich keinen arbeitsbezogenen Code freigeben, beantworte aber gerne weitere Fragen zur Implementierung im Allgemeinen.

@mikeschaekermann du könntest versuchen, deinen Sellerie-Beat mit /use/bin/flock zu verpacken, um den Zugang zu sperren ...

flock /nfs/lock.file celery beat ...

Vorausgesetzt, Sie vertrauen Ihrer NFS-Sperrimplementierung :)

Dies würde sicherstellen, dass nur einer tatsächlich läuft und die anderen blockieren, bis der Spind stirbt.

@mikeschaekermann du könntest versuchen, deinen Sellerie-Beat mit /use/bin/flock zu verpacken, um den Zugang zu sperren ...

Herde /nfs/lock.file Sellerie schlagen ...

Vorausgesetzt, Sie vertrauen Ihrer NFS-Sperrimplementierung :)

Dies würde sicherstellen, dass nur einer tatsächlich läuft und die anderen blockieren, bis der Spind stirbt.

Ich habe diese Methode ausprobiert. Wenn der Client, der die NFS-Sperre hält, die Verbindung zum NFS-Server verliert, kann die Sperre leider vom NFS-Server aufgehoben und an einen anderen Client weitergegeben werden. Wenn der ursprüngliche Sperreninhaber die Konnektivität wiedererlangt, erkennt flock nicht, dass die Sperre aufgehoben wurde, sodass jetzt zwei Knoten glauben, dass sie der „Führer“ sind.

Am Ende habe ich eine Advisory-Sperre in Postgres verwendet. Ich habe einen Django-Verwaltungsbefehl erstellt, der das Modul django_pglocks verwendet und Selleriebeat in einem Unterprozess ausführt.

Am Ende habe ich eine Advisory-Sperre in Postgres verwendet. Ich habe einen Django-Verwaltungsbefehl erstellt, der das Modul django_pglocks verwendet und Selleriebeat in einem Unterprozess ausführt.

Dies scheint anfällig für die gleichen Probleme zu sein, die ich bei der Verwendung von NFS gesehen habe. Was passiert, wenn der gesperrte Client die Verbindung zum Postgres-Server verliert oder der Postgres-Server neu gestartet wird?

@swt2c Argh, du hast natürlich recht! Es muss eine Art Lebenshaltung geben.

Ich mache gerade:

def _pre_exec():
    prctl.set_pdeathsig(signal.SIGTERM)

with advisory_lock(LOCK_ID) as acquired:
            assert acquired
            logging.info("Lock acquired: %s", acquired)
            p = subprocess.Popen(
                celery,
                shell=False,
                close_fds=True,
                preexec_fn=_pre_exec,
            )
            sys.exit(p.wait())

advisor_lock unterstützt Rekursion, aber ich weiß nicht, ob es tatsächlich die DB überprüft:

In [8]:  with advisory_lock('foo') as acquired:
   ...:     print acquired
   ...:     while True:
   ...:        with advisory_lock('foo') as acquired:
   ...:           print acquired
   ...:        time.sleep(1)
   ...:       

# Yes, it does:

True
True
True
<shutdown the instsance>
InterfaceError: cursor already closed

Also ... ich könnte es ändern, um die Sperre / Abfrage immer wieder unterzubeziehen und den Beat zu töten, wenn es fehlschlägt. Garantiert keinen gegenseitigen Ausschluss, aber für meine Zwecke könnte es ausreichen.

Für meinen Fall sind gleichzeitige Beats ein verschwenderisches Ärgernis, aber kein Integritätsproblem. Wenn dies der Fall wäre, könnte ich die Aufgabe auch in eine Advisory-Sperre einschließen, die, wenn die Datenbank ausfällt, die Aufgabe trotzdem fehlschlägt.

Ich habe auch Beat speichern den Zeitplan in der DB, aber ich habe nicht getestet, was Beat macht, wenn die DB sinkt.

@ddevlin Ich habe mich über Ihren Kommentar gefreut, da dies die Lösung war, die ich auch implementieren wollte.

Wenn Sie jedoch die Logik teilen könnten, wie Supervisor redbeat-1 automatisch neu startet, wenn redbeat-2 ausfällt, wäre das eine große Hilfe.

Dies mag an meinem Unverständnis bezüglich supervisor , aber es scheint, dass autorestart=True nur für Programme wirksam ist, die zumindest einmal in den Zustand RUNNING .

Mein Problem ist:

  1. Ich habe zwei program in meiner Supervisor.conf von celery beat mit redbeat.RedBeatScheduler .
  2. Beim Start des Supervisors erhält ein beat ( beat-1 ) die Sperre und läuft, während der andere ( beat-2 ) ein paar Mal versucht zu starten und in die FATAL Zustand (mit dem Seems we're already running? Fehler).
  3. Wenn beat-1 aufhört, möchte ich idealerweise, dass der Supervisor beat-2 startet.
  4. Dies geschieht jedoch nicht, da es sich zu Beginn nie in einem Zustand von RUNNING . Das heißt, wenn ich beat-1 , dann stoppt es und dann passiert nichts.

Aus meinem Kopf wäre die Lösung, ein cron , das alle 5 Sekunden oder so ein supervisorctl restart all , aber ich wollte nur wissen, wie du das erreichen konntest diese Redundanz mit dem Vorgesetzten.

Hallo @harisibrahimkv , Ihr Problem ist, dass Sie zwei identische Instanzen von Sellerie-Beat auf demselben Host starten. Ich gehe davon aus, dass Sie ERROR: Pidfile (celerybeat.pid) already exists. in Ihren Protokollen für beat-2 ? Ich kann sehen, dass es nützlich wäre, wenn zwei Instanzen von celery beat auf demselben Host ausgeführt werden, um das Failover zwischen ihnen zu testen, aber für echte Redundanz möchten Sie wahrscheinlich, dass celery beat auf mehreren Hosts ausgeführt wird.

Um mehrere Instanzen auf demselben Host laufen zu lassen, lassen Sie den Supervisor diese mit dem Argument --pidfile starten und geben Sie ihnen separate pidfiles: zB

# beat-1 
celery beat --scheduler=redbeat.RedBeatScheduler --pidfile="beat-1.pid" ...
# beat-2
celery beat --scheduler=redbeat.RedBeatScheduler --pidfile="beat-2.pid" ...

Beide Instanzen sollten erfolgreich unter Supervisor gestartet werden, aber wenn Sie die Protokolldateien überprüfen, sollte nur eine von ihnen Tasks planen. Wenn Sie diese Instanz stoppen, sollten Sie sehen, dass die andere Instanz die Aufgabenplanung übernimmt.

Unser Ziel war es, einen automatisch skalierenden Pool von identischen Hosts zu haben, die Selleriearbeiter und Sellerieschläge unter Aufsicht ausführen. Jeder Host hat eine einzelne Sellerie-Beat-Instanz. In dieser Konfiguration sollte celery beat auf allen Hosts erfolgreich gestartet werden, aber alle Instanzen von celery beat, die die Sperre nicht erhalten, sind effektiv Hot-Standbys und planen keine Tasks (obwohl alle Hosts im Pool Tasks verarbeiten). Wenn die Instanz mit der Sperre angehalten wird (z. B. wenn der Pool herunterskaliert wird oder wir ein fortlaufendes Upgrade von Hosts im Pool durchführen), dann erwirbt eine der Standby-Instanzen die Sperre und übernimmt die Planungsaufgaben.

@ddevlin Vielen Dank, dass Sie sich bei mir

  1. Das pidfile Bit funktionierte und ich war so glücklich zu sehen, wie beat-2 die Aufgaben übernahm, als der andere aufhörte. Konnte die Zeit des Beats mit CELERYBEAT_MAX_LOOP_INTERVAL = 25 konfigurieren (auf Sellerie 3.x).

  2. Ja, für echte Redundanz planen wir, dieses Setup auf verschiedenen Instanzen zu haben. Vielen Dank für die Erläuterung des von Ihnen verwendeten Setups. Werde jetzt daran arbeiten. Das Setup "mehrere Hosts auf derselben Instanz", wie Sie richtig verstanden haben, diente nur dazu, zunächst zu überprüfen, ob das Konzept des Failovers mit diesem Supervisor-Setup funktioniert.

Herzlichen Dank,
Aus einem kleinen Dorf an der südlichsten Spitze des indischen Subkontinents. :)

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen