Ich habe gerade von der Konfigurationsoption CELERYD_PREFETCH_MULTIPLIER
( docs ) erfahren . Der Standardwert ist 4, aber (glaube ich) ich möchte das Prefetching deaktivieren oder so niedrig wie möglich halten. Ich habe es jetzt auf 1 gesetzt, was nah genug an dem liegt, wonach ich suche, aber es gibt noch einige Dinge, die ich nicht verstehe:
Warum ist das Prefetching eine gute Idee? Ich sehe keinen Grund dafür, es sei denn, zwischen der Nachrichtenwarteschlange und den Arbeitern besteht eine große Latenz (in meinem Fall werden sie derzeit auf demselben Host ausgeführt und im schlimmsten Fall möglicherweise auf verschiedenen Hosts mit denselben Daten Center). In der Dokumentation werden nur die Nachteile erwähnt, die Vorteile jedoch nicht erläutert.
Viele Leute scheinen dies auf 0 zu setzen und erwarten, dass sie das Prefetching auf diese Weise deaktivieren können (meiner Meinung nach eine vernünftige Annahme). 0 bedeutet jedoch unbegrenztes Vorabrufen. Warum sollte jemand jemals unbegrenztes Prefetching wünschen, beseitigt dies nicht vollständig die Parallelität / Asynchronität, für die Sie eine Task-Warteschlange eingeführt haben?
Warum kann das Prefetching nicht deaktiviert werden? In den meisten Fällen ist es möglicherweise keine gute Idee, die Leistung auszuschalten. Gibt es jedoch einen technischen Grund dafür, dass dies nicht möglich ist? Oder ist es einfach nicht implementiert?
Manchmal ist diese Option mit verbunden
CELERY_ACKS_LATE
. Zum Beispiel. Roger Hu schreibt: «[…] Oft möchten [Benutzer], dass ein Mitarbeiter nur so viele Aufgaben reserviert, wie untergeordnete Prozesse vorhanden sind. Dies ist jedoch nicht möglich, ohne verspätete Bestätigungen zu ermöglichen. […] »Ich verstehe nicht, wie diese beiden Optionen miteinander verbunden sind und warum eine ohne die andere nicht möglich ist. Eine weitere Erwähnung der Verbindung finden Sie hier . Kann jemand erklären, warum die beiden Optionen miteinander verbunden sind?
CELERYD_PREFETCH_MULTIPLIER = 1
funktioniert nicht deaktivieren Prefetching. Es wird einfach - wie der Name schon sagt - jeweils nur eine Aufgabe vorab abgerufen.Alte Frage, aber ich füge immer noch meine Antwort hinzu, falls es jemandem hilft. Mein Verständnis von einigen ersten Tests war das gleiche wie das in David Wolevers Antwort. Ich habe dies gerade mehr in Sellerie 3.1.19 getestet und
-Ofair
funktioniert. Nur, dass es nicht dazu gedacht ist, das Prefetch auf Worker-Node-Ebene zu deaktivieren. Das wird auch weiterhin passieren. Die Verwendung-Ofair
hat einen anderen Effekt, der sich auf der Ebene der Poolarbeiter befindet. Um den Prefetch vollständig zu deaktivieren, gehen Sie wie folgt vor:CELERYD_PREFETCH_MULTIPLIER = 1
CELERY_ACKS_LATE = True
globaler Ebene oder Aufgabenebene festlegen-Ofair
beim Starten der ArbeiterWeitere Details hinzufügen:
Ich habe festgestellt, dass der Worker-Knoten standardmäßig immer vorab abgerufen wird. Sie können nur steuern, wie viele Aufgaben vorab abgerufen werden
CELERYD_PREFETCH_MULTIPLIER
. Bei der Einstellung 1 werden nur so viele Aufgaben vorab abgerufen wie die Anzahl der Pool-Worker (Parallelität) im Knoten. Wenn Sie also Parallelität = n hatten, sind die vom Knoten vorab abgerufenen maximalen Aufgaben n.Ohne die
-Ofair
Option passierte für mich, dass, wenn einer der Pool-Worker-Prozesse eine lange laufende Aufgabe ausführte, die anderen Worker im Knoten auch die Verarbeitung der bereits vom Knoten vorab abgerufenen Aufgaben einstellen würden. Durch die Verwendung-Ofair
hat sich das geändert. Obwohl einer der Mitarbeiter im Knoten lange laufende Aufgaben ausführte, hörten andere nicht mit der Verarbeitung auf und verarbeiteten weiterhin die vom Knoten vorab abgerufenen Aufgaben. Ich sehe also zwei Ebenen des Vorabrufens. Eine auf Worker-Node-Ebene. Der andere auf der Ebene der einzelnen Arbeitnehmer. Die Verwendung-Ofair
für mich schien es auf Arbeiterebene zu deaktivieren.Wie hängt das
ACKS_LATE
zusammen?. Ich habe gerade festgestellt, dass vorab abgerufene Nachrichten in rabbitmq unter "Nicht bestätigte Nachrichten" angezeigt werden. Ich bin mir also nicht sicher, ob eine EinstellungACKS_LATE = True
bedeutet, dass die Aufgabe nur bestätigt wird, wenn die Aufgabe erfolgreich ist. Wenn nicht, würde es wohl passieren, wenn es von einem Arbeiter empfangen wird. Im Falle eines Prefetch wird die Aufgabe zuerst vom Worker empfangen (aus Protokollen bestätigt), aber später ausgeführtTrue
unbedingt erforderlich ist. Wir hatten unsere Aufgaben aus anderen Gründen sowieso so eingestellt (spätes Bestätigen).quelle
-Ofair
einen "anderen Effekt", aber nicht, wie sich der Effekt unterscheidet. Sie sprechen auch anCELERY_ACKS_LATE
, wie andere zuvor, aber bisher hat es niemand geschafft, mir zu erklären, was dieses Attribut mit dem Deaktivieren des Vorabrufs zu tun hat.prefetch=1, celery_acks=True
und als ich es hinzufügte-Ofair
, wurde das Problem behoben, bei dem sie auf den hängenden Arbeiter warteten. Leider ist das Problem mit den hängengebliebenen Arbeitern immer noch nicht für mich behoben, und so hängen schließlich alle Arbeiter, aber zumindest tun sie es nicht mehr genau zur gleichen Zeit.Nur eine Warnung: Bei meinen Tests mit dem Redis Broker + Celery 3.1.15 sind alle Ratschläge, die ich zum
CELERYD_PREFETCH_MULTIPLIER = 1
Deaktivieren des Prefetching gelesen habe, nachweislich falsch.Um dies zu demonstrieren:
CELERYD_PREFETCH_MULTIPLIER = 1
time.sleep(5)
).Beobachten Sie die Länge der Aufgabenwarteschlange in Redis:
watch redis-cli -c llen default
Start
celery worker -c 1
5
bis abfällt3
CELERYD_PREFETCH_MULTIPLIER = 1
verhindert nicht das Vorabrufen , sondern beschränkt das Vorabrufen einfach auf 1 Aufgabe pro Warteschlange.-Ofair
verhindert trotz der Dokumentation auch nicht das Prefetching .Ohne den Quellcode zu ändern, habe ich keine Methode gefunden, um das Prefetching vollständig zu deaktivieren.
quelle
CELERY_ACKS_LATE = 1
, wird das Vorabrufen effektiv deaktiviert, wenn Sie auch festlegen .Ich kann die Antworten von David Wolever nicht kommentieren, da mein Stackcred nicht hoch genug ist. Daher habe ich meinen Kommentar als Antwort formuliert, da ich meine Erfahrungen mit Celery 3.1.18 und einem Mongodb-Broker teilen möchte. Ich habe es geschafft, das Prefetching mit folgendem zu beenden:
CELERYD_PREFETCH_MULTIPLIER = 1
zur Selleriekonfiguration hinzufügenCELERY_ACKS_LATE = True
zur Selleriekonfiguration hinzufügen--concurrency=1 -Ofair
Wenn Sie CELERY_ACKS_LATE auf den Standardwert setzen, wird der Worker weiterhin vorab abgerufen. Genau wie beim OP verstehe ich den Zusammenhang zwischen Prefetching und Late Acks nicht vollständig. Ich verstehe, was David sagt "CELERY_ACKS_LATE = True verhindert, dass Nachrichten bestätigt werden, wenn sie einen Mitarbeiter erreichen", aber ich verstehe nicht, warum späte Bestätigungen mit dem Prefetch nicht kompatibel sind. Theoretisch würde ein Prefetch immer noch erlauben, spätes Recht zu bestätigen - auch wenn es nicht als solches in Sellerie codiert ist?
quelle
Mit SQS als Broker habe ich etwas anderes erlebt.
Das Setup war:
CELERYD_PREFETCH_MULTIPLIER = 1 ACKS_ON_FAILURE_OR_TIMEOUT=False CELERY_ACKS_LATE = True CONCURRENCY=1
Nach dem Fehlschlagen der Aufgabe (Ausnahme ausgelöst) war der Worker nicht mehr verfügbar, da die Nachricht sowohl in der lokalen als auch in der Remote-Warteschlange nicht bestätigt wurde.
Die Lösung, die die Arbeiter dazu brachte, weiterhin Arbeit zu verbrauchen, war die Einstellung
CELERYD_PREFETCH_MULTIPLIER = 0
Ich kann nur spekulieren, dass acks_late beim Schreiben des SQS-Transports nicht berücksichtigt wurde
quelle