Speicherlecks während der Verwendung von Sellerie
Problembeschreibung
Sellerie-asynchrone Aufgaben führen asynchrone Aufgaben in einer Zeitschleife aus. Nach etwa einem halben Monat, nachdem eine Speicherwarnmeldung empfangen wurde, nimmt der Speicher eine Woche lang langsam zu.
Der oberste Befehl zum Abfragen der Speichernutzung ist sehr hoch, wie in der folgenden Abbildung dargestellt
Identifizieren Sie das Problem
Bei Verwendung des Memory Profiler- Toolkits zum Debuggen wird
festgestellt, dass an den meisten Stellen, an denen bei asynchronen Aufgaben Speicherinkremente auftreten, die Anforderung gesendet wird. Zum Beispiel das folgende BeispielLine # Mem usage Increment Occurences Line Contents ============================================================ 5 23.94531 MiB 23.94531 MiB 1 @profile(precision=5) 6 def my_func(url): 7 8 25.59375 MiB 1.64844 MiB 1 resp = requests.get(url) 9 25.59375 MiB 0.00000 MiB 1 print(resp) 10 25.59375 MiB 0.00000 MiB 1 return resp
Auflösungsprozess
Zur Ausgabe von Online - relevanten Sellerie Speicherlecks bei Github auf Sellerie - Projekt fanden auch ein ähnliches Speicherverlust - Problem hat Problem ,
stellt ein Sellerie Wiederherstellungsanforderung zu RabbitMQ Zeit initiieren, auch ein Leck Gedächtnis hatte. Dieses Problem wurde jedoch nicht gelöst und ist noch offenIch habe auch das Problem mit Speicherverlusten bei Anforderungen abgefragt: Bei der Verwendung von Anforderungen treten Speicherverluste auf, und der Speicher wird nach der Anforderung nicht freigegeben. Die Verwendung von request.Session () ist ein Anwendungsbeispiel, mit dem dieses Problem
behoben werden kann. Requests.Session () weist jedoch Thread-Sicherheitsprobleme auf. Es ist am besten, eine Session () für einen Thread zu verwenden, request.Session () folgt jedoch nicht dem Thread Ende und Ende. Dieses Problem wurde nicht vollständig behobenDies ist eindeutig nicht die Antwort , die sie sah, Sellerie amtliches Dokument per Child Aufgaben Max einstellen ,
erklärt das Problem der Speicherlecks , wenn es Sellerie Job - Programm, aber nicht innerhalb des Steuerungsprogramms. Sie können diese Option verwenden. Sie können den Worker so konfigurieren, dass stattdessen ein neuer Prozess gestartet und der vorherige Prozess geschlossen wird, nachdem die maximale Anzahl von Aufgaben ausgeführt wurde.
Da eine große Anzahl von Anforderungspaketen im Programm verwendet wird, ist es derzeit unmöglich, schnell zu ersetzen und einen Weg zu finden, auf dem kein Speicherverlust auftritt (außerdem sind die Informationen im Internet wahrscheinlich alle urllib3, urllib und Anforderungen weisen Speicherverluste auf).
Die aktuelle Lösung für den dringenden Bedarf besteht darin, CELERYD_MAX_TASKS_PER_CHILD zum Wiederherstellen zu verwenden , nachdem der Worker 30 Aufgaben ausgeführt hat.
CELERYD_CONCURRENCY = 1 # celery worker 的并发数
CELERYD_PREFETCH_MULTIPLIER = 1 # 一次预取多少消息乘以并发进程数。默认值为4 要禁用预取将其设置1 若为0 将允许工作程序继续使用所需数量的消息。
CELERYD_MAX_TASKS_PER_CHILD = 30 # 池工作进程可以被新任务替换之前执行的最大任务数。默认值是没有限制。
Die Neuerstellung des Prozesses ist jedoch keine gute Lösung. Es muss noch untersucht werden, wie das Problem des Speicherverlusts bei Anforderungen gelöst werden kann. Setzen Sie es später für die Forschung.
- Von: xaohuihui
- Das Reiben der Hände ist nicht einfach. Denken Sie daran, die Hauptrolle zu spielen