Celery: تسرب الذاكرة المستمر

تم إنشاؤها على ٢٣ يونيو ٢٠١٨  ·  129تعليقات  ·  مصدر: celery/celery

يوجد تسرب للذاكرة في العملية الأم لعامل الكرفس.
انها ليست عملية فرعية تنفيذ مهمة.
يحدث ذلك فجأة كل بضعة أيام.
ما لم توقف الكرفس ، فإنه يستهلك ذاكرة الخادم في عشرات الساعات.

تحدث هذه المشكلة على الأقل في الكرفس 4.1 ، وتحدث أيضًا في الكرفس 4.2.
يعمل الكرفس على Ubuntu 16 ويستخدم السماسرة RabbitMQ.

memory

Prefork Workers Pool RabbitMQ Broker Bug Report Critical Needs Testcase ✘ Needs Verification ✘ memory leak

التعليق الأكثر فائدة

لماذا تم إغلاق هذه القضية؟

ال 129 كومينتر

هل تستخدم مهام سير عمل Canvas؟ ربما # 4839 مرتبط.

أفترض أيضًا أنك تستخدم تجمع بريفورك لتزامن العمال؟

شكرا جورجيبساراكيس.

أنا لا أستخدم سير العمل.
يمكنني استخدام بريفورك التزامن 1 على خادم واحد.

معدل الزيادة يبدو خطيًا وغريبًا تمامًا. هل يقوم العامل بمعالجة المهام خلال هذه الفترة الزمنية؟ أيضًا ، هل يمكنك إضافة ملاحظة بالأمر الكامل الذي تستخدمه لبدء العامل؟

نعم. يستمر العامل في معالجة المهمة بشكل طبيعي.

يبدأ العامل بالأمر التالي.

/xxxxxxxx/bin/celery worker --app=xxxxxxxx --loglevel=INFO --pidfile=/var/run/xxxxxxxx.pid

تحدث هذه المشكلة في كل من بيئة الإنتاج وبيئة الاختبار.
يمكنني إضافة ملف تعريف الذاكرة واختبار الإخراج إلى بيئة الاختبار.
إذا كان هناك أي شيء يمكنني القيام به ، من فضلك قل شيئًا.

نحتاج إلى فهم ما يقوم العامل بتشغيله خلال الوقت الذي يتم فيه ملاحظة زيادة الذاكرة. أي معلومات وتفاصيل يمكن أن تقدمها ستكون بالتأكيد. من الجيد أيضًا أنه يمكنك إعادة إنتاج هذا.

على الرغم من أنها كانت حالة حدثت في توقيت مختلف عن الرسم البياني ، فقد تم إخراج السجل التالي في التوقيت الذي بدأ فيه تسرب الذاكرة.

[2018-02-24 07:50:52,953: WARNING/MainProcess] consumer: Connection to broker lost. Trying to re-establish the connection...
Traceback (most recent call last):
File "/xxxxxxxx/lib/python3.5/site-packages/celery/worker/consumer/consumer.py", line 320, in start
blueprint.start(self)
File "/xxxxxxxx/lib/python3.5/site-packages/celery/bootsteps.py", line 119, in start
step.start(parent)
File "/xxxxxxxx/lib/python3.5/site-packages/celery/worker/consumer/consumer.py", line 596, in start
c.loop(*c.loop_args())
File "/xxxxxxxx/lib/python3.5/site-packages/celery/worker/loops.py", line 88, in asynloop
next(loop)
File "/xxxxxxxx/lib/python3.5/site-packages/kombu/async/hub.py", line 293, in create_loop
poll_timeout = fire_timers(propagate=propagate) if scheduled else 1
File "/xxxxxxxx/lib/python3.5/site-packages/kombu/async/hub.py", line 136, in fire_timers
entry()
File "/xxxxxxxx/lib/python3.5/site-packages/kombu/async/timer.py", line 68, in __call__
return self.fun(*self.args, **self.kwargs)
File "/xxxxxxxx/lib/python3.5/site-packages/kombu/async/timer.py", line 127, in _reschedules
return fun(*args, **kwargs)
File "/xxxxxxxx/lib/python3.5/site-packages/kombu/connection.py", line 290, in heartbeat_check
return self.transport.heartbeat_check(self.connection, rate=rate)
File "/xxxxxxxx/lib/python3.5/site-packages/kombu/transport/pyamqp.py", line 149, in heartbeat_check
return connection.heartbeat_tick(rate=rate)
File "/xxxxxxxx/lib/python3.5/site-packages/amqp/connection.py", line 696, in heartbeat_tick
self.send_heartbeat()
File "/xxxxxxxx/lib/python3.5/site-packages/amqp/connection.py", line 647, in send_heartbeat
self.frame_writer(8, 0, None, None, None)
File "/xxxxxxxx/lib/python3.5/site-packages/amqp/method_framing.py", line 166, in write_frame
write(view[:offset])
File "/xxxxxxxx/lib/python3.5/site-packages/amqp/transport.py", line 258, in write
self._write(s)
ConnectionResetError: [Errno 104] Connection reset by peer
[2018-02-24 08:49:12,016: INFO/MainProcess] Connected to amqp://xxxxxxxx:**@xxx.xxx.xxx.xxx:5672/xxxxxxxx

يبدو أنه حدث عندما انقطع الاتصال بـ RabbitMQ مؤقتًا.

marvelph لذلك يحدث أثناء إعادة اتصال RabbitMQ؟ ربما ترتبط هذه القضايا:

نعم.
يبدو أن إعادة الاتصال تؤدي إلى ذلك.

يبدو أنني أواجه نفس المشكلة ... من الصعب جدًا بالنسبة لي معرفة ما الذي يؤدي إلى حدوثها ولماذا يوجد تسرب للذاكرة. إنه يزعجني لمدة شهر على الأقل. أنا أعود إلى استخدام الكرفس 3 وكل شيء على ما يرام.

بالنسبة لقضية تسرب الذاكرة ، أستخدم ubuntu 16 ، والكرفس 4.1.0 مع rabbitmq. قمت بنشره عبر عامل إرساء.

تسرب الذاكرة مع MainProcess وليس ForkPoolWorker. يعد استخدام ذاكرة ForkPoolWorker أمرًا طبيعيًا ، ولكن استخدام الذاكرة لـ MainProcess يتزايد دائمًا. لمدة خمس ثوان ، يتم تسريب حوالي 0.1 ميغا بايت من memeory. لا يبدأ تسريب الذاكرة بعد أن يبدأ العمل على الفور ولكن ربما بعد يوم أو يومين.

لقد استخدمت gdb و pyrasite لحقن عملية التشغيل ومحاولة gc.collect() ، لكن لم يتم جمع أي شيء.

لقد تحققت من السجل ، حدث consumer: Connection to broker lost. Trying to re-establish the connection... ، لكن في الوقت الحالي لست متأكدًا من أن هذا هو الوقت الذي يحدث فيه تسرب للذاكرة.

أي تلميحات لتصحيح هذه المشكلة ومعرفة ما يحدث بالفعل؟ شكرا.

نظرًا لأن marvelph قد ذكر أنه قد يكون مرتبطًا بإعادة اتصال rabbitmq ، فأنا أحاول إيقاف خادم rabbitmq. زاد استخدام الذاكرة بعد كل إعادة اتصال ، فيما يلي السجل. لذلك يمكنني تأكيد هذه المشكلة https://github.com/celery/kombu/issues/843 .

ولكن بعد إعادة الاتصال ، يتوقف استخدام الذاكرة ليزداد تدريجيًا. لذلك لست متأكدًا من أن هذا هو سبب تسرب الذاكرة.

سأحاول استخدام redis لمعرفة ما إذا كانت مشكلة تسرب الذاكرة هذه تتعلق بـ rabbitmq أم لا.

[2018-06-25 02:43:33,456: WARNING/MainProcess] consumer: Connection to broker lost. Trying to re-establish the connection...
Traceback (most recent call last):
  File "/app/.heroku/python/lib/python3.6/site-packages/celery/worker/consumer/consumer.py", line 316, in start
    blueprint.start(self)
  File "/app/.heroku/python/lib/python3.6/site-packages/celery/bootsteps.py", line 119, in start
    step.start(parent)
  File "/app/.heroku/python/lib/python3.6/site-packages/celery/worker/consumer/consumer.py", line 592, in start
    c.loop(*c.loop_args())
  File "/app/.heroku/python/lib/python3.6/site-packages/celery/worker/loops.py", line 91, in asynloop
    next(loop)
  File "/app/.heroku/python/lib/python3.6/site-packages/kombu/asynchronous/hub.py", line 354, in create_loop
    cb(*cbargs)
  File "/app/.heroku/python/lib/python3.6/site-packages/kombu/transport/base.py", line 236, in on_readable
    reader(loop)
  File "/app/.heroku/python/lib/python3.6/site-packages/kombu/transport/base.py", line 218, in _read
    drain_events(timeout=0)
  File "/app/.heroku/python/lib/python3.6/site-packages/amqp/connection.py", line 491, in drain_events
    while not self.blocking_read(timeout):
  File "/app/.heroku/python/lib/python3.6/site-packages/amqp/connection.py", line 496, in blocking_read
    frame = self.transport.read_frame()
  File "/app/.heroku/python/lib/python3.6/site-packages/amqp/transport.py", line 243, in read_frame
    frame_header = read(7, True)
  File "/app/.heroku/python/lib/python3.6/site-packages/amqp/transport.py", line 418, in _read
    s = recv(n - len(rbuf))
ConnectionResetError: [Errno 104] Connection reset by peer
[2018-06-25 02:43:33,497: ERROR/MainProcess] consumer: Cannot connect to amqp://***:**@***:***/***: [Errno 111] Connection refused.
Trying again in 2.00 seconds...

[2018-06-25 02:43:35,526: ERROR/MainProcess] consumer: Cannot connect to amqp://***:**@***:***/***: [Errno 111] Connection refused.
Trying again in 4.00 seconds...

[2018-06-25 02:43:39,560: ERROR/MainProcess] consumer: Cannot connect to amqp://***:**@***:***/***: [Errno 111] Connection refused.
Trying again in 6.00 seconds...

[2018-06-25 02:43:45,599: ERROR/MainProcess] consumer: Cannot connect to amqp://***:**@***:***/***: [Errno 111] Connection refused.
Trying again in 8.00 seconds...

[2018-06-25 02:43:53,639: ERROR/MainProcess] consumer: Cannot connect to amqp://***:**@***:***/***: [Errno 111] Connection refused.
Trying again in 10.00 seconds...

[2018-06-25 02:44:03,680: ERROR/MainProcess] consumer: Cannot connect to amqp://***:**@***:***/***: [Errno 111] Connection refused.
Trying again in 12.00 seconds...

[2018-06-25 02:44:15,743: ERROR/MainProcess] consumer: Cannot connect to amqp://***:**@***:***/***: [Errno 111] Connection refused.
Trying again in 14.00 seconds...

[2018-06-25 02:44:29,790: ERROR/MainProcess] consumer: Cannot connect to amqp://***:**@***:***/***: [Errno 111] Connection refused.
Trying again in 16.00 seconds...

[2018-06-25 02:44:45,839: ERROR/MainProcess] consumer: Cannot connect to amqp://***:**@***:***/***: [Errno 111] Connection refused.
Trying again in 18.00 seconds...

[2018-06-25 02:45:03,890: ERROR/MainProcess] consumer: Cannot connect to amqp://***:**@***:***/***: [Errno 111] Connection refused.
Trying again in 20.00 seconds...

[2018-06-25 02:45:23,943: ERROR/MainProcess] consumer: Cannot connect to amqp://***:**@***:***/***: [Errno 111] Connection refused.
Trying again in 22.00 seconds...

[2018-06-25 02:45:46,002: ERROR/MainProcess] consumer: Cannot connect to amqp://***:**@***:***/***: [Errno 111] Connection refused.
Trying again in 24.00 seconds...

[2018-06-25 02:46:10,109: INFO/MainProcess] Connected to amqp://***:**@***:***/***
[2018-06-25 02:46:10,212: INFO/MainProcess] mingle: searching for neighbors
[2018-06-25 02:46:10,291: WARNING/MainProcess] consumer: Connection to broker lost. Trying to re-establish the connection...
Traceback (most recent call last):
  File "/app/.heroku/python/lib/python3.6/site-packages/celery/worker/consumer/consumer.py", line 316, in start
    blueprint.start(self)
  File "/app/.heroku/python/lib/python3.6/site-packages/celery/bootsteps.py", line 119, in start
    step.start(parent)
  File "/app/.heroku/python/lib/python3.6/site-packages/celery/worker/consumer/mingle.py", line 40, in start
    self.sync(c)
  File "/app/.heroku/python/lib/python3.6/site-packages/celery/worker/consumer/mingle.py", line 44, in sync
    replies = self.send_hello(c)
  File "/app/.heroku/python/lib/python3.6/site-packages/celery/worker/consumer/mingle.py", line 57, in send_hello
    replies = inspect.hello(c.hostname, our_revoked._data) or {}
  File "/app/.heroku/python/lib/python3.6/site-packages/celery/app/control.py", line 132, in hello
    return self._request('hello', from_node=from_node, revoked=revoked)
  File "/app/.heroku/python/lib/python3.6/site-packages/celery/app/control.py", line 84, in _request
    timeout=self.timeout, reply=True,
  File "/app/.heroku/python/lib/python3.6/site-packages/celery/app/control.py", line 439, in broadcast
    limit, callback, channel=channel,
  File "/app/.heroku/python/lib/python3.6/site-packages/kombu/pidbox.py", line 315, in _broadcast
    serializer=serializer)
  File "/app/.heroku/python/lib/python3.6/site-packages/kombu/pidbox.py", line 290, in _publish
    serializer=serializer,
  File "/app/.heroku/python/lib/python3.6/site-packages/kombu/messaging.py", line 181, in publish
    exchange_name, declare,
  File "/app/.heroku/python/lib/python3.6/site-packages/kombu/messaging.py", line 203, in _publish
    mandatory=mandatory, immediate=immediate,
  File "/app/.heroku/python/lib/python3.6/site-packages/amqp/channel.py", line 1732, in _basic_publish
    (0, exchange, routing_key, mandatory, immediate), msg
  File "/app/.heroku/python/lib/python3.6/site-packages/amqp/abstract_channel.py", line 50, in send_method
    conn.frame_writer(1, self.channel_id, sig, args, content)
  File "/app/.heroku/python/lib/python3.6/site-packages/amqp/method_framing.py", line 166, in write_frame
    write(view[:offset])
  File "/app/.heroku/python/lib/python3.6/site-packages/amqp/transport.py", line 275, in write
    self._write(s)
ConnectionResetError: [Errno 104] Connection reset by peer
[2018-06-25 02:46:10,375: INFO/MainProcess] Connected to amqp://***:**@***:***/***
[2018-06-25 02:46:10,526: INFO/MainProcess] mingle: searching for neighbors
[2018-06-25 02:46:11,764: INFO/MainProcess] mingle: all alone

على الرغم من أنني تحققت من السجلات ، وجدت سجلاً لإعادة الاتصال في توقيت تسرب الذاكرة ، ولكن كانت هناك أيضًا حالة بدأ فيها تسرب للذاكرة في التوقيت الذي لم يحدث فيه إعادة الاتصال.
أنا أتفق مع فكرة jxlton.

أيضًا ، عندما كنت أستخدم Celery 3.x ، لم أواجه مثل هذه المشكلة.

نفس المشكلة هنا
screenshot 2018-06-25 11 09 22
كل بضعة أيام يجب علي إعادة تشغيل العمال بسبب هذه المشكلة
لا توجد أي أدلة مهمة في السجلات ، لكن لدي شك في أن إعادة الاتصال يمكن أن تؤثر ؛ منذ أن أعدت توصيل إدخالات السجل في مكان ما في الوقت المناسب عندما تبدأ الذاكرة في النمو باستمرار
أكون بلدي هو أوبونتو 17 ، خادم واحد - عامل واحد مع 3 التزامن ؛ أرنب وريديس على الواجهة الخلفية ؛ جميع الحزم هي أحدث الإصدارات

marvelph @ dmitry-kostin ، هل يمكنك من فضلك تقديم التكوين الدقيق الخاص بك (مع حذف المعلومات الحساسة بالطبع) وربما مهمة أو

التكوين قريب من الافتراضي

الواردات = ('app.tasks'،)
result_persistent = صحيح
Task_ignore_result = خطأ
Task_acks_late = صحيح
worker_concurrency = 3
worker_prefetch_multiplier = 4
enable_utc = صحيح
المنطقة الزمنية = "أوروبا / موسكو"
broker_transport_options = {'visibility_timeout': 3600، 'Confirm_publish': True، 'fanout_prefix': True، 'fanout_patterns': True}

screenshot 2018-06-25 11 35 17
هذه هي في الأساس عقدة منشورة جديدة ؛ تم نشره في 21/06 18-50 ؛ حدقت لتنمو 6/23 حوالي الساعة 05-00 وتحطمت في النهاية 6/23 حوالي 23-00

المهمة بسيطة جدًا ولا يوجد منطق فائق هناك ، أعتقد أنه يمكنني إعادة إنتاج الموقف بأكمله في مشروع مؤقت واضح ولكن ليس لدي وقت فراغ في الوقت الحالي ، إذا كنت محظوظًا ، فسأحاول تقديم مثال كامل في عطلة نهاية الأسبوع

محدث
كما ترى ، فإن المهمة نفسها تستهلك بعض الذاكرة ، يمكنك رؤيتها من خلال الارتفاعات المفاجئة على الرسم البياني ، ولكن الوقت الذي بدأت فيه الذاكرة في التسرب لم يتم إنتاج أي مهام أو أي أنشطة أخرى

marvelph @ dmitry- kostinjxltom لقد لاحظت أنك تستخدم Python3. هل تمانع في تمكين tracemalloc لهذه العملية؟ قد تحتاج إلى تصحيح عملية العامل على الرغم من تسجيل آثار تخصيص الذاكرة ، أخبرني إذا كنت بحاجة إلى مساعدة في ذلك.

georgepsarakis هل تقصد تمكين tracemalloc في إحصائيات العامل والسجل ، مثل أفضل 10 ملفات لاستخدام الذاكرة ، في فترة زمنية محددة مثل 5 دقائق؟

jxltom أعتقد أن شيئًا من هذا القبيل سيساعد في تحديد الجزء المسؤول من الكود. ماذا تعتقد؟

georgepsarakis لقد حاولت استخدام gdb و https://github.com/lmacken/pyrasite لحقن عملية تسرب الذاكرة وبدء التصحيح عبر tracemalloc. هذا هو أفضل 10 ملفات مع أعلى استخدام للذاكرة.

أستخدم resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024 ويتزايد استخدام الذاكرة بشكل تدريجي بالفعل.

>>> import tracemalloc
>>> 
>>> tracemalloc.start()
>>> snapshot = tracemalloc.take_snapshot()
>>> top_stats = snapshot.statistics('lineno')
>>> for stat in top_stats[:10]:
...     print(stat)
... 
/app/.heroku/python/lib/python3.6/site-packages/kombu/utils/eventio.py:84: size=12.0 KiB, count=1, average=12.0 KiB
/app/.heroku/python/lib/python3.6/site-packages/celery/worker/heartbeat.py:47: size=3520 B, count=8, average=440 B
/app/.heroku/python/lib/python3.6/site-packages/amqp/method_framing.py:166: size=3264 B, count=12, average=272 B
/app/.heroku/python/lib/python3.6/site-packages/celery/events/dispatcher.py:142: size=3060 B, count=10, average=306 B
/app/.heroku/python/lib/python3.6/site-packages/celery/events/dispatcher.py:157: size=2912 B, count=8, average=364 B
/app/.heroku/python/lib/python3.6/site-packages/amqp/abstract_channel.py:50: size=2912 B, count=8, average=364 B
/app/.heroku/python/lib/python3.6/site-packages/kombu/messaging.py:181: size=2816 B, count=12, average=235 B
/app/.heroku/python/lib/python3.6/site-packages/kombu/messaging.py:203: size=2816 B, count=8, average=352 B
/app/.heroku/python/lib/python3.6/site-packages/celery/events/dispatcher.py:199: size=2672 B, count=6, average=445 B
/app/.heroku/python/lib/python3.6/site-packages/amqp/channel.py:1734: size=2592 B, count=8, average=324 B

هذا هو الفرق بين لقطتين بعد حوالي 5 دقائق.

>>> snapshot2 = tracemalloc.take_snapshot()
>>> top_stats = snapshot2.compare_to(snapshot, 'lineno')
>>> print("[ Top 10 differences ]")
[ Top 10 differences ]

>>> for stat in top_stats[:10]:
...     print(stat)
... 
/app/.heroku/python/lib/python3.6/site-packages/celery/worker/heartbeat.py:47: size=220 KiB (+216 KiB), count=513 (+505), average=439 B
/app/.heroku/python/lib/python3.6/site-packages/celery/events/dispatcher.py:142: size=211 KiB (+208 KiB), count=758 (+748), average=285 B
/app/.heroku/python/lib/python3.6/site-packages/amqp/method_framing.py:166: size=210 KiB (+206 KiB), count=789 (+777), average=272 B
/app/.heroku/python/lib/python3.6/site-packages/celery/events/dispatcher.py:157: size=190 KiB (+187 KiB), count=530 (+522), average=366 B
/app/.heroku/python/lib/python3.6/site-packages/amqp/abstract_channel.py:50: size=186 KiB (+183 KiB), count=524 (+516), average=363 B
/app/.heroku/python/lib/python3.6/site-packages/celery/events/dispatcher.py:199: size=185 KiB (+182 KiB), count=490 (+484), average=386 B
/app/.heroku/python/lib/python3.6/site-packages/kombu/messaging.py:203: size=182 KiB (+179 KiB), count=528 (+520), average=353 B
/app/.heroku/python/lib/python3.6/site-packages/kombu/messaging.py:181: size=179 KiB (+176 KiB), count=786 (+774), average=233 B
/app/.heroku/python/lib/python3.6/site-packages/amqp/channel.py:1734: size=165 KiB (+163 KiB), count=525 (+517), average=323 B
/app/.heroku/python/lib/python3.6/site-packages/kombu/async/hub.py:293: size=157 KiB (+155 KiB), count=255 (+251), average=632 B

أي اقتراحات لكيفية الاستمرار في تصحيح هذا؟ ليس لدي أدنى فكرة عن كيفية المضي قدما. شكرا.

تضمين التغريدة

أريد القليل من الوقت لقطع المشروع من أجل التكاثر.

إنه وضع الكرفس.

BROKER_URL = [
    'amqp://xxxxxxxx:[email protected]:5672/zzzzzzzz'
]
BROKER_TRANSPORT_OPTIONS = {}

المجدول لديه الإعدادات التالية.

CELERYBEAT_SCHEDULE = {
    'aaaaaaaa_bbbbbbbb': {
        'task': 'aaaa.bbbbbbbb_cccccccc',
        'schedule': celery.schedules.crontab(minute=0),
    },
    'dddddddd_eeeeeeee': {
        'task': 'dddd.eeeeeeee_ffffffff',
        'schedule': celery.schedules.crontab(minute=0),
    },
}

في EC 2 ، أستخدم المشرف لتشغيله.

تضمين التغريدة
نظرًا لأن بيئة الاختبار الخاصة بي يمكن أن تتسامح مع تدهور الأداء ، يمكنك استخدام tracemalloc.
هل يمكنك عمل كرفس مصحح لتفريغ استخدام الذاكرة؟

jxltom أراهن أن tracemalloc مع 5 دقائق لن يساعد في تحديد موقع المشكلة
على سبيل المثال ، لدي 5 عقد و 3 منها فقط واجهت هذه المشكلة خلال الأيام الأربعة الماضية ، وعملت 2 بشكل جيد كل هذا الوقت ، لذلك سيكون من الصعب جدًا تحديد موقع المشكلة ..
أشعر أن هناك بعض التبديل الذي يتم تشغيله ثم تبدأ الذاكرة في النمو ، حتى يبدو استهلاك ذاكرة التبديل هذا جيدًا جدًا

حاولت معرفة ما إذا كانت هناك مشكلات مماثلة حدثت في أنظمة تشغيل أخرى.
يختلف تكرار الحدوث ، ولكن حدث تسرب للذاكرة على ثلاثة أنظمة تستخدم Celery 4.x ، ولم يحدث ذلك في نظام واحد.
النظام الذي يحتوي على تسرب للذاكرة هو Python 3.5.x ، والنظام الذي لا يحتوي على تسرب للذاكرة هو Python 2.7.x.

@ dmitry-kostin ما الفرق مع العقدتين العاديتين الأخريين ، هل كلاهما يستخدم نفس rabbitmq كوسيط؟

نظرًا لأن مناقشتنا ذكرت أنها قد تتعلق بـ rabbitmq ، فقد بدأت عقدة جديدة أخرى بنفس التكوين باستثناء استخدام redis بدلاً من ذلك. حتى الآن ، لا يوجد تسرب للذاكرة في هذه العقدة بعد تشغيلها لمدة 24 ساعة. سأقوم بنشره هنا إذا كان به تسرب للذاكرة لاحقًا

marvelph فهل تقصد أن النظام الثلاثة الذي يحتوي على تسرب للذاكرة يستخدم python3 بينما النظام الجيد يستخدم python2؟

jxltom لا فرق على الإطلاق ، ونعم هم على Python 3 & rabit كوسيط و redis على الواجهة الخلفية
لقد قمت بعمل مثال اختبار لإعادة إنتاج هذا ، إذا نجح في غضون يومين ، فسأقدم بيانات اعتماد لهذه الخوادم لشخص يدرك كيفية تحديد موقع هذا الخطأ

تضمين التغريدة
نعم.
بقدر ما يتعلق الأمر ببيئتي ، لا تحدث المشكلات في Python 2.

لقد تتبعت تسرب الذاكرة عبر tracemalloc خلال فترة أطول.

استخدام ذاكرة البدء الذي تم تسجيله بواسطة الوحدة النمطية resource هو 146.58MB ، بعد 3.5 ساعة ، يبلغ استخدام الذاكرة 224.21MB .

فيما يلي اختلاف اللقطة الذي تم الإبلاغ عنه بواسطة tracemalloc

>>> snapshot2 = tracemalloc.take_snapshot(); top_stats = snapshot2.compare_to(snapshot, 'lineno')
>>> for stat in top_stats[:10]:
...     print(stat)
... 
/app/.heroku/python/lib/python3.6/site-packages/celery/worker/heartbeat.py:47: size=3619 KiB (+3614 KiB), count=8436 (+8426), average=439 B
/app/.heroku/python/lib/python3.6/site-packages/celery/events/dispatcher.py:142: size=3470 KiB (+3466 KiB), count=12529 (+12514), average=284 B
/app/.heroku/python/lib/python3.6/site-packages/amqp/method_framing.py:166: size=3418 KiB (+3414 KiB), count=12920 (+12905), average=271 B
/app/.heroku/python/lib/python3.6/site-packages/celery/events/dispatcher.py:157: size=3149 KiB (+3145 KiB), count=8762 (+8752), average=368 B
/app/.heroku/python/lib/python3.6/site-packages/amqp/abstract_channel.py:50: size=3099 KiB (+3096 KiB), count=8685 (+8676), average=365 B
/app/.heroku/python/lib/python3.6/site-packages/celery/events/dispatcher.py:199: size=3077 KiB (+3074 KiB), count=8354 (+8345), average=377 B
/app/.heroku/python/lib/python3.6/site-packages/kombu/messaging.py:203: size=3020 KiB (+3017 KiB), count=8723 (+8713), average=355 B
/app/.heroku/python/lib/python3.6/site-packages/kombu/messaging.py:181: size=2962 KiB (+2959 KiB), count=12952 (+12937), average=234 B
/app/.heroku/python/lib/python3.6/site-packages/amqp/channel.py:1734: size=2722 KiB (+2718 KiB), count=8623 (+8613), average=323 B
/app/.heroku/python/lib/python3.6/site-packages/kombu/async/hub.py:293: size=2588 KiB (+2585 KiB), count=4193 (+4188), average=632 B

أيه أفكار؟ يبدو أنه ليس ملف واحد يتسرب؟

لقد قمت أيضًا باستيراد gc ، و gc.collect() إرجاع 0 ...

georgepsarakis لقد تمكنت من إعادة إنتاج هذا الأمر ، قم

تحديث: لقد قمت بتحديث الوسيط من rabbitmq إلى redis عن طريق تحديث عنوان url الخاص بالوسيط كمتغير بيئة والحفاظ على عامل الإرساء / الكود كما هو تمامًا. وهي تعمل لمدة 4 أيام ولا يوجد تسرب للذاكرة .

لذلك أعتقد أن هذه المشكلة مرتبطة بسمسار rabbitmq.

إذا كان ذلك ممكنًا ، يرجى محاولة تشغيل الأمر المعياري المذكور هنا: https://github.com/celery/celery/issues/2927#issuecomment -171455414

يعمل هذا النظام على تشغيل 20 خادمًا.
حدث تسرب للذاكرة بالأمس ، لكنه يحدث على جميع الخوادم تقريبًا في نفس الوقت.
memoryleak

لا أعرف ما إذا كان الأمر متعلقًا أم لا ، اتركه هنا في حال كان ذلك مفيدًا.

لدي مشكلة مختلفة مع الكرفس و rabbitmq (يفقد الكرفس الاتصال ويبدأ في إعادة توصيل الكثير من المرات في الثانية ، وحدة المعالجة المركزية تعمل بنسبة 100٪ على نواة واحدة ، ولا يمكن للفوز إرسال مهام جديدة ، وتحتاج إلى إعادة تشغيل الكرفس).

السبب في أنني أبلغ عن هذا هنا هو المشغل: بعد أيام من المراقبة ، أعتقد أنني حددت بداية المشكلة ويبدو أن rabbitmq ينقل بعض الرسائل من الذاكرة إلى القرص. في ذلك الوقت ، يبدأ الكرفس في محاولة إعادة الاتصال بأسرع ما يمكن ، وتظهر سجلات rabbitmq عشرات عمليات الاتصال / قطع الاتصال في الثانية ، على دفعات من حوالي 10 أو نحو ذلك في المرة الواحدة. لا تؤدي إعادة تشغيل rabbitmq إلى حل المشكلة ، حيث تعمل إعادة تشغيل الكرفس على إصلاحها على الفور. ليس لدي حل مناسب ولكن على سبيل المثال ، وضع سياسة انتهاء الصلاحية تسمح للرسائل بالبقاء دائمًا في الذاكرة يعمل على حل المشكلة ولم أرها منذ ذلك الحين.

بالنظر إلى بعض تفاصيل هذه المشكلة تتطابق مع ما رأيته (تبديل rabbitmq مع redis يعمل على إصلاحه ، لا توجد نقطة بداية واضحة ، يحدث ذلك على أكثر من عامل / خادم واحد في نفس الوقت) أعتقد أنه قد يكون هناك مشغل شائع وقد يكون تكون هي نفسها التي رصدتها.

تم تغيير مجموعة الاختبار من https://github.com/celery/celery/tree/master/funtests/stress إلى https://github.com/celery/cyanide ، وهي تدعم Python2 فقط.

لذلك قمت بتشغيله في Python2 مع rabbitmq كوسيط. لقد جمعت !join: connection lost: error(104, 'Connection reset by peer') . هل هذا مرتبط بمشكلة تسرب الذاكرة؟

هنا سجل مجموعة الاختبار.

➜  cyanide git:(master) pipenv run python -m cyanide.bin.cyanide
Loading .env environment variables…
Cyanide v1.3.0 [celery 4.2.0 (windowlicker)]

Linux-4.13.0-45-generic-x86_64-with-debian-stretch-sid

[config]
.> app:    cyanide:0x7fb097f31710
.> broker: amqp://**:**@**:**/cyanide
.> suite: cyanide.suites.default:Default

[toc: 12 tests total]
.> 1) manyshort,
.> 2) always_timeout,
.> 3) termbysig,
.> 4) timelimits,
.> 5) timelimits_soft,
.> 6) alwayskilled,
.> 7) alwaysexits,
.> 8) bigtasksbigvalue,
.> 9) bigtasks,
.> 10) smalltasks,
.> 11) revoketermfast,
.> 12) revoketermslow

+enable worker task events...
+suite start (repetition 1)
[[[manyshort(50)]]]
 1: manyshort                            OK (1/50) rep#1 runtime: 15.00 seconds/15.01 seconds
 1: manyshort                            OK (2/50) rep#1 runtime: 13.16 seconds/28.17 seconds
 1: manyshort                            OK (3/50) rep#1 runtime: 13.29 seconds/41.46 seconds
 1: manyshort                            OK (4/50) rep#1 runtime: 13.70 seconds/55.16 seconds
 1: manyshort                            OK (5/50) rep#1 runtime: 13.77 seconds/1.15 minutes
 1: manyshort                            OK (6/50) rep#1 runtime: 13.91 seconds/1.38 minutes
!join: connection lost: error(104, 'Connection reset by peer')
!Still waiting for 1000/1000: [1624cd7a-3cc0-474a-b957-b0484f6b4937, 2b436525-73de-4062-bd6b-924cbd11ba74, ce04cb5e-a99e-41e2-95dc-e9bc351e606d,...]: TimeoutError(u'The operation timed out.',)
!Still waiting for 1000/1000: [1624cd7a-3cc0-474a-b957-b0484f6b4937, 2b436525-73de-4062-bd6b-924cbd11ba74, ce04cb5e-a99e-41e2-95dc-e9bc351e606d,...]: TimeoutError(u'The operation timed out.',)
!Still waiting for 475/1000: [1624cd7a-3cc0-474a-b957-b0484f6b4937, 2b436525-73de-4062-bd6b-924cbd11ba74, ce04cb5e-a99e-41e2-95dc-e9bc351e606d,...]: TimeoutError(u'The operation timed out.',)
!Still waiting for 1000/1000: [1624cd7a-3cc0-474a-b957-b0484f6b4937, 2b436525-73de-4062-bd6b-924cbd11ba74, ce04cb5e-a99e-41e2-95dc-e9bc351e606d,...]: TimeoutError(u'The operation timed out.',)
!Still waiting for 1000/1000: [1624cd7a-3cc0-474a-b957-b0484f6b4937, 2b436525-73de-4062-bd6b-924cbd11ba74, ce04cb5e-a99e-41e2-95dc-e9bc351e606d,...]: TimeoutError(u'The operation timed out.',)
!Still waiting for 475/1000: [1624cd7a-3cc0-474a-b957-b0484f6b4937, 2b436525-73de-4062-bd6b-924cbd11ba74, ce04cb5e-a99e-41e2-95dc-e9bc351e606d,...]: TimeoutError(u'The operation timed out.',)
!Still waiting for 1000/1000: [1624cd7a-3cc0-474a-b957-b0484f6b4937, 2b436525-73de-4062-bd6b-924cbd11ba74, ce04cb5e-a99e-41e2-95dc-e9bc351e606d,...]: TimeoutError(u'The operation timed out.',)
!Still waiting for 1000/1000: [1624cd7a-3cc0-474a-b957-b0484f6b4937, 2b436525-73de-4062-bd6b-924cbd11ba74, ce04cb5e-a99e-41e2-95dc-e9bc351e606d,...]: TimeoutError(u'The operation timed out.',)
!join: connection lost: error(104, 'Connection reset by peer')
failed after 7 iterations in 3.12 minutes
Traceback (most recent call last):
  File "/home/***/.pyenv/versions/2.7.15/lib/python2.7/runpy.py", line 174, in _run_module_as_main
    "__main__", fname, loader, pkg_name)
  File "/home/***/.pyenv/versions/2.7.15/lib/python2.7/runpy.py", line 72, in _run_code
    exec code in run_globals
  File "/home/***/Documents/Python-Dev/cyanide/cyanide/bin/cyanide.py", line 62, in <module>
    main()
  File "/home/***/Documents/Python-Dev/cyanide/cyanide/bin/cyanide.py", line 58, in main
    return cyanide().execute_from_commandline(argv=argv)
  File "/home/***/.local/share/virtualenvs/cyanide-Vy3PQPTU/lib/python2.7/site-packages/celery/bin/base.py", line 275, in execute_from_commandline
    return self.handle_argv(self.prog_name, argv[1:])
  File "/home/***/.local/share/virtualenvs/cyanide-Vy3PQPTU/lib/python2.7/site-packages/celery/bin/base.py", line 363, in handle_argv
    return self(*args, **options)
  File "/home/***/.local/share/virtualenvs/cyanide-Vy3PQPTU/lib/python2.7/site-packages/celery/bin/base.py", line 238, in __call__
    ret = self.run(*args, **kwargs)
  File "/home/***/Documents/Python-Dev/cyanide/cyanide/bin/cyanide.py", line 20, in run
    return self.run_suite(names, **options)
  File "/home/***/Documents/Python-Dev/cyanide/cyanide/bin/cyanide.py", line 30, in run_suite
    ).run(names, **options)
  File "cyanide/suite.py", line 366, in run
    self.runtest(test, iterations, j + 1, i + 1)
  File "cyanide/suite.py", line 426, in runtest
    self.execute_test(fun)
  File "cyanide/suite.py", line 447, in execute_test
    fun()
  File "cyanide/suites/default.py", line 22, in manyshort
    timeout=10, propagate=True)
  File "cyanide/suite.py", line 246, in join
    raise self.TaskPredicate('Test failed: Missing task results')
cyanide.suite.StopSuite: Test failed: Missing task results

هنا سجل للعامل.

➜  cyanide git:(master) pipenv run celery -A cyanide worker -c 1
Loading .env environment variables…

 -------------- celery@** v4.2.0 (windowlicker)
---- **** ----- 
--- * ***  * -- Linux-4.13.0-45-generic-x86_64-with-debian-stretch-sid 2018-07-03 12:59:28
-- * - **** --- 
- ** ---------- [config]
- ** ---------- .> app:         cyanide:0x7fdc988b4e90
- ** ---------- .> transport:   amqp://**:**@**:**/cyanide
- ** ---------- .> results:     rpc://
- *** --- * --- .> concurrency: 1 (prefork)
-- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker)
--- ***** ----- 
 -------------- [queues]
                .> c.stress         exchange=c.stress(direct) key=c.stress


[2018-07-03 12:59:29,883: WARNING/ForkPoolWorker-1] ! Still waiting for 1000/1000: [e6e71bed-8e58-4e7e-96c5-f56b583a37af, 42fd4f97-4ff5-4e0e-b874-89e7b3f0ff22, 3de45eeb-9b89-41bc-8284-95a4c07aa34a,...]: TimeoutError('The operation timed out.',) !
[2018-07-03 12:59:29,886: WARNING/ForkPoolWorker-1] ! Still waiting for 1000/1000: [e6e71bed-8e58-4e7e-96c5-f56b583a37af, 42fd4f97-4ff5-4e0e-b874-89e7b3f0ff22, 3de45eeb-9b89-41bc-8284-95a4c07aa34a,...]: TimeoutError('The operation timed out.',) !
[2018-07-03 12:59:30,964: WARNING/ForkPoolWorker-1] + suite start (repetition 1) +
[2018-07-03 12:59:30,975: WARNING/ForkPoolWorker-1] ---  1: manyshort                             (0/50) rep#1 runtime: 0.0000/0.0000 ---
[2018-07-03 13:01:07,835: WARNING/ForkPoolWorker-1] ! join: connection lost: error(104, 'Connection reset by peer') !
[2018-07-03 13:01:17,918: WARNING/ForkPoolWorker-1] ! Still waiting for 1000/1000: [1624cd7a-3cc0-474a-b957-b0484f6b4937, 2b436525-73de-4062-bd6b-924cbd11ba74, ce04cb5e-a99e-41e2-95dc-e9bc351e606d,...]: TimeoutError(u'The operation timed out.',) !
[2018-07-03 13:01:27,951: WARNING/ForkPoolWorker-1] ! Still waiting for 1000/1000: [1624cd7a-3cc0-474a-b957-b0484f6b4937, 2b436525-73de-4062-bd6b-924cbd11ba74, ce04cb5e-a99e-41e2-95dc-e9bc351e606d,...]: TimeoutError(u'The operation timed out.',) !
[2018-07-03 13:01:38,902: WARNING/ForkPoolWorker-1] ! Still waiting for 475/1000: [1624cd7a-3cc0-474a-b957-b0484f6b4937, 2b436525-73de-4062-bd6b-924cbd11ba74, ce04cb5e-a99e-41e2-95dc-e9bc351e606d,...]: TimeoutError(u'The operation timed out.',) !
[2018-07-03 13:01:48,934: WARNING/ForkPoolWorker-1] ! Still waiting for 1000/1000: [1624cd7a-3cc0-474a-b957-b0484f6b4937, 2b436525-73de-4062-bd6b-924cbd11ba74, ce04cb5e-a99e-41e2-95dc-e9bc351e606d,...]: TimeoutError(u'The operation timed out.',) !
[2018-07-03 13:01:58,961: WARNING/ForkPoolWorker-1] ! Still waiting for 1000/1000: [1624cd7a-3cc0-474a-b957-b0484f6b4937, 2b436525-73de-4062-bd6b-924cbd11ba74, ce04cb5e-a99e-41e2-95dc-e9bc351e606d,...]: TimeoutError(u'The operation timed out.',) !
[2018-07-03 13:02:09,906: WARNING/ForkPoolWorker-1] ! Still waiting for 475/1000: [1624cd7a-3cc0-474a-b957-b0484f6b4937, 2b436525-73de-4062-bd6b-924cbd11ba74, ce04cb5e-a99e-41e2-95dc-e9bc351e606d,...]: TimeoutError(u'The operation timed out.',) !
[2018-07-03 13:02:19,934: WARNING/ForkPoolWorker-1] ! Still waiting for 1000/1000: [1624cd7a-3cc0-474a-b957-b0484f6b4937, 2b436525-73de-4062-bd6b-924cbd11ba74, ce04cb5e-a99e-41e2-95dc-e9bc351e606d,...]: TimeoutError(u'The operation timed out.',) !
[2018-07-03 13:02:29,964: WARNING/ForkPoolWorker-1] ! Still waiting for 1000/1000: [1624cd7a-3cc0-474a-b957-b0484f6b4937, 2b436525-73de-4062-bd6b-924cbd11ba74, ce04cb5e-a99e-41e2-95dc-e9bc351e606d,...]: TimeoutError(u'The operation timed out.',) !
[2018-07-03 13:02:37,900: WARNING/ForkPoolWorker-1] ! join: connection lost: error(104, 'Connection reset by peer') !

لقد قمت بالتحديث لاستخدام الكرفس 3.1.25 مع نفس مجموعة اختبار التحمل ، كل شيء على ما يرام.

راجع للشغل لكل من يبحث عن حل سريع - استبدال الأرنب بـ redis يحل المشكلة كما اقترح jxltom ، لدي أكثر من أسبوع من العمل المستقر مع redis الآن فقط
لذا فإن المشكلة تكمن بالتأكيد في مكان ما بالقرب من حدود الكرفس <-> الأرنب

dieeasy لقد واجهنا نفس المشكلة. أفترض أنك تستخدم الواجهة الخلفية لنتائج RPC. إذا كان الأمر كذلك ، فحاول التبديل إلى الخلفية الخلفية لنتيجة قاعدة البيانات ومعرفة ما إذا كان ذلك يساعدك. المشكلة التي تسبب ذلك هي: https://github.com/celery/kombu/pull/779 وموضحة هنا: https://github.com/celery/kombu/pull/779#discussion_r134961611

لدي نفس مشكلة تسرب الذاكرة
ذاكرة
image

إصدار
python 3.6.5 celery 4.2.1 الخلفية redis وسيط rabbitmq

التكوين

[celery]
broker_url=amqp://taunt:[email protected]:5672/%2ftaunt
celery_result_backend=redis://xx.xx.xx.xx:6379
# 7days
celery_task_result_expires=604800
celery_task_serializer=msgpack
celery_result_serializer=json
celery_accept_content=json,msgpack
celery_timezone=Asia/Shanghai
celery_enable_utc=True

[cmd]
worker=True
proj=app.worker.celery
log_level=INFO
name=send_im%%h
queue=im
autoscale=10,3
concurrency=10

"" الثعبان

- - الترميز: utf-8 - -

من kombu import Queue، Exchange
من سجل الاستيراد oslo_log كتسجيل

من app.conf استيراد CONF

LOG = logging.getLogger (__ name__)

الكرفس = (
قائمة الانتظار ('im'، exchange = Exchange ('sender')، routing_key = 'im')،
قائمة الانتظار ('sms' ، exchange = Exchange ('sender') ، routing_key = 'sms') ،
قائمة الانتظار ('mail' ، exchange = Exchange ('sender') ، routing_key = 'mail') ،
قائمة الانتظار ('ivr' ، exchange = Exchange ('sender') ، routing_key = 'ivr')
)

celery_routes = {
'sender.im': {'queue': 'im'، 'routing_key': 'im'}،
'sender.sms': {'queue': 'sms'، 'routing_key': 'sms'}،
'sender.mail': {'queue': 'mail'، 'routing_key': 'mail'}،
'sender.ivr': {'queue': 'ivr'، 'routing_key': 'ivr'}
}

التكوين = {
"BROKER_URL": CONF.celery.broker_url ،
"CELERY_RESULT_BACKEND": CONF.celery.celery_result_backend ،
"CELERY_TASK_RESULT_EXPIRES": CONF.celery.celery_task_result_expires،
"CELERY_TASK_SERIALIZER": CONF.celery.celery_task_serializer ،
"CELERY_RESULT_SERIALIZER": CONF.celery.celery_result_serializer ،
'CELERY_ACCEPT_CONTENT': CONF.celery.celery_accept_content.split ('،')،
"CELERY_TIMEZONE": CONF.celery.celery_timezone ،
"CELERY_ENABLE_UTC": CONF.celery.celery_enable_utc ،
"CELERY_QUEUES": celery_queues ،
"CELERY_ROUTES": celery_routes
}

**Startup**
```python

def make_command() -> list:
    log_path = f'{CONF.log_dir}{os.sep}{CONF.log_file}'
    command_name = f'{sys.path[0]}{os.sep}celery'
    command = [command_name, 'worker', '-A', CONF.cmd.proj, '-E']
    if CONF.cmd.log_level:
        command.extend(['-l', CONF.cmd.log_level])
    if CONF.cmd.queue:
        command.extend(['-Q', CONF.cmd.queue])
    if CONF.cmd.name:
        command.extend(['-n', CONF.cmd.name])
    # if CONF.cmd.autoscale:
    #     command.extend(['--autoscale', CONF.cmd.autoscale])
    if CONF.cmd.concurrency:
        command.extend(['--concurrency', CONF.cmd.concurrency])
    command.extend(['-f', log_path]) 
    return command


if CONF.cmd.worker:
    LOG.info(make_command())
    entrypoint = celery.start(argv=make_command())

يمكنني تقديم المزيد من المعلومات إذا لزم الأمر.

بالنسبة لما يستحق ، أواجه هذه المشكلة ويمكنني إعادة إنتاجها باستمرار عن طريق فتح وحدة التحكم في إدارة rabbitmq ، والانتقال إلى الاتصالات ، وإغلاق الاتصالات بحركة المرور من الكرفس إلى rabbitmq.

لقد اختبرت مع الكرفس 4.1 و 4.2 و rabbitmq 3.7.7-1
تحرير: أيضًا إصدار python 3.6.5 و ubuntu 16.04 (صورة AWS EC2)

لدي تسرب في الذاكرة مع وسيط الكرفس 4.2.1 و redis. تنمو الذاكرة من 100 ميجابايت إلى 500 ميجابايت (محدودة) في 3 ساعات ، ويتم وضع علامة على العمال على أنهم غير متصلون بالإنترنت في الأزهار. يظهر كل من تجمع بريفورك وجيفينت نفس المشكلة.

yifeikong قد لا تكون هذه هي المشكلة نفسها ، ولكن بالنسبة لحالتك ، هل يمكنك تجربة الحل المقترح https://github.com/celery/celery/pull/4839#issuecomment -447739820؟

georgepsarakis أنا أستخدم Python 3.6.5 ، لذا فأنا لا

ربما نفس السبب مع # 5047 ، يبدو أن هذا الخطأ يمكن أن يؤدي إلى ظاهرة مختلفة.

نحن نواجه نفس تسرب الذاكرة بتشغيل Celery 4.2.1 و Kombu 4.2.2 و python3.6 مع RabbitMQ كوسيط.

$ celery --app=eventr.celery_app report

software -> celery:4.2.1 (windowlicker) kombu:4.2.2-post1 py:3.6.8
            billiard:3.5.0.5 py-amqp:2.4.0
platform -> system:Linux arch:64bit imp:CPython

أستطيع أن أقول إننا جربنا العديد من الأشياء التي ذكرها الآخرون كحلول محتملة (redis كوسيط ، باستخدام jemalloc ، libamqp ، مسار القرد __del__ على AsyncResult ) ولكن انتهى بنا الأمر دائمًا إلى تسريب الذاكرة.

من خلال تحليل سجلنا ، لاحظنا أن لدينا الكثير من الرسائل المتعلقة بنبضات القلب المفقودة من القيل والقال.

{"asctime": "2019-01-25 13:40:06,486", "levelname": "INFO", "name": "celery.worker.consumer.gossip", "funcName": "on_node_lost", "lineno": 147, "message": "missed heartbeat from celery@******"}

آخر شيء جربناه هو تعطيل النميمة عن طريق تشغيل العمال --without-gossip ، ومن المدهش أن تعطيل النميمة كان له تأثير فوري.

يمكنك أن ترى هنا:
celery-memory-14d

منذ أن قمنا بإلغاء تنشيط النميمة في مشروعين يديران عمال الكرفس ، تحسن استهلاك الذاكرة.

إذا انتبهت ، قبل أن نشهد ارتفاعات ذاكرة مماثلة كما هو موضح هنا https://github.com/celery/celery/issues/4843#issuecomment -399833781

أحد الأشياء التي كنت أحاول فهمها تمامًا هو ما هي الآثار المترتبة على التعطيل التام للقيل والقال ، نظرًا لأنه يتم وصفه فقط بأنه اتصال عامل <-> ، إذا تمكن أي شخص من إلقاء بعض الضوء على هذا الأمر ، فسأكون ممتنًا للغاية.

أتمنى أن يساعد هذا وشكرا على العمل الشاق.

لماذا تم إغلاق هذه القضية؟

هناك ملاحظات نشطة واهتمام بهذه المشكلة ، لذا فأنا أعيد فتح الباب.

حسنًا ، georgepsarakis نظرًا لأننا قمنا بتشخيص التسريب الخاص بي على أنه ليس # 4839 ، وكنت تشك في أنه كان # 4843 ، سأنتقل إلى سلسلة التسريب هذه على الأقل في الوقت الحالي. لست متأكدًا من أن # 4843 هو التسريب أيضًا. وفقًا للإصدار الأولي في هذا الموضوع:

تحدث هذه المشكلة على الأقل في الكرفس 4.1 ، وتحدث أيضًا في الكرفس 4.2.
يعمل الكرفس على Ubuntu 16 ويستخدم السماسرة RabbitMQ.

انا حاليا على:

بيثون 2.7.12
نظام التشغيل Ubuntu 16.04.1 amd64
RabbitMQ 3.7.5

استخدام:

الكرفس 4.1.1
librabbitmq 2.0.0
amqp 2.4.0
الكرمة 1.1.4
بلياردو 3.5.0.5
كومبو 4.2.2.post1
gevent 1.2.2

ومع ذلك ، فإن الكرفس 4.1.1 + gevent 1.2.2 لا يتسرب بالنسبة لي (ولا الكرفس 3.1.25 + gevent 1.2.2 AFAICT) ؛ الكرفس 4.2.1 + gevent 1.3.7 يفعل. لسوء الحظ ، فإن gevent 1.3.7 و gevent 1.2.2 غير قابلين للتبديل لإثبات (أو استبعاد) مكتبة gevent كمصدر محتمل للمشكلة.

تحرير: حسنًا ... يبدو أن هناك تصحيحًا gevent (022f447dd) يبدو أنه يمكنه إصلاح الخطأ الذي واجهته. سأحاول أن أجعل ذلك يعمل.

قمت بتطبيق 022f447 على الكرفس 4.1.1 وقمت بتثبيت برنامج gevent 1.3.7. تم تشغيل تركيبة Celery + gevent ... وأنتجت أنماط استخدام للذاكرة متوافقة مع التسرب الذي كنت أواجهه. سأقوم بتثبيت Celery 4.2.1 + gevent 1.2.2 (مع التصحيح العكسي) ومعرفة ما إذا كنت أحصل على نمط استخدام الذاكرة المعتاد.

لقد لاحظت إصدار gevent 1.4.0. ربما يجب أن أعطي هذه الدوامة أيضًا لأرى كيف يتصرف ذلك.

لا يبدو أن الكرفس 4.2.1 + gevent 1.2.2 + التصحيح العكسي لـ gevent 1.2.2 ينتج عنه التسرب كما يفعل الكرفس 4.2.1 + gevent 1.3.7.

يبدو أن الكرفس 4.2.1 + gevent 1.4.0 يتسرب بنفس معدل التسرب تقريبًا مثل gevent 1.3.7 AFAICT.

https://github.com/celery/celery/blob/9f0a554dc2d28c630caf9d192873d040043b7346/celery/events/dispatcher.py

    def _publish(self, event, producer, routing_key, retry=False,
                 retry_policy=None, utcoffset=utcoffset):
        exchange = self.exchange
        try:
            producer.publish(...)
        except Exception as exc:  # pylint: disable=broad-except
            if not self.buffer_while_offline:  # <-- False by default
                raise
            self._outbound_buffer.append((event, routing_key, exc))  # <---- Always buffered

    def send(self, type, blind=False, utcoffset=utcoffset, retry=False,
            ...
            if group in self.buffer_group:   # <--- Never true for eventlet & gevent
                ...
                if len(buf) >= self.buffer_limit:
                    self.flush()     #  <---- Never flushed even when grows above limit
                ...
            else:
                return self.publish(type, fields, self.producer, blind=blind,
                                    Event=Event, retry=retry,

https://github.com/celery/celery/blob/b2668607c909c61becd151905b4525190c19ff4a/celery/worker/consumer/events.py

    def start(self, c):
        # flush events sent while connection was down.
        prev = self._close(c)
        dis = c.event_dispatcher = c.app.events.Dispatcher(
            ...
            # we currently only buffer events when the event loop is enabled
            # XXX This excludes eventlet/gevent, which should actually buffer.
            buffer_group=['task'] if c.hub else None,
            on_send_buffered=c.on_send_event_buffered if c.hub else None,
        )
        if prev:
            dis.extend_buffer(prev)
            dis.flush()    # <---- The only (!) chance to flush on [g]event[let] is on reconnect.

الآن ، إذا فهمت بشكل صحيح ما يفعله AMQP تحت الغطاء ، فعندئذ يكون له نبض قلبه الخاص وعندما يكتشف اتصالًا معطلًا ، فإنه يمضي قدمًا ويعيد الاتصال تحت الغطاء. اعتمادًا على أنواع الأحداث التي يتم تمكينها (القيل والقال ونبضات القلب) ، يمكن أن يتسرب هذا بسرعة كبيرة.
يجب أن يكون هذا صحيحًا بالنسبة لأي إصدار من الأحداث الصغيرة والجيفنت ، لكن قد يواجه البعض مشكلات اتصال تجعل الأمور أسوأ / أكثر وضوحًا.

أهلا،

أظن أننا نواجه نفس المشكلة.
التكوين لدينا أدناه. هل يمكنني رفض أو تأكيد أن هذه هي نفس المشكلة التي تمت مناقشتها هنا؟

بايثون: 2.7
الكرفس: 4.2.1
نظام التشغيل: إصدار CentOS 6.10
ريديس كوسيط

في الصورة المرفقة تستطيع أن ترى:

  1. يتزايد استهلاك الذاكرة باستمرار وينخفض ​​عند إعادة التشغيل.
  2. في 13 يناير - قمنا بالترقية من 3.1.25 إلى 4.2.1 من الكرفس. يزداد استهلاك الذاكرة بوتيرة متزايدة.

image

تحديث

بغض النظر عن هذه المشكلة ، قمنا بالترقية إلى python 3.6 ومنذ ذلك الحين يبدو أن التسريب لم يعد يحدث.

image
(كانت الترقية في 19 فبراير)

تضمين التغريدة

لست متأكدًا من مدى صلة ذلك ، لكنني أواجه 2 غيغابايت من مساحة SWAP التي استنفدها الكرفس في الإنتاج. توقف زهرة لم يمسح الذاكرة ، ولكن إيقاف الكرفس فعل ذلك.

هل يمكن لأي شخص أن يجرب الكرفس 4.3rc1؟

auvipy لقد قمت بتثبيت الكرفس 4.3.0rc1 + gevent 1.4.0. ترقية البلياردو بالنقطة إلى 3.6.0.0 و kombu 4.3.0.

نوع من الحيرة أن vine 1.2.0 لم تكن مطلوبة أيضًا بواسطة حزمة rc1 ، نظرًا لأن # 4839 تم إصلاحه من خلال تلك الترقية.

على أي حال ، يبدو أن الكرفس 4.3.0 rc1 يعمل بشكل جيد.

@ ldav1s شكرا جزيلا لملاحظاتك. لذلك ، تم إعلان كرمة على أنها تبعية في py-amqp في الواقع. في عمليات التثبيت الجديدة ، سيتم تثبيت أحدث إصدار من vine ولكن هذا قد لا يحدث في التثبيتات الحالية.

thedrow ربما يجب أن نعلن التبعية في متطلبات الكرفس أيضًا؟

دعونا نفتح قضية حول هذا الموضوع ونناقشها هناك.

يعمل الكرفس 4.3.0rc1 + gevent 1.4.0 منذ يومين. يبدو أنه يتسرب بنفس طريقة الكرفس 4.2.1 + gevent 1.4.0.

image

وجود نفس التسرب مع الكرفس 4.2.1 ، بيثون 3.6

أي تحديثات على هذا؟

تواجه نفس المشكلة هنا

تحيات،

أواجه مشكلة مماثلة ، لكنني لست متأكدًا من أنها هي نفسها.

بعد أن قمت بترحيل تطبيق الكرفس الخاص بنا في بيئة / شبكة مختلفة ، بدأ عمال الكرفس في التسريب. في السابق كان تطبيق الكرفس ومثيل rabbitmq في نفس البيئة / الشبكة.

تهيئتي على Python 3.6.5:

amqp (2.4.2)
billiard (3.5.0.5)
celery (4.1.1)
eventlet (0.22.0)
greenlet (0.4.15)
kombu (4.2.1)
vine (1.3.0)

الكرفس

broker_url = rabbitmq
result_backend = mongodb
task_acks_late = True
result_expires = 0
task_default_rate_limit = 2000
task_soft_time_limit = 120
task_reject_on_worker_lost = True
loglevel = 'INFO'
worker_pool_restarts = True
broker_heartbeat = 0
broker_pool_limit = None

يتكون التطبيق من عدة عمال مع Eventlet pool ، بدأ عن طريق الأمر في المشرف:

[program:worker1]
command={{ celery_path }} worker -A celery_app --workdir {{ env_path }} -l info -E -P eventlet -c 250 -n worker1@{{ hostname }} -Q queue1,queue2

يبدو سلوك تسرب الذاكرة على هذا النحو ، كل 10 ساعات تقريبًا عادة ما يبدأ عامل واحد ، بحد أقصى 2 يبدأ في التسريب:
image

لذلك قمت بإنشاء رسالة إذاعية ليتم تنفيذها على كل عامل ، لاستخدام tracemalloc ، هذه نتيجة لأمر علوي على الجهاز ، هناك عامل واحد فقط تسرب مع 1464m:

217m   1%   2   0% /usr/bin/python3 -m celery worker -A celery_app --workdir   379
189m   1%   0   0% /usr/bin/python3 -m celery worker -A celery_app --workdir   377     
1464m   9%   1   0% /usr/bin/python3 -m celery worker -A celery_app --workdir   378
218m   1%   0   0% /usr/bin/python3 -m celery worker -A celery_app --workdir   376 
217m   1%   2   0% /usr/bin/python3 -m celery worker -A celery_app --workdir   375
217m   1%   3   0% /usr/bin/python3 -m celery worker -A celery_app --workdir   394
163m   1%   0   0% /usr/bin/python3 -m celery beat -A celery_app --workdir /app

نتائج tracemalloc أعلى 10 على عامل التسريب

[2019-03-29 07:18:03,809: WARNING/MainProcess] [ Top 10: worker5<strong i="6">@hostname</strong> ]

[2019-03-29 07:18:03,809: WARNING/MainProcess] /usr/lib/python3.6/site-packages/eventlet/greenio/base.py:207: size=17.7 MiB, count=26389, average=702 B

[2019-03-29 07:18:03,810: WARNING/MainProcess] /usr/lib/python3.6/site-packages/kombu/messaging.py:203: size=16.3 MiB, count=44422, average=385 B

[2019-03-29 07:18:03,811: WARNING/MainProcess] /usr/lib/python3.6/site-packages/celery/worker/heartbeat.py:49: size=15.7 MiB, count=39431, average=418 B

[2019-03-29 07:18:03,812: WARNING/MainProcess] /usr/lib/python3.6/site-packages/celery/events/dispatcher.py:156: size=13.0 MiB, count=40760, average=334 B

[2019-03-29 07:18:03,812: WARNING/MainProcess] /usr/lib/python3.6/site-packages/eventlet/greenio/base.py:363: size=12.9 MiB, count=19507, average=695 B

[2019-03-29 07:18:03,813: WARNING/MainProcess] /usr/lib/python3.6/site-packages/amqp/transport.py:256: size=12.7 MiB, count=40443, average=328 B

[2019-03-29 07:18:03,814: WARNING/MainProcess] /usr/lib/python3.6/site-packages/celery/events/dispatcher.py:138: size=12.4 MiB, count=24189, average=539 B

[2019-03-29 07:18:03,814: WARNING/MainProcess] /usr/lib/python3.6/site-packages/amqp/transport.py:256: size=12.3 MiB, count=19771, average=655 B

[2019-03-29 07:18:03,815: WARNING/MainProcess] /usr/lib/python3.6/site-packages/amqp/connection.py:505: size=11.9 MiB, count=39514, average=317 B

[2019-03-29 07:18:03,816: WARNING/MainProcess] /usr/lib/python3.6/site-packages/kombu/messaging.py:181: size=11.8 MiB, count=61362, average=201 B

TOP 1 مع 25 لقطة

TOP 1

[2019-03-29 07:33:05,787: WARNING/MainProcess] [ TOP 1: worker5<strong i="10">@hostname</strong> ]

[2019-03-29 07:33:05,787: WARNING/MainProcess] 26938 memory blocks: 18457.2 KiB

[2019-03-29 07:33:05,788: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/eventlet/greenio/base.py", line 207

[2019-03-29 07:33:05,788: WARNING/MainProcess] mark_as_closed=self._mark_as_closed)

[2019-03-29 07:33:05,789: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/eventlet/greenio/base.py", line 328

[2019-03-29 07:33:05,789: WARNING/MainProcess] timeout_exc=socket_timeout('timed out'))

[2019-03-29 07:33:05,790: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/eventlet/greenio/base.py", line 357

[2019-03-29 07:33:05,790: WARNING/MainProcess] self._read_trampoline()

[2019-03-29 07:33:05,790: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/eventlet/greenio/base.py", line 363

[2019-03-29 07:33:05,791: WARNING/MainProcess] return self._recv_loop(self.fd.recv, b'', bufsize, flags)

[2019-03-29 07:33:05,791: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/amqp/transport.py", line 440

[2019-03-29 07:33:05,791: WARNING/MainProcess] s = recv(n - len(rbuf))

[2019-03-29 07:33:05,792: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/amqp/transport.py", line 256

[2019-03-29 07:33:05,792: WARNING/MainProcess] frame_header = read(7, True)

[2019-03-29 07:33:05,792: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/amqp/connection.py", line 505

[2019-03-29 07:33:05,793: WARNING/MainProcess] frame = self.transport.read_frame()

[2019-03-29 07:33:05,793: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/amqp/connection.py", line 500

[2019-03-29 07:33:05,793: WARNING/MainProcess] while not self.blocking_read(timeout):

[2019-03-29 07:33:05,793: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/kombu/transport/pyamqp.py", line 103

[2019-03-29 07:33:05,794: WARNING/MainProcess] return connection.drain_events(**kwargs)

[2019-03-29 07:33:05,794: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/kombu/connection.py", line 301

[2019-03-29 07:33:05,794: WARNING/MainProcess] return self.transport.drain_events(self.connection, **kwargs)

[2019-03-29 07:33:05,795: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/celery/worker/pidbox.py", line 120

[2019-03-29 07:33:05,795: WARNING/MainProcess] connection.drain_events(timeout=1.0)

آمل أن يساعد ذلك ، فلا يوجد خطأ في السجلات ، بخلاف ضربات القلب المفقودة بين العمال. الآن أحاول استخدام النسخة الدقيقة من libs التي كنا نستخدمها القديمة.

تحديث: باستخدام نفس إصدارات التبعيات الدقيقة ونبضات قلب الوسيط كل 5 دقائق ، بدا التطبيق مستقرًا لفترة أطول: أكثر من يومين ، مما تم تسريبه مرة أخرى.

كان هناك ارتفاع طفيف مستمر لمدة ساعة تقريبًا بمرور الوقت ، ولكن تم "امتصاص / تجميع" .. يبدو أن آخر ارتفاع بدأ في الارتفاع.

بعد الارتفاع الأول ، المنحدر الأول ، قمت بإعادة تشغيل عامل التسريب .. كما ترى بدأ عامل آخر في التسرب بعده أو ربما كان هناك تسرب بالفعل ، المنحدر الثاني.

image

سأقوم بالاختبار بدون ضربات قلب.

تحديث: بدون تسريب ضربات القلب مرة أخرى بعد يومين ، نفس السلوك

440m   3%   1   0% /usr/bin/python3 -m celery worker -A celery_app --without-heartbeat --workdir /app -l info -E -P eventlet -c 250 -Ofair -n worker1@ -Q p_1_queue,p_2_queue
176m   1%   0   0% /usr/bin/python3 -m celery worker -A celery_app --without-heartbeat --workdir /app -l info -E -P eventlet -c 250 -Ofair -n worker2@ -Q p_1_queue,p_2_queue
176m   1%   2   0% /usr/bin/python3 -m celery worker -A celery_app --without-heartbeat --workdir /app -l info -E -P eventlet -c 250 -Ofair -n worker5@ -Q p_1_queue,p_2_queue
176m   1%   1   0% /usr/bin/python3 -m celery worker -A celery_app --without-heartbeat --workdir /app -l info -E -P eventlet -c 250 -Ofair -n worker3@ -Q p_1_queue,p_2_queue
176m   1%   1   0% /usr/bin/python3 -m celery worker -A celery_app --without-heartbeat --workdir /app -l info -E -P eventlet -c 250 -Ofair -n worker4@ -Q p_1_queue,p_2_queue
171m   1%   1   0% /usr/bin/python3 -m celery worker -A celery_app --without-heartbeat --workdir /app -l info -E -P eventlet -c 20 -n worker_p_root@ -Q p_root_queue
157m   1%   0   0% /usr/bin/python3 -m celery beat -A celery_app --workdir /app --schedule /app/beat.db -l info

image

تحديث:
باستخدام 4.3.0 الكرفس يبدو أن المشكلة قد تم حلها وأنه مستقر منذ أسبوع
image

amqp (2.4.2)
billiard (3.6.0.0)
celery (4.3.0)
eventlet (0.24.1)
greenlet (0.4.15)
kombu (4.5.0)
vine (1.3.0)

يرجى إعلامي إذا كان بإمكاني المساعدة بطريقة أو بأخرى ، في ضبط الشفرة. إذا لزم الأمر ، قم بتوفير الروابط والمثال من فضلك.

شكرا لك

لدي أيضًا تسرب للذاكرة. يبدو أنني تمكنت من إيجاد السبب.
https://github.com/celery/celery/blob/master/celery/events/dispatcher.py#L75
أستطيع أن أرى أن هذا المخزن المؤقت يبدأ في النمو بعد مشكلات الاتصال مع الأرانب. لا أفهم سبب فشلها في مسح الأحداث في نهاية المطاف ، فهي تستمر في النمو بمرور الوقت وتستهلك المزيد والمزيد من ذاكرة الوصول العشوائي. يبدو أن تمرير buffer_while_offline=False هنا https://github.com/celery/celery/blob/master/celery/worker/consumer/events.py#L43 يصلح التسريب بالنسبة لي. هل يمكن لشخص ما التحقق مما إذا كان هذا متعلقًا؟

@ yevhen - م شكرا جزيلا لك! ساعدنا ذلك في حل مشكلة تسرب الذاكرة!

من الجيد أن يكون لدينا حل بديل ولكن هل يمكننا العثور على حل مناسب؟

متابعة مستمرة لمشكلة تسرب الذاكرة هذه

image

celery-pod-screencshot-lastweek

أنا أستخدم الكرفس في بيئة إنتاج ، وأنا أنشره عبر عامل إرساء.
مثل لقطة الشاشة ، نواجه نفس المشكلة.
يتم عرض تكوين الإنتاج لدينا أدناه.

الصورة الأصل Docker: python 3.6.8-buster
إصدار الكرفس: 4.2.0
خيارات الأمر:

  • التزامن 4
  • الجلب المسبق المضاعف 8
  • لا نتيجة_خلفية
  • acks_late ورفض الخسارة على العامل

أتساءل عما إذا كانت ترقية إصدار الكرفس إلى 4.3.0 يحل مشكلة تسرب الذاكرة.

شكرا لك!

الكرفس 4.4.0 هو أحدث إسطبل

فريق ، هل هناك أي تحديث حول هذه المسألة؟ هل تم تناول هذا الأمر وتثبيته في الكرفس 4.4.0؟

فريق ، هل هناك أي تحديث حول هذه المسألة؟ هل تم تناول هذا الأمر وتثبيته في الكرفس 4.4.0؟

للاسف لا. يتم تناوله الآن.

فريق ، هل هناك أي تحديث حول هذه المسألة؟ هل تم تناول هذا الأمر وتثبيته في الكرفس 4.4.0؟

سيكون متاحًا في 4.4.1

سيكون متاحًا في 4.4.1

هل تم إصلاحه في الإصدار الحالي 4.4.1؟

auvipy لا تزال المشكلة موجودة في

BROKER_POOL_LIMIT = None
CELERY_ACKS_LATE = False
CELERY_TRACK_STARTED = True
CELERYD_MAX_TASKS_PER_CHILD = 1
CELERYD_PREFETCH_MULTIPLIER = 1
BROKER_TRANSPORT_OPTIONS = {
    'fanout_prefix': True,
    'fanout_patterns': True,
    'visibility_timeout': 43200,
    'health_check_interval': 180,
    'socket_keepalive': True,
    'retry_on_timeout': True,
}

بدأ عامل الكرفس بعلامات -O fair --without-heartbeat --without-gossip -c 1 -l . نستخدم أيضًا علامات -n و -Q لتعيين اسم العامل وقوائم الانتظار. يعمل في وضع بريفورك. تم تكوين Redis ليكون وسيطًا ومخزنًا للنتائج.

image

~ نحن نرى العديد من ضربات القلب المفقودة في مهام التشغيل الطويلة. لذا فإن المشكلة المبلغ عنها في القضايا المرتبطة لا تزال قائمة

إنه نفس الشيء مع دقات القلب المعوقة.

jsynowiec عندما واجهت هذه المشكلة ، كان الشيء الوحيد الذي https://github.com/celery/celery/issues/4843#issuecomment -459789086

نواجه نفس المشكلة مع الكرفس 4.4.2 و redis كوسيط. على مدار 48 ساعة ، يستهلك الكرفس ما يصل إلى 60 جيجابايت من ذاكرة الوصول العشوائي حتى نفاد الذاكرة في النهاية.
لم يكن لأي من الحلول المذكورة هنا أي تأثير على هذا السلوك.

نواجه نفس المشكلة مع الكرفس 4.4.2 و redis كوسيط. على مدار 48 ساعة ، يستهلك الكرفس ما يصل إلى 60 جيجابايت من ذاكرة الوصول العشوائي حتى نفاد الذاكرة في النهاية.
لم يكن لأي من الحلول المذكورة هنا أي تأثير على هذا السلوك.

هل جربت أحدث إصدار من التصحيح لدينا؟
هل لديك نفس شروط البروتوكول الاختياري؟

لا يزال تسرب الذاكرة موجودًا في الإصدار 4.4.6. نحن نشغل العاملين بالإعدادات المدرجة في تعليق سابق . OP يستخدم RabbitMQ ، نستخدم Redis كوسيط.

image

+1 ، ملاحظة زيادة استخدام الذاكرة تدريجيًا على مدار 24 ساعة حتى مع الحد الأدنى من العمل الذي يتم إجراؤه. أعتقد أنه يجب إعادة فتح هذه المشكلة.

هل يمكنك ملف تعريف ومعرفة جذر تسرب الذاكرة الخاصة بك؟

لا يزال تسرب الذاكرة موجودًا في الإصدار 4.4.6. نحن نشغل العاملين بالإعدادات المدرجة في تعليق سابق . OP يستخدم RabbitMQ ، نستخدم Redis كوسيط.

image

يبدو أن هذه مشكلة مختلفة أو أن إصلاحنا لم يكن صحيحًا.
نظرًا لأن هذا أدى إلى حل مشكلة OP ، فمن المحتمل أن تكون مشكلة مختلفة ، أليس كذلك؟

[2020-07-31 10:51:53,176: WARNING/MainProcess] /usr/local/lib/python3.8/site-packages/redis/client.py:90: size=19.2 KiB (+19.2 KiB), count=180 (+180), average=109 B
[2020-07-31 10:53:53,271: WARNING/MainProcess] /usr/local/lib/python3.8/site-packages/redis/client.py:90: size=230 KiB (+211 KiB), count=2160 (+1980), average=109 B
[2020-07-31 10:54:53,364: WARNING/MainProcess] /usr/local/lib/python3.8/site-packages/redis/client.py:90: size=250 KiB (+19.2 KiB), count=2340 (+180), average=109 B

....

[2020-07-31 12:24:10,633: WARNING/MainProcess] /usr/local/lib/python3.8/site-packages/redis/client.py:90: size=49.9 MiB (+76.8 KiB), count=478620 (+720), average=109 B
[2020-07-31 12:25:14,528: WARNING/MainProcess] /usr/local/lib/python3.8/site-packages/redis/client.py:90: size=49.9 MiB (+19.2 KiB), count=478800 (+180), average=109 B
[2020-07-31 12:27:22,346: WARNING/MainProcess] /usr/local/lib/python3.8/site-packages/redis/client.py:90: size=49.9 MiB (+57.6 KiB), count=479340 (+540), average=109 B
[2020-07-31 12:28:26,265: WARNING/MainProcess] /usr/local/lib/python3.8/site-packages/redis/client.py:90: size=50.2 MiB (+269 KiB), count=481860 (+2520), average=109 B

CELERY_RESULT_BACKEND = False CELERY_IGNORE_RESULT = True CELERY_MAX_TASKS_PER_CHILD = 1 CELERY_WORKER_PREFETCH_MULTIPLIER = 1 CELERY_TASK_RESULT_EXPIRES = 10 CELERY_BROKER_POOL_LIMIT = 70 CELERY_REDIS_MAX_CONNECTIONS = 100
app.conf.broker_transport_options = {'visibility_timeout': 43200}

celery -A proj worker --concurrency=70 --prefetch-multiplier=1 -Ofair --pool=gevent -n --without-gossip --without-mingle

عميل ريديس يسرب الذاكرة؟ أنا أستخدم الكرفس v4.4.6 مع gevent و redis كوسيط ولا توجد نتيجة خلفية.

ربما هذه مشكلة أيضًا. ربما يكون في gevent؟
MustafaHosny اللهم امين
هل يمكنك مساعدتنا في التخلص من هذه المشكلة والتأكد من عدم تسرب الذاكرة من جانبك؟

ربما يكون في gevent؟

نحن لا نستخدم gevent . بدأ العمال مع التزامن = 1 و Prefork.

مرحبًا يا شباب ، لست متأكدًا من سبب إغلاق هذه المشكلة ، فنحن نواجه هذه المشكلة منذ عامين ، ونقوم بالتحديث إلى الإصدار الأخير من Celery في كل مرة ، وما زلنا نمتلك خوادم كبيرة (64-128 جيجابايت من ذاكرة الوصول العشوائي) تنفد باستمرار من ذاكرة الوصول العشوائي بسبب من مشكلات تسرب الذاكرة هذه.

هل هناك أي حل بديل دون الرجوع إلى Celery 3 أو استبدال Rabbitmq؟

هذا يجعل الكرفس غير مستقر تمامًا في بيئات الإنتاج ، آمل أن يتم إصلاحه ، لا يمكننا الرجوع إلى إصدار Celery 3 لذلك نحن نخطط للانتقال إلى حل آخر (ربما Dramatiq) من أجل التوقف عن القلق بشأن تناول الكرفس للخوادم بأكملها ذاكرة الوصول العشوائي على الإنتاج كل يومين.

arielcamino - كنت أستخدم الإعداد worker_max_tasks_per_child لاستبدال مثيلات العامل بعد 100 مهمة مما ساعد في الحفاظ على استخدام الذاكرة ، على الأقل

Skowt واو ، هذا مفيد للغاية ، شكرًا جزيلاً! سأحاول الآن.

arielcamino - كنت أستخدم الإعداد worker_max_tasks_per_child لاستبدال مثيلات العامل بعد 100 مهمة مما ساعد في الحفاظ على استخدام الذاكرة ، على الأقل

شكرا لتقاسم الحل الخاص بك. هذا لم يساعد هنا - لكننا نستخدم redis.

thedrow لست على علم بأي تسرب للذاكرة في redis-py. إذا كان لدى redis-py تسريب ، أفترض أن شخصًا ما قد واجهه خارج بيئة الكرفس وأبلغ متتبع مشكلة redis-py به.

يسعدني تقديم المساعدة حيثما يمكنني (أستخدم Celery w / Redis كوسيط في العديد من المشاريع) ، لكنني لم أواجه هذه المشكلة في عمليات النشر الخاصة بي.

لست على علم بأي تسرب للذاكرة في الإصدارات الحالية من gevent. أفترض (آمل) أن يقول شخص ما شيئًا ما إذا واجه ذلك (حدث مرة أو مرتين من قبل). نشراتي الحالية لـ gevent لديها العديد من العاملين (الويب والخلفية) لأسابيع في كل مرة باستخدام gevent بكثافة ولم نواجه تسربًا في الذاكرة.

مرحبًا يا شباب ، لست متأكدًا من سبب إغلاق هذه المشكلة ، فنحن نواجه هذه المشكلة منذ عامين ، ونقوم بالتحديث إلى الإصدار الأخير من Celery في كل مرة ، وما زلنا نمتلك خوادم كبيرة (64-128 جيجابايت من ذاكرة الوصول العشوائي) تنفد باستمرار من ذاكرة الوصول العشوائي بسبب من مشكلات تسرب الذاكرة هذه.

هل هناك أي حل بديل دون الرجوع إلى Celery 3 أو استبدال Rabbitmq؟

هذا يجعل الكرفس غير مستقر تمامًا في بيئات الإنتاج ، آمل أن يتم إصلاحه ، لا يمكننا الرجوع إلى إصدار Celery 3 لذلك نحن نخطط للانتقال إلى حل آخر (ربما Dramatiq) من أجل التوقف عن القلق بشأن تناول الكرفس للخوادم بأكملها ذاكرة الوصول العشوائي على الإنتاج كل يومين.

كم عدد العمال لديك؟ كم عدد المهام التي تديرها؟ كم مرة تقوم بتشغيل هذه المهام وما المدة التي تستغرقها عادةً حتى تنتهي؟

يمكن أن يكون السبب وراء بدء استخدام Rabbitmq / الكرفس في استخدام الكثير من ذاكرة الوصول العشوائي مرتبطًا بكمية المهام الموجودة في قائمة الانتظار. إذا قمت بوضع عدد كبير جدًا من المهام في قائمة الانتظار ولم يتمكن العمال من إكمالها جميعًا ، فسيؤدي ذلك إلى توسيع قائمة الانتظار وستستخدم قائمة الانتظار هذه المزيد والمزيد من ذاكرة الوصول العشوائي وستستهلك في النهاية كل ذاكرة الوصول العشوائي المتاحة. أعتقد أن هذه المشكلة قد تحدث مع Redis أيضًا.

لدي نظرية أخرى ولكن أولاً أريد أن أعرف ما إذا كان هذا هو سبب مشكلتك.

ardilom آسف ، لقد أدركت للتو أننا لا نرسل بيانات RabbitMQ إلى datadog ، لكنني سأحاول توضيح موقفنا ، هكذا تنخفض بعض ذاكرة الوصول العشوائي للخوادم كل يومين:
memory-leaks-1

نتحقق دائمًا من عدد المهام المعلقة ، وعادة ما يكون حوالي 0 (هذه البيانات من بعض الأيام الماضية):

memory-leaks-2

نقوم بتشغيل حوالي 250000 مهمة في اليوم ، ولدينا حوالي 10 عمال ، كل واحدة بها حوالي 4 إلى 10 التزامن ، ومتوسط ​​وقت التشغيل حوالي 5 ثوان ، وهذا يعتمد على نوع المهمة.

نتحقق دائمًا من messages_ ready للتأكد من عدم وجود عدد كبير جدًا من المهام في قائمة الانتظار (هذا ما تراه في الصورة الثانية) ، هل تعتقد أنه لا بأس من قياس الرسائل بالفعل ؟ لدينا بعض القمم في نهاية المطاف ، ولكن عادةً ما تكون قريبة من الصفر.

لحل المشكلة ، أقوم فقط بإعادة تشغيل عامل الكرفس يدويًا وسيصبح استخدام ذاكرة الوصول العشوائي طبيعيًا مرة أخرى.

أخبرني إذا كنت بحاجة إلى أي شيء آخر ، لقد قمت للتو بتغيير إعداد worker_max_tasks_per_child على أحد خوادم المهام ، لمعرفة ما إذا كان هناك أي اختلاف مع باقي الخوادم بعد تطبيق التكوين.

شكرا!

مرحبًا يا شباب ، هذا للتأكيد على أن تغيير worker_max_tasks_per_child إلى 1000 في حالتي ، تم إصلاح المشكلة 🎉 شكرًا مرة أخرى Skowt

شيء لم أذكره بالأمس ، أنا أستخدم وضع "Prefork" ، ربما يكون الانتقال إلى gevent طريقة أخرى لحل المشكلة.

arielcamino تم إغلاق هذه المشكلة نظرًا لأننا حللنا مشكلة تسرب ذاكرة معينة. لم نجد بعد سببًا آخر لتسرب الذاكرة. نعلم أن هناك مشكلة ولكننا لا نعرف كيف نعيد إنتاجها.
نحتاج إلى شخص لديه إمكانية الوصول إلى بيئة إنتاج حيث يتكرر الخطأ لتصحيح المشكلة.
إذا لم يكن لدينا واحد ، فسيتعين علينا تحديد أن هذه المشكلة غير قابلة للتنفيذ.

مرحبًا ، هل يمكننا إعادة فتح هذه المشكلة؟ نحن نشهد تسريبات مماثلة ، باستخدام الكرفس == 4.4.7 (مع rabbitmq) لدينا عامل يعمل بشكل مستقر لبضع ساعات ، وأحيانًا أكثر من ذلك بكثير ، ثم يبدأ فجأة بالتسرب ببطء وينتهي به الأمر باستخدام كل الذاكرة.

يتم استخدام Prefork حاليًا مع --concurrency=1 والعلامة --max-tasks-per-child=100 والتي لا يبدو أنها تساعد حيث يبدو أن العملية الرئيسية هي العملية التي تتسرب.

celery_leak

يمكنني تقديم المزيد من المعلومات للمساعدة في تصحيح هذه المشكلة.

مرحبًا ، هل يمكننا إعادة فتح هذه المشكلة؟ نحن نشهد تسريبات مماثلة ، باستخدام الكرفس == 4.4.7 (مع rabbitmq) لدينا عامل يعمل بشكل مستقر لبضع ساعات ، وأحيانًا أكثر من ذلك بكثير ، ثم يبدأ فجأة بالتسرب ببطء وينتهي به الأمر باستخدام كل الذاكرة.

يتم استخدام Prefork حاليًا مع --concurrency=1 والعلامة --max-tasks-per-child=100 والتي لا يبدو أنها تساعد حيث يبدو أن العملية الرئيسية هي العملية التي تتسرب.

celery_leak

يمكنني تقديم المزيد من المعلومات للمساعدة في تصحيح هذه المشكلة.

إعادة فتح المشكلة ليست مشكلة كبيرة ، إنها مصلحة شخص ما يواجه هذا الأمر في الإنتاج ويساعد في تتبع الإصلاح والمساهمة فيه أو على الأقل اكتشاف السبب الجذري للتسرب في الإنتاج.

يمكنني بالتأكيد المساعدة ، لكنني نفدت بعض الأفكار حول ما يجب القيام به ، قمت بتشغيل عدة أدوات ولكن لم أتمكن من تحديد الكثير حول هذه المشكلة. الشيء الوحيد الذي يضيقه نوعًا ما هو لقطات tracemalloc التي التقطتها ، والتي تُظهر زيادة الذاكرة في نفس الأماكن كل دقيقتين أو نحو ذلك. هذه هي أفضل 10 مقارنة بين لقطتين:

/usr/local/lib/python3.8/site-packages/celery/events/dispatcher.py:148: size=259 KiB (+218 KiB), count=1026 (+867), average=259 B
/usr/local/lib/python3.8/site-packages/kombu/messaging.py:178: size=231 KiB (+194 KiB), count=1056 (+888), average=224 B
/usr/local/lib/python3.8/site-packages/amqp/connection.py:513: size=217 KiB (+182 KiB), count=703 (+591), average=316 B
/usr/local/lib/python3.8/site-packages/celery/events/dispatcher.py:214: size=207 KiB (+174 KiB), count=704 (+592), average=302 B
/usr/local/lib/python3.8/site-packages/kombu/messaging.py:200: size=204 KiB (+171 KiB), count=704 (+592), average=296 B
/usr/local/lib/python3.8/site-packages/amqp/transport.py:253: size=203 KiB (+171 KiB), count=703 (+591), average=296 B
/usr/local/lib/python3.8/site-packages/amqp/connection.py:508: size=184 KiB (+154 KiB), count=703 (+591), average=268 B
/usr/local/lib/python3.8/site-packages/celery/worker/consumer/consumer.py:445: size=182 KiB (+153 KiB), count=352 (+296), average=528 B
/usr/local/lib/python3.8/site-packages/amqp/channel.py:1758: size=169 KiB (+143 KiB), count=703 (+593), average=247 B
/usr/local/lib/python3.8/site-packages/kombu/asynchronous/hub.py:301: size=167 KiB (+140 KiB), count=351 (+295), average=486 B

المشكلة لا تزال قائمة
يحدث هذا عندما تصل مهمة الكرفس إلى سياق التطبيق للقيام بوظيفة ما
لن تطلقها أو تتخلص منها بعد أداء المهمة

--max-tasks-per-child=

لم يكن مفيدا

مرحبًا ، هل يمكننا إعادة فتح هذه المشكلة؟ نحن نشهد تسريبات مماثلة ، باستخدام الكرفس == 4.4.7 (مع rabbitmq) لدينا عامل يعمل بشكل مستقر لبضع ساعات ، وأحيانًا أكثر من ذلك بكثير ، ثم يبدأ فجأة بالتسرب ببطء وينتهي به الأمر باستخدام كل الذاكرة.
يتم استخدام Prefork حاليًا مع --concurrency=1 والعلامة --max-tasks-per-child=100 والتي لا يبدو أنها تساعد حيث يبدو أن العملية الرئيسية هي العملية التي تتسرب.
celery_leak
يمكنني تقديم المزيد من المعلومات للمساعدة في تصحيح هذه المشكلة.

إعادة فتح المشكلة ليست مشكلة كبيرة ، إنها مصلحة شخص ما يواجه هذا الأمر في الإنتاج ويساعد في تتبع الإصلاح والمساهمة فيه أو على الأقل اكتشاف السبب الجذري للتسرب في الإنتاج.

بالنسبة لي إذا أضفت --max-tasks-per-child فهو يعمل.
مثل هذه الوسيطات النموذجية --autoscale=5,2 --max-tasks-per-child=40 النتيجة هكذا

Screenshot 2020-08-13 at 2 26 13 PM

بينما أعتقد أن ترقية الكرفس الأخيرة أدت إلى تسرب الذاكرة ، لا يمكنني أن أكون واثقًا تمامًا. سأشارك أن الإعداد التالي حل التسرب.

لا يمكنني معرفة الإعدادات الصالحة من خلال التوثيق ، لذلك أقوم بإعداد كل هذه القيم في ملف إعدادات Django.

CELERY_CONCURRENCY = CELERY_WORKER_CONCURRENCY = 1
CELERY_MAX_TASKS_PER_CHILD = CELERY_WORKER_MAX_TASKS_PER_CHILD = 1

هذا لا يحل التسرب الذي نراه ، كما يحدث أيضًا في تجمع gevent. ما لاحظته هو أن لدينا طابور celeryev مشغول للغاية. نظرًا لأن tracemalloc أظهر إرسال الحدث كأحد المصادر المحتملة للتسرب ، فقد عطلت بشكل صريح أحداث المهمة وأوقف تشغيل مثيل الزهرة الخاص بنا ، في الوقت الحالي يبدو أن التسريب لم يعد يحدث بعد الآن ، وسأسمح له بالعمل خلال عطلة نهاية الأسبوع ومشاركته النتائج هنا.

المصادر المحتملة للتسرب لقد عطلت بشكل صريح أحداث المهمة وأوقف تشغيل مثيل الزهرة

نقطة بيانات قصصية من شخص ما كان يشاهد هذه المشكلة بصمت منذ وقت مبكر (ولم يختبرها بشكل مباشر مطلقًا): أنا على دراية بمشروع آخر (مع عبء عمل غير جوهري للكرفس) حيث أدى القيام بما سبق إلى نفس النتيجة وقف تسرب الذاكرة. من خلال الحصول على معلومات من جهة ثانية فقط ، لا يمكنني - من الواضح - أن أؤكد أنها كانت نفس المشكلة الأساسية (AFAIK كانت عبارة عن rabbitmq ، ولا توجد فكرة عن gevent وما إلى ذلك) ، ولكن من المثير للاهتمام أنها مرتبطة.

أظن أن له علاقة باتصال rabbitmq بطريقة ما ، المكدس الذي كنا نلاحظه هذا التسريب:

  • الكرفس (الإصدار الأخير): إما بركة مسبقة الصنع أو مسبحة ، وكلاهما يظهر نفس نمط التسرب.
  • rabbitmq (cloudamqp SaaS)
  • زهرة

لقد فحصنا جميع مهامنا بحثًا عن التسريبات ولم نتمكن من العثور على أي تسريبات ، ولهذا السبب أشك في وجود شيء على جانب الكرفس.

إحدى الحقائق المثيرة للاهتمام هي أن لدينا حاليًا العديد من العمال يركضون ، وقد لاحظت أنه بمجرد أن يبدأ المرء في التسريب يظهر أيضًا على الأزهار على أنها غير متصلة بالإنترنت.

نظرًا لأنني نفدت الأفكار حول المكان الذي أبدو فيه ، فقد عطلت أحداث الزهرة والمهمة وسأواصل المراقبة إذا كان التسرب سيعود أم لا.

أنا منفتح على الاعتقاد بأنه جزء آخر من مجموعتي الذي يسرب الذاكرة في هذه المرحلة. ربما كان للكرفس سلوك صدفة في الماضي ساهم في السيطرة على تسرب الذاكرة ، ولكن لا يبدو أننا جميعًا نواجه مشكلات مماثلة كافية لتأكيد ذلك. أعلم أن الكثير منا إما يركض ...

  • عدد كبير من المهام المتداخلة في وقت واحد ، أو
  • عدد قليل من الأحجار المتجانسة التي تبدأ المعالجة متعددة النواة داخل العامل

في هذه الحالات ، نحتاج فقط إلى أن نكون أذكياء بشأن السماح أو عدم السماح بمستوى معين من التزامن ، وانتظار المهام ، والمهام لكل طفل عامل. بالإضافة إلى ذلك ، يجب علينا جميعًا استخدام وسائل حماية مدمجة يمكنها القضاء على المهام المتعطشة للذاكرة قبل أن تتاح لهم الفرصة لتعطل خوادمنا.

يقوم عدد متزايد من الأشخاص بتشغيل عمليات معقدة مرتبطة بوحدة المعالجة المركزية والذاكرة في الكرفس ، وهو ما لم يتم صنعه بالفعل ، لذلك أعتقد أن وثائق البدء السريع يجب أن تتضمن مزيدًا من التفاصيل حول هذا الأمر.

كما ذكرنا سابقًا في تعليقاتي السابقة ، نحن ندير عمالًا مع كل من max-tasks-per-child وتعيين التزامن على 1 منذ فترة طويلة. إنه لا يفعل أي شيء حيال تسريب الذاكرة. علاوة على ذلك ، نحن نستخدم Redis كوسيط وخلفية للنتائج.

من ملاحظاتي ، عندما يتم استخدام RabbitMQ كوسيط ، إذا كان تعيين max-tasks-per-child إلى 1 "يحل" تسرب الذاكرة ، فمن المحتمل أن تكون مشكلة في تنفيذ المهمة ، وليس الكرفس.

ما نلاحظه ونبلغ عنه مختلف. حتى لو تركنا العامل في وضع الخمول لعدة أيام ، دون معالجة مهمة واحدة ، فإنه لا يزال يؤدي إلى تسرب الذاكرة إلى نقطة عندما يصل إلى الحد الأقصى للذاكرة ويقتل من قبل المشرف. يمكنك العثور على مزيد من التفاصيل ومخططات الذاكرة في التعليقات السابقة.

مع معالجة العامل لمهمة واحدة في الموعد المحدد ، يجب أن يُظهر مخطط الذاكرة بشكل أو بآخر شكل موجة مربعة ، ولكن يمكنك أن ترى بوضوح أن الاستخدام الكلي للذاكرة يزيد فقط.
Screenshot 2020-08-14 at 20 42 24

لقد تمكنت من وضع سمات عمال الكرفس على خارطة الطريق الخاصة بنا. سأشارك مقالب الذاكرة والمزيد من التفاصيل عندما نبدأ العمل على هذا.

أستطيع أن أؤكد أن إيقاف تشغيل الزهرة (وتعطيل أحداث المهمة بشكل صريح من خلال الإعدادات) أدى إلى إصلاح التسرب.

كما ذكرت من قبل ، في اللحظة التي بدأ فيها العامل في التسريب ، لاحظت في الزهرة أنه سيتوقف عن العمل وأن الكرفس كان دائمًا مشغولًا للغاية ، لذلك ذهبت في الطريق السهل وأطفأت الزهرة.

لسوء الحظ ، لم أتمكن من العثور على جزء الكود الذي يسبب التسرب. ولكن على الأقل يوجد هذا الحل.

إذن ربما هذه ليست قضية كرفس بل زهرة؟

زهرة auvipy تثير المشكلة ، لكن التسرب يحدث بالتأكيد على العامل (الكرفس)

زهرة auvipy تثير المشكلة ، لكن التسرب يحدث بالتأكيد على العامل (الكرفس)

عادلة بما فيه الكفاية. شكرا للمشاركة.

أنا أستخدم الكرفس مع Redis و Flower ، ولا بد لي من القول إنني لا أرى حاليًا أي مشاكل في الذاكرة. أي شيء تريده مني فيما يتعلق بالبيانات؟

auvipy لا تستخدم زهرة. بدأ العمال مع الأحداث المعوقين.

auvipy لا تستخدم زهرة. بدأ العمال مع الأحداث المعوقين.

يرجى محاولة التصحيح ومعرفة جذر تسرب الذاكرة. يمكن أن يكون الكرفس أو العلبة الخاصة بك. سيكون من الأفضل مشاركة اختبارات الوحدة والتكامل

يرجى محاولة التصحيح ومعرفة جذر تسرب الذاكرة. يمكن أن يكون الكرفس أو العلبة الخاصة بك. سيكون من الأفضل مشاركة اختبارات الوحدة والتكامل

مذكور هنا ، أننا نرى OOMs بسبب تسرب الذاكرة لعامل الكرفس حتى لو لم تتم معالجة أي مهام بواسطة العامل.
لا يمكن مشاركة اختبارات الوحدة أو التكامل لأن هذا من شأنه أن يفضح عنوان IP الخاص بالشركة. آسف. لكنني تمكنت من إضافة مهمة لالتقاط مقالب الذاكرة على عمال الإنتاج في خريطة الطريق الداخلية الخاصة بنا. ستشارك العدادات والمراجع لبعض السيناريوهات عند الانتهاء.

jsynowiec إذا كان

بمجرد وصول إصلاح الخطأ إلى المستوى الرئيسي ، سيتم نقله إلى 4.x أيضًا.

thedrow متى يتم تخطيط GA من 5.0؟ لسوء الحظ ، لدينا بعض الرموز القديمة التي لا يزال من المقرر ترحيلها إلى Py3 😞 لذلك نحن عالقون مع Celery 4 في الوقت الحالي.

لدينا مانع إصدار واحد وبعض الوثائق لإكمالها.
الجواب قريبا جدا.

أستطيع أن أؤكد أن إيقاف تشغيل الزهرة يوقف التسرب. كنا نركض دون تسرب منذ ما يقرب من شهر الآن.

لذلك لا يزال هناك خطأ في مكان ما في آلية نشر الأحداث لدينا.
هل لدى أي شخص فكرة عما يمكن أن يكون؟

نحن لا نستخدم Flower وبدأ العمال بدون --events ، لكننا نشهد تسربًا مستمرًا للذاكرة.

الجواب قريبا جدا.

لقد تمكنت من إعطاء أولوية عالية للحصول على تفريغ الذاكرة وعدادات الكائنات من عمال الإنتاج. من المفترض أن أتمكن من نشر بعض البيانات في الأسابيع التالية. لقد قمنا أيضًا برفع الأولوية عند الانتهاء من نقل py2-> py3 ، لذلك يجب تشغيل كل شيء ، وتكوين ملف تعريف باستخدام Python 3

ما يقلقني هو أننا نتحدث عن قضيتين مختلفتين هنا.

فيما يبدو. يرتبط أحدهما بالأحداث وربما زهرة ، وربما أيضًا باستخدام RabbitMQ كوسيط. وفقًا للمشكلات التي تم الإبلاغ عنها هنا ، على GitHub ، تظهر هنا وهناك منذ بضع سنوات. العنصر الآخر (الذي يؤثر على مشروعي) مرتبط بمكونات مختلفة وعلى الأرجح مرتبط باستخدام Redis كوسيط. أو ربما في الجذر ، هذه هي نفس المشكلات التي تنشأ في نفس الكود الذي يعرف 🤷🏼. مثل تلك التي تحتوي على trail لتتبع المهام الفرعية وحالات التسريب من AsyncResult 😉

thedrowauvipy فقط مما يتيح لك معرفة أننا نتجه الآن إلى ذاكرة التنميط العمال.

أيضًا ، أثناء إنهاء ترحيل Python3 ، واجهنا مشكلة أخرى تبدو مرتبطة بـ https://github.com/celery/celery/issues/4470 أو https://github.com/celery/celery/issues/5359. في ظل ظروف معينة على أنظمة Linux ، أثناء استخدام Redis كوسيط ، تتوقف المكالمات إلى join_native إلى أجل غير مسمى على الرغم من تنفيذ جميع المهام داخل المجموعة بالفعل. يشير التعزيز السريع إلى أنه معلق حرفيًا عند القراءة ، مما قد يشير إلى بعض عناصر kernel / lib منخفضة المستوى. في الوقت الحالي ، قمنا بالتبديل إلى الوضع العادي ، حيث نقوم بتجميع join بينما نركز على تسرب الذاكرة.

مرحبًا بالجميع - أخيرًا _some_ data: celery-memtrace-1.tar.xz ، التوقيع ، مفتاحي .

يحتوي الأرشيف على سجلات tracemalloc من 8 عمال بعد 16 يومًا تقريبًا ، ورسم بياني لاستخدام الذاكرة للفترة وبعض معلومات الإصدار (بما في ذلك لافتة بدء تشغيل الكرفس).

لم أمضِ أي وقت طويل في تحليل أي من هذا بصراحة ، ولكن أ) لم يكن الرمز الخاص بنا موجودًا في القائمة أبدًا ، ب) قد يكون أيضًا تفاعلًا غريبًا مع SQLAlchemy الذي نستخدمه أيضًا في كل مكان ، لذلك ليس من المستحيل أن تكون المشكلة في مكان آخر ، أو أنها مشكلة دمج / تفاعل.

إذا كانت أي تفاصيل أخرى ستكون مفيدة ، يرجى السؤال. نواصل أيضًا تشغيل هؤلاء العمال الثمانية باستخدام تسجيل استخدام الذاكرة هذا ، لذلك ربما سنكون قادرين على جمع بيانات أكثر / أفضل.

تحرير : هذا التعليق أيضًا من هذا الموضوع مرتبط - ما زلنا نستخدم نفس الإعدادات.

أتمنى أن تجد السبب الجذري لهذا التسريب.
سأحاول تخصيص بعض الوقت للبحث في هذا بنفسي.

أتساءل عما إذا كان هذا يمكن أن يساعد في تخفيف المشكلة.
https://reliability.substack.com/p/run-python-servers-more-efficiently

نحن نحقق في احتمال أن يكون أصل تسرب الذاكرة داخل مكتبة الطلبات وليس الكرفس نفسه. أي شخص آخر يعاني من تسرب الذاكرة في الكرفس باستخدام الطلبات في المهام؟

ErrorInPersona نعم ، نحن نسجل OOMs في العمال مع وبدون طلبات على حد سواء.

drbig أي حظ؟

Screenshot_2020-11-17_12-56-28

حسنًا ، انظر إلى "اللون الأخضر" ، فالأرضية ترتفع ، ببطء ولكن بثبات ... لذا ، باستثناء التأكيد السريع على "نعم ، لا تزال مشكلة" لا يمكنني إضافتها من جانبي ، للأسف.

ومع ذلك ، فقد قمت بتصفح الرابط الذي - try running some workers with jemalloc forced in ، لذلك سأصل إلى ذلك ، _ في النهاية_.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات