Celery: Dieselbe Aufgabe wird mehrmals gleichzeitig ausgeführt?

Erstellt am 20. Nov. 2017  ·  43Kommentare  ·  Quelle: celery/celery

Das Problem ist ein Repost eines unbeaufsichtigten Google Groups -Posts _Gleiche Aufgabe wird mehrmals ausgeführt?_

> ./bin/celery -A celery_app report

software -> celery:4.1.0 (latentcall) kombu:4.1.0 py:3.6.1
            billiard:3.5.0.3 redis:2.10.6
platform -> system:Linux arch:64bit, ELF imp:CPython
loader   -> celery.loaders.app.AppLoader
settings -> transport:redis results:redis://localhost:6379/2

broker_url: 'redis://localhost:6379/2'
result_backend: 'redis://localhost:6379/2'
task_serializer: 'json'
result_serializer: 'json'
accept_content: ['json']
timezone: 'Europe/Berlin'
enable_utc: True
imports: 'tasks'
task_routes: {
 'tasks': {'queue': 'celery-test-queue'}}

Meine Anwendung plant eine einzelne Gruppe von zwei, manchmal drei Aufgaben, von denen jede ihre eigene ETA innerhalb einer Stunde hat. Wenn die ETA eintrifft, sehe ich Folgendes in meinem Sellerieprotokoll:

[2017-11-20 09:55:34,470: INFO/ForkPoolWorker-2] Task tasks._test_exec[bd08ab85-28a8-488f-ba03-c2befde10054] succeeded in 33.81780316866934s: None
[2017-11-20 09:55:34,481: INFO/ForkPoolWorker-2] Task tasks._test_exec[bd08ab85-28a8-488f-ba03-c2befde10054] succeeded in 0.009824380278587341s: None
[2017-11-20 09:55:34,622: INFO/ForkPoolWorker-2] Task tasks._test_exec[bd08ab85-28a8-488f-ba03-c2befde10054] succeeded in 0.14010038413107395s: None
…
[2017-11-20 09:55:37,890: INFO/ForkPoolWorker-8] Task tasks._test_exec[bd08ab85-28a8-488f-ba03-c2befde10054] succeeded in 0.012678759172558784s: None
[2017-11-20 09:55:37,891: INFO/ForkPoolWorker-2] Task tasks._test_exec[bd08ab85-28a8-488f-ba03-c2befde10054] succeeded in 0.01177949644625187s: None
[2017-11-20 09:55:37,899: INFO/ForkPoolWorker-8] Task tasks._test_exec[bd08ab85-28a8-488f-ba03-c2befde10054] succeeded in 0.008250340819358826s: None
…

Dies kann sich dutzende Male wiederholen. Beachten Sie die Ausführungszeit der ersten Aufgabe von 33 Sekunden und den Einsatz verschiedener Arbeiter!

Ich habe keine Erklärung für dieses Verhalten und würde gerne verstehen, was hier vor sich geht.

Redis Broker Redis Results Backend Feedback Needed ✘ Needs Testcase ✘

Hilfreichster Kommentar

@georgepsarakis Wenn die Aufgabe also weit im Voraus geplant ist, sehe ich dann möglicherweise das Obige? Das „Sichtbarkeits-Timeout“ adressiert das? Aus der verlinkten Dokumentation:

Das standardmäßige Sichtbarkeits-Timeout für Redis beträgt 1 Stunde.

Das bedeutet, dass, wenn der Arbeiter die Aufgabe nicht innerhalb einer Stunde bestätigt (dh sie ausführt?), diese Aufgabe an einen anderen Arbeiter gesendet wird, der nicht bestätigen würde, und so weiter… In der Tat scheint dies der Fall zu sein, wenn man sich den Abschnitt mit den Vorbehalten ansieht die Dokumentation; dieses verwandte Problem https://github.com/celery/kombu/issues/337; oder Zitat aus diesem Blog :

Aber wenn Entwickler gerade erst anfangen, es zu verwenden, werden sie regelmäßig mit abnormalem Verhalten von Arbeitern konfrontiert, insbesondere mit der mehrfachen Ausführung derselben Aufgabe durch mehrere Arbeiter. Der Grund dafür ist eine Einstellung für das Sichtbarkeits-Timeout.

Sieht so aus, als wäre das Festlegen von visibility_timeout auf 31.540.000 Sekunden (ein Jahr) eine schnelle Lösung.

Alle 43 Kommentare

Vielleicht hängt das mit dem Sichtbarkeits-Timeout zusammen?

@georgepsarakis Könnten Sie Ihren Verdacht bitte näher erläutern?

Soweit ich weiß, ist dies ein bekanntes Problem für Broker-Transporte, die keine integrierten Bestätigungsmerkmale von AMQP haben. Die Aufgabe wird einem neuen Mitarbeiter zugewiesen, wenn die Zeit bis zur Erledigung der Aufgabe die Zeitüberschreitung für die Sichtbarkeit überschreitet, sodass Aufgaben möglicherweise parallel ausgeführt werden.

@georgepsarakis Wenn die Aufgabe also weit im Voraus geplant ist, sehe ich dann möglicherweise das Obige? Das „Sichtbarkeits-Timeout“ adressiert das? Aus der verlinkten Dokumentation:

Das standardmäßige Sichtbarkeits-Timeout für Redis beträgt 1 Stunde.

Das bedeutet, dass, wenn der Arbeiter die Aufgabe nicht innerhalb einer Stunde bestätigt (dh sie ausführt?), diese Aufgabe an einen anderen Arbeiter gesendet wird, der nicht bestätigen würde, und so weiter… In der Tat scheint dies der Fall zu sein, wenn man sich den Abschnitt mit den Vorbehalten ansieht die Dokumentation; dieses verwandte Problem https://github.com/celery/kombu/issues/337; oder Zitat aus diesem Blog :

Aber wenn Entwickler gerade erst anfangen, es zu verwenden, werden sie regelmäßig mit abnormalem Verhalten von Arbeitern konfrontiert, insbesondere mit der mehrfachen Ausführung derselben Aufgabe durch mehrere Arbeiter. Der Grund dafür ist eine Einstellung für das Sichtbarkeits-Timeout.

Sieht so aus, als wäre das Festlegen von visibility_timeout auf 31.540.000 Sekunden (ein Jahr) eine schnelle Lösung.

Ich würde sagen, wenn Sie das Sichtbarkeits-Timeout auf 2 Stunden erhöhen, werden Ihre Aufgaben nur einmal ausgeführt.

Wenn Sie also kombinieren:

  • Redis-Broker
  • Verspätete Bestätigung
  • ETA gleich/über dem Sichtbarkeits-Timeout
    Sie erhalten mehrere Ausführungen für die Aufgabe.

Ich denke, was passiert ist:

  • Nach Ablauf einer Stunde beginnt ein Arbeitsprozess mit der Verarbeitung der Aufgabe.
  • Ein zweiter Worker sieht, dass sich diese Nachricht länger als das Sichtbarkeits-Timeout in der Warteschlange befindet und von einem anderen Worker verarbeitet wird.
  • Die Nachricht wird in der Warteschlange wiederhergestellt.
  • Ein anderer Worker beginnt mit der Verarbeitung derselben Nachricht.
  • Das obige geschieht für alle Worker-Prozesse.

Wenn Sie sich die Redis-Transportimplementierung ansehen, werden Sie feststellen, dass sie Sorted Sets verwendet und die Zeit in der Warteschlange als Punktzahl an zadd übergibt . Die Nachricht wird basierend auf diesem Zeitstempel wiederhergestellt und mit einem Intervall verglichen, das dem Sichtbarkeits-Timeout entspricht.

Ich hoffe, dies erklärt ein wenig die Interna des Redis-Transports.

@georgepsarakis , ich bin jetzt gründlich verwirrt. Wenn die ETA einer Aufgabe auf zwei Monate ab jetzt festgelegt ist, warum sollte ein Arbeiter sie eine Stunde nach der Planung der Aufgaben abholen? Übersehe ich etwas?

Meine (falsche?) Vermutung ist folgende:

  • Ich plane jederzeit in der Zukunft eine Aufgabe mit einer ETA; dann
  • die Aufgabe (dh ihre gemarshallten Argumente) und ETA werden in der Warteschlange sitzen, bis ETA ankommt; dann
  • ein Arbeiter beginnt mit der Bearbeitung der Aufgabe bei ETA.

Ihr „_Ich denke, was passiert ist:_“ oben ist ganz anders als meine Annahme.

Ich bin auch auf das gleiche Problem gestoßen, hast du es gelöst? @jenströger

Danke!

@jenstroeger das klingt nicht nach einem durchführbaren Ablauf, ich denke, der Arbeiter stellt die Nachricht einfach kontinuierlich in die Warteschlange, um die Ausführung zu verschieben, bis die ETA-Bedingung endlich erfüllt ist. Das Konzept der Warteschlange besteht darin, Nachrichten zu verteilen, sobald sie ankommen, sodass der Worker die Nachricht untersucht und einfach erneut in die Warteschlange einreiht.

Bitte beachten Sie, dass dies meine Vermutung ist, ich bin mir der Interna der ETA-Implementierung nicht wirklich bewusst.

@zivsu , wie oben erwähnt , habe ich visibility_timeout auf eine _sehr_ große Zahl gesetzt, und das scheint die Symptome behoben zu haben. Wie @georgepsarakis betont , scheint dies jedoch ein schlechter Ansatz zu sein.

Ich kenne weder die Ursache des ursprünglichen Problems, noch weiß ich, wie man es richtig angeht.

@jenstroeger Ich habe einen Blog gelesen, visibility_timeout ändern kann das Problem nicht vollständig lösen, also ändere ich meinen Borker auf rabbitmq .

@zivsu , kannst du bitte den Link zum Blog teilen? Hast du vorher Redis verwendet?

@jenstroeger Ich kann den Blog nicht finden, ich habe vorher Redis als Broker verwendet. Für die Zeitplanaufgabe wähle ich rebbitmq, um zu vermeiden, dass der Fehler erneut auftritt.

Ich habe genau das gleiche Problem, meine Konfiguration ist:
django==1.11.6
Sellerie==4.2rc2
Django-Sellerie-Beat==1.0.1

die Einstellungen:

CELERY_ENABLE_UTC = True
# CELERY_TIMEZONE = 'America/Los_Angeles'

Und das ist die einzige funktionierende Kombination dieser Einstellungen. Außerdem muss ich meine regelmäßigen Aufgaben in der UTC-Zeitzone planen.
Wenn Sie CELERY_TIMEZONE aktivieren oder CELERY_ENABLE_UTC deaktivieren, werden periodische Aufgaben mehrmals ausgeführt.

Ich habe das Speicherproblem. Die eta-Aufgabe wird mehrfach ausgeführt, wenn Redis als Broker verwendet wird.
irgendwie kann man das lösen..
Sieht so aus, als würde der Broker von Redis zu Rabbitmq wechseln, um dieses Problem zu lösen.

Bei der Verwendung von redis gibt es ein bekanntes Problem, wenn Sie eine andere Zeitzone als UTC angeben. Um das Problem zu umgehen, klassifizieren Sie die Standard-App und fügen Sie Ihre eigene Zeitzonen-Behandlungsfunktion hinzu:

from celery import Celery


class MyAppCelery(Celery):
    def now(self):
        """Return the current time and date as a datetime."""
        from datetime import datetime
        return datetime.now(self.timezone)

Hoffe, das hilft jemand anderem, der auf dieses Problem stößt.

Ich bekomme dieses Problem manchmal, wenn ich häufig Sellerie-Jobs mit Beat auf Multicore-Rechnern neu starte. Ich habe mir angewöhnt, ps aux | grep celery und dann kill <each_pid> auszuführen, um das Problem zu lösen.

Der beste Rat, den ich habe, ist, immer sicherzustellen, dass die Meldung "Neustart fertig" angezeigt wird, bevor Sie die Verbindung zur Maschine trennen.

{"log":"INFO 2018-10-09 17:41:08,468 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-09T17:41:08.468912644Z"}
{"log":"INFO 2018-10-09 17:41:08,468 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-09T17:41:08.468955918Z"}
{"log":"INFO 2018-10-09 19:46:04,293 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-09T19:46:04.293780045Z"}
{"log":"INFO 2018-10-09 19:46:04,293 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-09T19:46:04.293953621Z"}
{"log":"INFO 2018-10-09 20:46:04,802 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-09T20:46:04.802819711Z"}
{"log":"INFO 2018-10-09 20:46:04,802 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-09T20:46:04.802974829Z"}
{"log":"INFO 2018-10-09 21:46:05,335 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-09T21:46:05.336081133Z"}
{"log":"INFO 2018-10-09 21:46:05,335 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-09T21:46:05.336107517Z"}
{"log":"INFO 2018-10-09 22:46:05,900 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-09T22:46:05.901078395Z"}
{"log":"INFO 2018-10-09 22:46:05,900 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-09T22:46:05.901173663Z"}
{"log":"INFO 2018-10-09 23:46:06,484 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-09T23:46:06.485276904Z"}
{"log":"INFO 2018-10-09 23:46:06,484 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-09T23:46:06.485415253Z"}
{"log":"INFO 2018-10-10 00:46:07,072 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-10T00:46:07.072529828Z"}
{"log":"INFO 2018-10-10 00:46:07,072 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-10T00:46:07.072587887Z"}
{"log":"INFO 2018-10-10 01:46:07,602 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-10T01:46:07.60325321Z"}
{"log":"INFO 2018-10-10 01:46:07,602 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-10T01:46:07.603327426Z"}
{"log":"INFO 2018-10-10 02:46:08,155 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-10T02:46:08.155868992Z"}
{"log":"INFO 2018-10-10 02:46:08,155 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-10T02:46:08.155921893Z"}
{"log":"INFO 2018-10-10 03:46:08,753 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-10T03:46:08.75401387Z"}
{"log":"INFO 2018-10-10 03:46:08,753 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-10T03:46:08.754056891Z"}
{"log":"DEBUG 2018-10-10 04:00:00,013 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:70\n","stream":"stderr","time":"2018-10-10T04:00:00.013548928Z"}
{"log":"DEBUG 2018-10-10 04:00:00,013 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:70\n","stream":"stderr","time":"2018-10-10T04:00:00.013592318Z"}
{"log":"DEBUG 2018-10-10 04:00:00,013 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:71\n","stream":"stderr","time":"2018-10-10T04:00:00.014000106Z"}
{"log":"DEBUG 2018-10-10 04:00:00,013 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:71\n","stream":"stderr","time":"2018-10-10T04:00:00.014167558Z"}
{"log":"DEBUG 2018-10-10 04:00:00,014 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:64\n","stream":"stderr","time":"2018-10-10T04:00:00.014661348Z"}
{"log":"DEBUG 2018-10-10 04:00:00,014 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:64\n","stream":"stderr","time":"2018-10-10T04:00:00.014684354Z"}
{"log":"DEBUG 2018-10-10 04:00:00,014 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:65\n","stream":"stderr","time":"2018-10-10T04:00:00.01514884Z"}
{"log":"DEBUG 2018-10-10 04:00:00,014 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:65\n","stream":"stderr","time":"2018-10-10T04:00:00.015249646Z"}
{"log":"DEBUG 2018-10-10 04:00:00,015 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:66\n","stream":"stderr","time":"2018-10-10T04:00:00.01571124Z"}
{"log":"DEBUG 2018-10-10 04:00:00,015 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:66\n","stream":"stderr","time":"2018-10-10T04:00:00.01580249Z"}
{"log":"DEBUG 2018-10-10 04:00:00,019 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:68\n","stream":"stderr","time":"2018-10-10T04:00:00.019260948Z"}
{"log":"DEBUG 2018-10-10 04:00:00,019 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:68\n","stream":"stderr","time":"2018-10-10T04:00:00.019322151Z"}
{"log":"DEBUG 2018-10-10 04:00:00,245 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:70\n","stream":"stderr","time":"2018-10-10T04:00:00.245159563Z"}
{"log":"DEBUG 2018-10-10 04:00:00,245 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:70\n","stream":"stderr","time":"2018-10-10T04:00:00.245177267Z"}
{"log":"DEBUG 2018-10-10 04:00:00,245 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:67\n","stream":"stderr","time":"2018-10-10T04:00:00.245338722Z"}
{"log":"DEBUG 2018-10-10 04:00:00,245 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:67\n","stream":"stderr","time":"2018-10-10T04:00:00.245351289Z"}
{"log":"DEBUG 2018-10-10 04:00:00,256 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:65\n","stream":"stderr","time":"2018-10-10T04:00:00.256770035Z"}
{"log":"DEBUG 2018-10-10 04:00:00,256 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:65\n","stream":"stderr","time":"2018-10-10T04:00:00.256788689Z"}
{"log":"INFO 2018-10-10 04:00:00,371 trace celery.app.trace 68 140031597243208 Task main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] succeeded in 0.35710329699213617s: None\n","stream":"stderr","time":"2018-10-10T04:00:00.371967002Z"}
{"log":"INFO 2018-10-10 04:00:00,371 trace celery.app.trace 68 140031597243208 Task main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] succeeded in 0.35710329699213617s: None\n","stream":"stderr","time":"2018-10-10T04:00:00.371983293Z"}
{"log":"INFO 2018-10-10 04:00:00,387 trace celery.app.trace 69 140031597243208 Task main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] succeeded in 0.10637873200175818s: None\n","stream":"stderr","time":"2018-10-10T04:00:00.388119538Z"}
{"log":"INFO 2018-10-10 04:00:00,387 trace celery.app.trace 69 140031597243208 Task main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] succeeded in 0.10637873200175818s: None\n","stream":"stderr","time":"2018-10-10T04:00:00.388166317Z"}
{"log":"INFO 2018-10-10 04:00:00,404 trace celery.app.trace 70 140031597243208 Task main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] succeeded in 0.16254851799749304s: None\n","stream":"stderr","time":"2018-10-10T04:00:00.404834545Z"}
{"log":"INFO 2018-10-10 04:00:00,404 trace celery.app.trace 70 140031597243208 Task main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] succeeded in 0.16254851799749304s: None\n","stream":"stderr","time":"2018-10-10T04:00:00.404862208Z"}
{"log":"INFO 2018-10-10 04:00:00,421 trace celery.app.trace 65 140031597243208 Task main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] succeeded in 0.1654666289978195s: None\n","stream":"stderr","time":"2018-10-10T04:00:00.421607856Z"}
{"log":"INFO 2018-10-10 04:00:00,421 trace celery.app.trace 65 140031597243208 Task main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] succeeded in 0.1654666289978195s: None\n","stream":"stderr","time":"2018-10-10T04:00:00.421674687Z"}
{"log":"INFO 2018-10-10 04:00:00,438 trace celery.app.trace 67 140031597243208 Task main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] succeeded in 0.19588526099687442s: None\n","stream":"stderr","time":"2018-10-10T04:00:00.438295459Z"}
{"log":"INFO 2018-10-10 04:00:00,438 trace celery.app.trace 67 140031597243208 Task main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] succeeded in 0.19588526099687442s: None\n","stream":"stderr","time":"2018-10-10T04:00:00.438311386Z"}
...

Wenn wir die Zeitstempel der empfangenen Aufgabe überprüfen, erhält sie jede Stunde eine neue Aufgabe mit derselben ID. Das Ergebnis ist, dass alle ETA-Nachrichten mehr als 10 Mal gesendet werden. Sieht so aus, als wäre rabbitmq nur eine Option, wenn wir ETA verwenden möchten

Treffen Sie kürzlich auf einen ähnlichen Fehler. Auch ps aux | grep celery zeigte mehr Prozesse als Worker starteten, also zweimal mehr. Das Anhängen des Parameters --pool gevent an den Befehl zum Starten von Selleriearbeitern verringerte die Anzahl der Prozesse auf die genaue Anzahl der gestarteten Arbeiter und des Sellerieschlags. Und jetzt beobachte ich die Ausführung meiner Aufgaben.

Könnte eine andere Lösung darin bestehen, die Ack-Emulation vollständig zu deaktivieren? dh "broker_transport_options": {"ack_emulation": False} . Irgendwelche Nachteile für kurz laufende Aufgaben / Countdowns?

Hat jemand die Lösung bekommen?

Stehe vor dem gleichen Problem, gibt es eine Lösung dafür?

Ruckeln, das gleiche Problem.

Dasselbe Problem hier, mit Redis als Broker.

$ pipenv graph --bare | grep -i "redis\|celery"                                                                                                                                                                                                                              
---
channels-redis==2.4.0
  - aioredis [required: ~=1.0, installed: 1.3.0]
    - hiredis [required: Any, installed: 1.0.0]
django-celery-beat==1.5.0
django-celery-results==1.1.2
  - celery [required: >=4.3,<5.0, installed: 4.3.0]
  - celery [required: >=3.1.0, installed: 4.3.0]
  - pylint-celery [required: ==0.3, installed: 0.3]
redis==3.2.1

Selbes Problem hier. Sellerie-Version 4.3.0
Sellerie = Sellerie('tasks', broker='pyamqp://nosd:sdsd@rabbit//', config_from_object={"broker_transport_options":{'visibility_timeout': 18000}})

Der Befehl, mit dem ich meinen Worker ausführe
celery -A Tasks Worker --pidfile=/tmp/celery_worker.pid -f=/tmp/celery_worker.log -Q celery_queue --loglevel=info --pool=solo --concurrency=1 -n worker_celery --detach -- ohne Klatsch - ohne Vermischung - ohne Herzschlag

kannst du es mit celery==4.4.0rc4 versuchen?

Sellerie erhält dieselbe Aufgabe zweimal mit derselben Aufgaben-ID zur gleichen Zeit.
Hier sind die Protokolle

[2019-11-29 08:07:35,464: INFO/MainProcess] Received task: app.jobs.booking.bookFlightTask[657985d5-c3a3-438d-a524-dbb129529443]  
[2019-11-29 08:07:35,465: INFO/MainProcess] Received task: app.jobs.booking.bookFlightTask[657985d5-c3a3-438d-a524-dbb129529443]  
[2019-11-29 08:07:35,471: WARNING/ForkPoolWorker-4] in booking funtion1
[2019-11-29 08:07:35,473: WARNING/ForkPoolWorker-3] in booking funtion1
[2019-11-29 08:07:35,537: WARNING/ForkPoolWorker-3] book_request_pp
[2019-11-29 08:07:35,543: WARNING/ForkPoolWorker-4] book_request_pp

beide laufen gleichzeitig,

mit Sellerie==4.4.0rc4 , boto3==1.9.232, Kombu==4.6.6 mit SQS in Python-Flasche.
In SQS beträgt das standardmäßige Sichtbarkeits-Timeout 30 Minuten, und meine Aufgabe hat keine ETA und keine Bestätigung.

laufender Arbeiter wie,
Selleriearbeiter -A app.jobs.run -l info --pidfile=/var/run/celery/celery.pid --logfile=/var/log/celery/celery.log --time-limit=7200 --concurrency =8

@auvipy , jede Hilfe wäre großartig.

Welchen Broker und welches Ergebnis-Backend verwenden Sie? Können Sie versuchen, auf ein anderes Backend umzusteigen?

Welchen Broker und welches Ergebnis-Backend verwenden Sie? Können Sie versuchen, auf ein anderes Backend umzusteigen?

Bei Verwendung von SQS ist das Ergebnis-Backend MYSQL mit sqlalchemy.
Einzelheiten finden Sie hier unter SO, https://stackoverflow.com/questions/59123536/celery-is-receiving-same-task-twice-with-same-task-id-at-same-time
@auvipy kannst du bitte mal schauen.

@thedrow tritt dieses Problem in Bloomberg auf?

@nitish-itilite: Welche Zeitzone verwendest du für Sellerie?

@nitish-itilite: Welche Zeitzone verwendest du für Sellerie?

es ist standardmäßig UTC. in Quadratkilometern ist die Region diese USA Ost (Nord-Virginia).

Ich hatte einen ähnlichen Fall mit Sellerie mit SQS. Ich habe eine Dummy-Aufgabe mit countdown=60 ausgeführt, während das Sichtbarkeits-Timeout in SQS 30 Sekunden beträgt. Hier ist, was ich bekomme:

HINWEIS: Ich habe Sellerie mit --concurrency=1 begonnen, also gibt es zwei Threads, richtig?

[2020-02-18 14:46:32 +0000] [INFO] Received task: notification[b483a22f-31cc-4335-9709-86041baa8f05]  ETA:[2020-02-18 14:47:31.898563+00:00] 
[2020-02-18 14:47:02 +0000] [INFO] Received task: notification[b483a22f-31cc-4335-9709-86041baa8f05]  ETA:[2020-02-18 14:47:31.898563+00:00] 
[2020-02-18 14:47:32 +0000] [INFO] Task notification[b483a22f-31cc-4335-9709-86041baa8f05] succeeded in 0.012232275999849662s: None
[2020-02-18 14:47:32 +0000] [INFO] Task notification[b483a22f-31cc-4335-9709-86041baa8f05] succeeded in 0.012890915997559205s: None

Was geschah in chronologischer Reihenfolge:

  1. 14:46:32 Aufgabe wurde empfangen und SQS hat sie für 30 Sekunden in den inflight -Modus versetzt
  2. 14:47:02 Dieselbe Aufgabe wurde empfangen, weil das Sichtbarkeits-Timeout abgelaufen ist
  3. 14:47:32 Beide Tasks werden gleichzeitig ausgeführt

Meine Vermutung ist, dass dies ein Fehler in Celery (?) ist. Ich denke, es hätte überprüfen sollen, ob die Nachrichten-ID ( b483a22f-31cc-4335-9709-86041baa8f05 ) bereits von diesem Arbeiter übernommen wurde.

Vielleicht könnte es eine Hash-Liste mit allen Nachrichten-IDs geben, damit Celery entscheiden kann, ob eine empfangene Aufgabe zur Verarbeitung gültig ist. Kann Sellerie das?

ANMERKUNG 2:
Wir können ein Sichtbarkeits-Timeout nicht zu lange festlegen, denn wenn der Arbeiter tatsächlich stirbt, würde es zu lange dauern, bis die Nachricht von einem anderen Arbeiter abgeholt wird. Eine zu niedrige Einstellung würde diesen Zustand aufdecken.

Das scheint mir auch zu passieren.

[2020-05-11 15:31:23,673: INFO/MainProcess] Empfangene Aufgabe: ee_external_attributes.tasks. spezifische_werte neu erstellen[53046bd7-2a19-4f72-808f-d712eaecb0e8]
[2020-05-11 15:31:28,673: INFO/MainProcess] Empfangene Aufgabe: ee_external_attributes.tasks.recreate_specific_values[53046bd7-2a19-4f72-808f-d712eaecb0e8]

(Ich habe den Aufgabennamen in den Protokollen für die öffentliche Veröffentlichung angepasst.)

Aufgrund von Eindeutigkeitsbeschränkungen wirft einer meiner Arbeiter mitten in der Aufgabe einen Fehler, und der andere ist erfolgreich.

Ich habe versucht einzustellen
CELERY_WORKER_PREFETCH_MULTIPLIER = 1
Wie sich herausstellte, half das nicht.

Ich benutze
Sellerie==4.4.1
Django-Sellerie-Ergebnisse==1.2.1

Und ich verwende AWS SQS für die Warteschlange.

Ich habe eine Theorie. Anscheinend war meine Einstellung "Default Visibility Timeout" in meiner Warteschlange nur auf 5 Sekunden eingestellt. Es kann sein, dass der zweite Arbeiter den Auftrag zurückgezogen hat, während der erste daran gearbeitet hat, weil er davon ausgegangen ist, dass der erste Arbeiter gestorben ist. Ich habe das Sichtbarkeits-Timeout auf 2 Minuten erhöht, und es scheint besser zu werden. Ich hatte viele Aufgaben, die 8-12 Sekunden gedauert haben, also könnten 2 Minuten zu viel des Guten sein. Aber das löst es hoffentlich.

Es kann sein, dass der zweite Arbeiter den Auftrag zurückgezogen hat, während der erste daran gearbeitet hat, weil er davon ausgegangen ist, dass der erste Arbeiter gestorben ist.

@JulieGoldberg , das wäre eine miese Art für Celery, Jobs zu erledigen. Ein Celery-Arbeiter sollte niemals einen Job starten, den ein anderer Arbeiter aus der Warteschlange gezogen hat und aktiv bearbeitet; denke, das wäre ernsthaft kaputt. (Aber es ist Sellerie, mich wundert nichts mehr 😒)

Ich habe ein ähnliches Problem mit einer Anwendung, die in Kubernetes ausgeführt wird. In der Kubernetes-Instanz haben wir 10 Worker (Sellerie-App-Instanz), die die Aufgaben von Redis verbrauchen.

Symptome:
Der Selleriearbeiter plant eine ETA-Aufgabe, die nach 30 Minuten geplant wird. Wenn der Kubernetes-Pod rotiert (der Worker wird von Kubernetes beendet) oder eine neuere Version der Anwendung bereitgestellt wird (alle Worker werden beendet und neue Worker erstellt), übernehmen alle Worker die geplante Aufgabe und beginnen mit der Ausführung in der definierten Zeit.
Für den Arbeiter habe ich versucht, für mehrere Stunden bis zu einem Jahr unterschiedliche Werte von visibility_timeout festzulegen, aber das Ergebnis war immer noch dasselbe. Dasselbe Verhalten wurde mit der Einstellung enable_utc = True , bzw. einer Reduzierung um worker_prefetch_multiplier = 1 erreicht.

Ich weiß nicht, ob das jemandem hilft, aber das war mein Problem:

Ich hatte Aufgaben (Berichterstellung), die ausgeführt wurden, als eine Seite über GET geladen wurde. Aus irgendeinem Grund (etwas, das mit Favicons zu tun hat) würde Chrome bei jedem Laden der Seite 2 GET-Anfragen senden und die Aufgabe zweimal auslösen.
GET-Anfragen sollen frei von Nebenwirkungen sein, also habe ich sie alle in Formulare umgewandelt, die Sie einreichen, und das Problem wurde behoben.

Es kann sein, dass der zweite Arbeiter den Auftrag zurückgezogen hat, während der erste daran gearbeitet hat, weil er davon ausgegangen ist, dass der erste Arbeiter gestorben ist.

@JulieGoldberg , das wäre eine miese Art für Celery, Jobs zu erledigen. Ein Celery-Arbeiter sollte niemals einen Job starten, den ein anderer Arbeiter aus der Warteschlange gezogen hat und aktiv bearbeitet; denke, das wäre ernsthaft kaputt. (Aber es ist Sellerie, mich wundert nichts mehr 😒)

Anstatt sich zu beschweren, können Sie uns helfen, das Problem zu beheben, indem Sie eine Lösung und eine PR vorschlagen.

Ich habe ein ähnliches Problem mit einer Anwendung, die in Kubernetes ausgeführt wird. In der Kubernetes-Instanz haben wir 10 Worker (Sellerie-App-Instanz), die die Aufgaben von Redis verbrauchen.

Symptome:
Der Selleriearbeiter plant eine ETA-Aufgabe, die nach 30 Minuten geplant wird. Wenn der Kubernetes-Pod rotiert (der Worker wird von Kubernetes beendet) oder eine neuere Version der Anwendung bereitgestellt wird (alle Worker werden beendet und neue Worker erstellt), übernehmen alle Worker die geplante Aufgabe und beginnen mit der Ausführung in der definierten Zeit.

@elMateso Ich hatte ähnliche Probleme mit der Airflow-Bereitstellung auf k8s (Verbraucher auf Pods und Redis als Warteschlange). Aber ich konnte die Bereitstellung stabil und wie erwartet funktionieren lassen, vielleicht helfen Ihnen diese Tipps:
https://www.polidea.com/blog/application-scalability-kubernetes/#tips-for-hpa

Stehe hier vor dem gleichen.

Scheint bei keiner Timing-Konfiguration (Sichtbarkeits-Timeout, ETA usw.) ein Problem zu sein, zumindest für mich. In meinem Fall passiert es Mikrosekunden zwischen den Ausführungen. Ich habe nicht herausgefunden, wie Sellerie tatsächlich eine Nachricht bestätigt, aber wenn es in RabbitMQ perfekt funktioniert, scheint es ein Problem mit Parallelität und Bestätigung in Redis zu geben.

Ich sehe das gleiche Problem und wir verwenden Redis auch als Broker. Der Wechsel zu rabbitMQ ist für uns keine Option.

Hat jemand versucht, eine Sperre zu verwenden, um sicherzustellen, dass die Aufgabe nur einmal ausgeführt wird? Könnte das funktionieren?

zB https://docs.celeryproject.org/en/latest/tutorials/task-cookbook.html#ensuring-a-task-is-only-executed-one-at-a-time

@ErikKalkoken am Ende machen wir genau das.

def semaphore(fn):
    @wraps(fn)
    def wrapper(self_origin, *args, **kwargs):
        cache_name = f"{UID}-{args[0].request.id}-semaphore"
        agreement_redis = AgreementsRedis()
        if not agreement_redis.redis.set(cache_name, "", ex=30, nx=True):
          Raise Exception("...")
        try:
            return fn(self_origin, *args, **kwargs)
        finally:
            agreement_redis.redis.delete(cache_name)

    return wrapper

Der obige Code wird nicht für Sellerie verwendet, aber die mehrfache Ausführung von Sellerie ist dieselbe Logik, Sie müssen nur die task_id abrufen und den Cache festlegen. Bisher funktioniert gut.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen