Celery: Kebocoran memori terus menerus

Dibuat pada 23 Jun 2018  ·  129Komentar  ·  Sumber: celery/celery

Ada kebocoran memori dalam proses induk pekerja Celery.
Ini bukan proses anak menjalankan tugas.
Itu terjadi tiba-tiba setiap beberapa hari.
Kecuali Anda menghentikan Celery, Celery menghabiskan memori server dalam puluhan jam.

Masalah ini terjadi setidaknya di Celery 4.1, dan juga terjadi di Celery 4.2.
Celery berjalan di Ubuntu 16 dan broker menggunakan RabbitMQ.

memory

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

Komentar yang paling membantu

Mengapa masalah ini ditutup?

Semua 129 komentar

Apakah Anda menggunakan alur kerja Canvas? Mungkin # 4839 terkait.

Juga saya berasumsi Anda menggunakan kolam prefork untuk konkurensi pekerja?

Terima kasih georgepsarakis.

Saya tidak menggunakan alur kerja.
Saya menggunakan konkurensi prefork 1 di satu server.

Tingkat kenaikannya tampaknya cukup linier, cukup aneh. Apakah pekerja memproses tugas selama periode waktu ini? Selain itu, dapatkah Anda menambahkan catatan dengan perintah lengkap yang Anda gunakan untuk memulai pekerja?

Iya. Pekerja terus memproses tugas secara normal.

Pekerja dimulai dengan perintah berikut.

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

Masalah ini terjadi di lingkungan produksi dan lingkungan pengujian.
Saya dapat menambahkan profil memori dan hasil pengujian ke lingkungan pengujian.
Jika ada yang bisa saya lakukan, tolong katakan sesuatu.

Kita perlu memahami apa yang dijalankan pekerja selama waktu peningkatan memori diamati. Informasi dan detail apa pun yang mungkin dapat Anda berikan pasti akan. Ini juga bagus bahwa Anda bisa mereproduksi ini.

Meskipun itu adalah kasus yang terjadi pada waktu yang berbeda dari grafik, log berikutnya adalah keluaran pada waktu dimulainya kebocoran memori.

[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

Sepertinya itu terjadi ketika koneksi dengan RabbitMQ terputus untuk sementara.

@marvelph sehingga terjadi selama koneksi ulang RabbitMQ? Mungkin masalah ini terkait:

Iya.
Tampaknya koneksi ulang memicunya.

Sepertinya saya mengalami masalah yang sama ... Sangat sulit bagi saya untuk mencari tahu apa yang memicunya dan mengapa ada kebocoran memeory. Itu mengganggu saya setidaknya selama sebulan. Saya kembali ke seledri bekas 3 dan semuanya baik-baik saja.

Untuk masalah kebocoran memori, saya menggunakan ubuntu 16, seledri 4.1.0 dengan rabbitmq. Saya menerapkannya melalui buruh pelabuhan.

Kebocoran memori terjadi pada MainProcess bukan ForkPoolWorker. Penggunaan memori ForkPoolWorker normal, tetapi penggunaan memori MainProcess selalu meningkat. Selama lima detik, sekitar 0,1MB memeory bocor. Kebocoran memori tidak dimulai setelah pekerjaan dimulai dengan segera tetapi mungkin setelah satu atau dua hari.

Saya menggunakan gdb dan pyrasite untuk menyuntikkan proses yang sedang berjalan dan mencoba gc.collect() , tetapi tidak ada yang dikumpulkan.

Saya memeriksa log, consumer: Connection to broker lost. Trying to re-establish the connection... memang terjadi, tetapi untuk saat ini saya tidak yakin ini adalah waktu ketika kebocoran memori terjadi.

Adakah petunjuk untuk men-debug masalah ini dan untuk mencari tahu apa yang sebenarnya terjadi? Terima kasih.

Karena @marvelph menyebutkan bahwa ini mungkin berhubungan dengan koneksi ulang rabbitmq, saya mencoba menghentikan server rabbitmq saya. Penggunaan memori memang meningkat setelah setiap koneksi ulang, berikut adalah lognya. Jadi saya dapat mengonfirmasi https://github.com/celery/kombu/issues/843 masalah ini.

Tetapi setelah koneksi disambungkan kembali, penggunaan memori berhenti untuk meningkat secara bertahap. Jadi saya tidak yakin ini alasan kebocoran memori.

Saya akan mencoba menggunakan redis untuk mencari tahu apakah masalah kebocoran memori ini terkait dengan rabbitmq atau tidak.

[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

Meskipun saya memeriksa log, saya menemukan log koneksi ulang pada waktu kebocoran memori, tetapi ada juga kasus di mana kebocoran memori dimulai pada waktu ketika koneksi ulang tidak terjadi.
Saya setuju dengan ide jxlton.

Juga, ketika saya menggunakan Celery 3.x, saya tidak mengalami masalah seperti itu.

Masalah yang sama disini
screenshot 2018-06-25 11 09 22
Setiap beberapa hari saya harus memulai ulang pekerja karena masalah ini
tidak ada petunjuk signifikan dalam log, tetapi saya curiga bahwa menghubungkan kembali dapat memengaruhi; karena saya telah menyambungkan kembali entri log di suatu tempat pada saat memori mulai terus berkembang
Conf saya adalah ubuntu 17, 1 server - 1 pekerja dengan 3 konkurensi; kelinci dan redis di bagian belakang; semua paket adalah versi terbaru

@marvelph @ dmitry-kostin Bisakah Anda memberikan konfigurasi yang tepat (tentu saja menghilangkan informasi sensitif) dan mungkin tugas, atau contoh, yang mereproduksi masalah? Selain itu, apakah Anda memiliki perkiraan interval waktu kerja rata-rata saat peningkatan memori pekerja mulai muncul?

konfigurasi mendekati default

import = ('app.tasks',)
result_persistent = Benar
task_ignore_result = Salah
task_acks_late = Benar
worker_concurrency = 3
worker_prefetch_multiplier = 4
enable_utc = Benar
zona waktu = 'Eropa / Moskow'
broker_transport_options = {'visibility_timeout': 3600, 'confirm_publish': Benar, 'fanout_prefix': Benar, 'fanout_patterns': Benar}

screenshot 2018-06-25 11 35 17
Pada dasarnya ini adalah node yang baru digunakan; itu digunakan pada 06/21 18-50; menatap untuk tumbuh 6/23 sekitar 05-00 dan akhirnya jatuh 6/23 sekitar 23-00

tugasnya cukup sederhana dan tidak ada superlogic di sana, saya pikir saya dapat mereproduksi seluruh situasi pada proyek temp yang jelas tetapi tidak memiliki waktu luang untuk saat ini, jika saya beruntung saya akan mencoba membuat contoh lengkap pada akhir pekan

UPD
seperti yang Anda lihat, tugas itu sendiri menghabiskan beberapa memori, Anda dapat melihatnya dengan lonjakan pada grafik, tetapi saat memori menatap bocor, tidak ada tugas yang dihasilkan atau aktivitas lainnya.

@marvelph @ dmitry-kostin @jxltom Saya perhatikan Anda menggunakan Python3. Apakah Anda keberatan mengaktifkan tracemalloc untuk proses tersebut? Anda mungkin perlu menambal proses pengerjaan untuk mencatat jejak alokasi memori, beri tahu saya jika Anda memerlukan bantuan untuk itu.

@georgepsarakis Maksud Anda mengaktifkan tracemalloc di statistik pekerja dan log, seperti 10 file penggunaan memori teratas, pada interval tertentu seperti 5 menit?

@jxltom Saya pikir sesuatu seperti itu akan membantu menemukan bagian dari kode yang bertanggung jawab. Bagaimana menurut anda?

@georgepsarakis Saya mencoba menggunakan gdb dan https://github.com/lmacken/pyrasite untuk memasukkan proses kebocoran memori, dan memulai debug melalui tracemalloc. Berikut adalah 10 file teratas dengan penggunaan mem tertinggi.

Saya menggunakan resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024 dan penggunaan memori secara bertahap meningkat.

>>> 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

Berikut adalah perbedaan antara dua jepretan setelah sekitar 5 menit.

>>> 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

Ada saran untuk bagaimana melanjutkan debug ini? Saya tidak tahu bagaimana melanjutkan. Terima kasih.

@jodohgratis

Saya ingin sedikit waktu untuk menghentikan proyek reproduksi.

Ini adalah pengaturan seledri.

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

Penjadwal memiliki pengaturan berikut.

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),
    },
}

Pada EC 2, saya menggunakan supervisord untuk mengoperasikannya.

@jodohgratis
Karena lingkungan pengujian saya dapat mentolerir penurunan kinerja, Anda dapat menggunakan tracemalloc.
Bisakah Anda membuat Celery yang ditambal untuk membuang penggunaan memori?

@jxltom Saya yakin tracemalloc dengan 5 menit tidak akan membantu untuk menemukan masalah
Misalnya saya memiliki 5 node dan hanya 3 dari mereka yang mengalami masalah ini selama 4 hari terakhir, dan 2 berfungsi dengan baik selama ini, jadi akan sangat sulit untuk menemukan masalah ..
Saya merasa ada beberapa sakelar yang aktif dan kemudian memori mulai bertambah, hingga konsumsi memori sakelar ini terlihat sangat baik

Saya mencoba mencari tahu apakah masalah serupa terjadi di sistem lain yang sedang berjalan.
Frekuensi kemunculannya bervariasi, tetapi kebocoran memori telah terjadi pada tiga sistem yang menggunakan Celery 4.x, dan itu tidak terjadi pada satu sistem.
Sistem yang mengalami kebocoran memori adalah Python 3.5.x, dan sistem tanpa kebocoran memori adalah Python 2.7.x.

@ dmitry-kostin Apa bedanya dengan dua node normal lainnya, apakah keduanya menggunakan rabbitmq yang sama sebagai broker?

Karena diskusi kami menyebutkan itu mungkin terkait dengan rabbitmq, saya memulai node baru lain dengan konfigurasi yang sama kecuali untuk menggunakan redis sebagai gantinya. Sejauh ini, node ini tidak mengalami kebocoran memori setelah berjalan 24 jam. Saya akan mempostingnya di sini jika nanti mengalami kebocoran memori

@marvelph Jadi maksud Anda tiga sistem dengan kebocoran memori menggunakan python3 sedangkan yang baik-baik saja menggunakan python2?

@jxltom tidak ada perbedaan sama sekali, dan ya mereka di python 3 & rabit sebagai broker dan redis di backend
Saya membuat contoh pengujian untuk mereproduksi ini, jika itu akan berhasil dalam beberapa hari saya akan memberikan kredensial ke server ini untuk seseorang yang tahu bagaimana menemukan bug ini

@bayu_joo
Iya.
Sejauh menyangkut lingkungan saya, masalah tidak terjadi di Python 2.

Saya melacak kebocoran memori melalui tracemalloc dalam waktu yang lebih lama.

Penggunaan memori awal yang dilaporkan oleh modul resource adalah 146.58MB , setelah 3,5 jam, dilaporkan bahwa penggunaan memori adalah 224.21MB .

Berikut ini adalah perbedaan snapshot yang dilaporkan oleh 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

Ada ide? Sepertinya tidak ada satu file pun yang bocor?

Saya juga mengimpor gc , dan gc.collect() mengembalikan 0 ...

@georgepsarakis Saya dapat mereproduksi ini, ping saya untuk kredibilitas akses

Pembaruan: Saya telah memperbarui broker dari rabbitmq ke redis dengan memperbarui url broker sebagai variabel lingkungan dan menyimpan buruh pelabuhan / kode sepenuhnya sama. Dan itu berjalan selama 4 hari dan tidak ada kebocoran memori .

Jadi saya yakin masalah ini terkait dengan broker rabbitmq.

Jika memungkinkan, coba jalankan perintah benchmark, yang disebutkan di sini: https://github.com/celery/celery/issues/2927#issuecomment -171455414

Sistem ini menjalankan pekerja dengan 20 server.
Kebocoran memori terjadi kemarin, tetapi terjadi di hampir semua server pada waktu yang sama.
memoryleak

Tidak tahu apakah itu terkait, tinggalkan di sini kalau-kalau itu membantu.

Saya memiliki masalah yang berbeda dengan seledri dan kelincimq (seledri kehilangan koneksi dan mulai menghubungkan kembali banyak kali per detik, cpu berjalan 100% pada 1 inti, ketukan tidak dapat mengirim tugas baru, perlu memulai ulang seledri).

Alasan saya melaporkan hal ini di sini adalah pemicunya: setelah beberapa hari pemantauan, saya rasa saya telah menemukan awal masalah dan tampaknya kelincimq memindahkan beberapa pesan dari memori ke disk. Pada saat itu seledri mulai mencoba menyambung kembali secepat mungkin dan log rabbitmq menunjukkan puluhan operasi sambungan / pemutusan sambungan per detik, dalam batch ~ 10 atau lebih sekaligus. Memulai ulang rabbitmq tidak memperbaiki masalah, memulai ulang seledri akan segera memperbaikinya. Saya tidak memiliki perbaikan yang tepat tetapi sebagai contoh, menetapkan kebijakan kedaluwarsa yang memungkinkan pesan untuk selalu berada di memori berfungsi di sekitar masalah dan saya belum melihatnya sejak itu.

Diberikan beberapa detail dari masalah ini sesuai dengan apa yang saya lihat (menukar rabbitmq dengan redis memperbaikinya, tidak ada titik awal yang jelas, ini terjadi pada lebih dari satu pekerja / server pada saat yang sama) Saya kira mungkin ada pemicu umum dan mungkin sama seperti yang saya lihat.

Paket pengujian diubah dari https://github.com/celery/celery/tree/master/funtests/stress menjadi https://github.com/celery/cyanide , dan hanya mendukung Python2.

Jadi saya menjalankannya di Python2 dengan rabbitmq sebagai broker. Ini mengumpulkan !join: connection lost: error(104, 'Connection reset by peer') . Apakah ini terkait dengan masalah kebocoran memori?

Berikut adalah log untuk rangkaian pengujian.

➜  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

Ini log untuk pekerja.

➜  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') !

Saya telah memperbarui untuk menggunakan seledri 3.1.25 dengan rangkaian uji stres yang sama, semuanya baik-baik saja.

BTW Untuk semua orang yang mencari solusi cepat - mengganti kelinci dengan redis menyelesaikan masalah seperti yang disarankan @jxltom , saya memiliki lebih dari seminggu kerja stabil dengan redis hanya sekarang
Jadi masalahnya pasti ada di suatu tempat di dekat perbatasan kelinci <-> seledri

@dieeasy kami pernah mengalami masalah yang sama. Saya berasumsi Anda menggunakan backend hasil RPC. Jika demikian, coba beralih ke backend hasil DB dan lihat apakah itu membantu. Masalah yang menyebabkan ini adalah: https://github.com/celery/kombu/pull/779 dan dijelaskan di sini: https://github.com/celery/kombu/pull/779#discussion_r134961611

Saya memiliki masalah kebocoran memori yang sama
Penyimpanan
image

Versi: kapan
python 3.6.5 seledri 4.2.1 backend redis pialang rabbitmq

Config

[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

`` python

- - pengkodean: utf-8 - -

dari kombu import Queue, Exchange
dari oslo_log impor log sebagai logging

dari app.conf impor CONF

LOG = logging.getLogger (__ name__)

antrean_seledri = (
Antrian ('im', exchange = Exchange ('sender'), routing_key = 'im'),
Antrian ('sms', exchange = Exchange ('sender'), routing_key = 'sms'),
Antrian ('mail', exchange = Exchange ('sender'), routing_key = 'mail'),
Antrian ('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'}
}

config = {
'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': antrean_seledri,
'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())

Saya dapat memberikan lebih banyak informasi jika diperlukan.

Untuk apa nilainya, saya mengalami masalah ini dan dapat mereproduksinya secara konsisten dengan membuka konsol manajemen rabbitmq, membuka koneksi, dan menutup koneksi dengan lalu lintas dari seledri ke rabbitmq.

Saya telah menguji dengan seledri 4.1 dan 4.2 dan kelincimq 3.7.7-1
EDIT: juga python versi 3.6.5 dan ubuntu 16.04 (gambar AWS EC2)

Saya mengalami kebocoran memori dengan seledri 4.2.1 dan redis broker. Memori bertambah dari 100 MiB menjadi 500 MiB (terbatas) dalam 3 jam, dan pekerja ditandai sebagai offline dalam bunga. Baik kumpulan prefork dan gevent menunjukkan masalah yang sama.

@yifeikong ini mungkin bukan masalah yang sama, tetapi untuk kasus Anda, bisakah Anda mencoba solusi yang diusulkan https://github.com/celery/celery/pull/4839#issuecomment -447739820?

@georgepsarakis Saya menggunakan Python 3.6.5, jadi saya tidak terpengaruh oleh bug ini. Saya akan menggunakan tracemalloc untuk melakukan penelitian. Jika itu adalah kutu seledri, saya akan membuka edisi baru. Terima kasih

Mungkin penyebabnya sama dengan # 5047 , sepertinya bug ini dapat menyebabkan fenomena yang berbeda.

Kami menghadapi kebocoran memori yang sama menjalankan Celery 4.2.1, Kombu 4.2.2 dan python3.6 dengan RabbitMQ sebagai broker.

$ 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

Saya dapat mengatakan kami telah mencoba banyak hal yang disebutkan orang lain sebagai solusi yang mungkin (redis sebagai broker, menggunakan jemalloc, libamqp, monkey path __del__ pada AsyncResult ) tetapi kami selalu berakhir dengan kebocoran memori.

Dengan menganalisis log kami, kami menemukan bahwa kami memiliki banyak pesan terkait detak jantung yang terlewat dari gosip.

{"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@******"}

Satu hal terakhir yang kami coba adalah menonaktifkan gosip dengan menghukum para pekerja dengan --without-gossip , yang mengejutkan, menonaktifkan gosip memiliki efek langsung.

Anda bisa melihatnya di sini:
celery-memory-14d

Sejak kami menonaktifkan gosip di dua proyek yang menjalankan pekerja seledri, konsumsi memori telah meningkat.

Jika Anda perhatikan, sebelumnya kami mengalami lonjakan memori serupa seperti yang dijelaskan di sini https://github.com/celery/celery/issues/4843#issuecomment -399833781

Satu hal yang saya coba pahami sepenuhnya adalah apa implikasi dari menonaktifkan gosip sepenuhnya, karena ini hanya dijelaskan sebagai komunikasi pekerja <-> pekerja, jika ada yang bisa menjelaskan hal ini saya akan sangat berterima kasih.

Semoga ini bisa membantu dan terima kasih atas kerja kerasnya.

Mengapa masalah ini ditutup?

Ada umpan balik aktif dan minat dalam masalah ini, jadi saya buka kembali.

Nah @georgepsarakis karena kami mendiagnosis kebocoran saya bukan # 4839, dan Anda curiga itu # 4843, saya akan beralih ke utas kebocoran ini setidaknya untuk saat ini. Saya juga tidak yakin # 4843 adalah kebocoran saya. Menurut masalah awal di utas ini:

Masalah ini terjadi setidaknya di Celery 4.1, dan juga terjadi di Celery 4.2.
Celery berjalan di Ubuntu 16 dan broker menggunakan RabbitMQ.

Saya saat ini berada di:

python 2.7.12
Ubuntu 16.04.1 amd64
RabbitMQ 3.7.5

menggunakan:

Seledri 4.1.1
librabbitmq 2.0.0
amqp 2.4.0
anggur 1.1.4
biliar 3.5.0.5
kombu 4.2.2.post1
gevent 1.2.2

Namun, Celery 4.1.1 + gevent 1.2.2 tidak bocor untuk saya (Celery 3.1.25 + gevent 1.2.2 AFAICT juga tidak); Celery 4.2.1 + gevent 1.3.7 tidak. Sayangnya, gevent 1.3.7 dan gevent 1.2.2 tidak dapat dipertukarkan untuk mendemonstrasikan (atau mengecualikan) pustaka gevent sebagai kemungkinan sumber masalah.

EDIT: Hmm ... sepertinya ada patch gevent (022f447dd) yang sepertinya bisa memperbaiki kesalahan yang saya temui. Saya akan mencoba dan membuatnya bekerja.

Saya menerapkan 022f447 ke Celery 4.1.1 dan menginstal gevent 1.3.7. Kombinasi Celery + gevent itu berjalan ... dan menghasilkan pola penggunaan memori yang konsisten dengan kebocoran yang saya alami. Saya akan menginstal Celery 4.2.1 + gevent 1.2.2 (dengan tambalan terbalik) dan melihat apakah saya mendapatkan pola penggunaan memori yang biasa.

Saya melihat gevent 1.4.0 keluar. Mungkin aku harus mencobanya juga untuk melihat bagaimana perilakunya.

Celery 4.2.1 + gevent 1.2.2 + reverse patch untuk gevent 1.2.2 sepertinya tidak menghasilkan kebocoran seperti halnya Celery 4.2.1 + gevent 1.3.7.

Celery 4.2.1 + gevent 1.4.0 tampaknya bocor pada laju yang kira-kira sama dengan 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.

Sekarang, jika saya memahami dengan benar apa yang dilakukan AMQP di bawah kap, maka ia memiliki detak jantungnya sendiri dan ketika mendeteksi koneksi yang rusak, ia akan melanjutkan dan menyambung kembali di bawah kap. Bergantung pada jenis acara yang diaktifkan (gosip, detak jantung), ini bisa bocor dengan cukup cepat.
Ini harus benar untuk semua versi eventlet & gevent tetapi beberapa dapat menunjukkan masalah koneksi yang membuat segalanya menjadi lebih buruk / lebih terlihat.

Hai,

Saya menduga kami mengalami masalah yang sama.
Konfigurasi kami ada di bawah. Dapatkah saya meniadakan atau mengonfirmasi bahwa ini adalah masalah yang sama yang dibahas di sini?

Python: 2.7
Seledri: 4.2.1
OS: CentOS rilis 6.10
Redis sebagai broker

Pada gambar terlampir Anda dapat melihat:

  1. Konsumsi memori meningkat secara konstan dan menurun saat restart.
  2. Pada 13 Januari - kami meningkatkan dari seledri 3.1.25 menjadi 4.2.1. Kecepatan konsumsi memori meningkat.

image

MEMPERBARUI

Terlepas dari masalah ini, kami meningkatkan ke python 3.6 dan sejak itu sepertinya kebocoran tidak terjadi lagi.

image
(peningkatan dilakukan pada 19 Februari)

@jodohgratis

Tidak yakin seberapa relevan ini, tetapi saya memiliki ruang SWAP 2GB saya yang habis oleh seledri dalam produksi. Stopping Flower tidak menghapus ingatannya, tetapi menghentikan Celery berhasil.

adakah yang bisa mencoba seledri 4.3rc1?

@auvipy Saya menginstal Celery 4.3.0rc1 + gevent 1.4.0. pip meningkatkan biliar menjadi 3.6.0.0 dan kombu 4.3.0.

Agak bingung bahwa vine 1.2.0 tidak juga diperlukan oleh paket rc1, mengingat # 4839 diperbaiki oleh peningkatan itu.

Bagaimanapun, Celery 4.3.0 rc1 sepertinya bekerja dengan baik.

@ ldav1s terima kasih banyak atas umpan baliknya. Jadi, vine sebenarnya dideklarasikan sebagai dependensi di py-amqp . Dalam pemasangan baru versi vine terbaru akan dipasang tetapi ini mungkin tidak terjadi pada versi yang sudah ada.

@thedrow mungkin kita harus menyatakan ketergantungan dalam persyaratan Celery juga?

Mari kita buka masalah tentang itu dan diskusikan di sana.

Celery 4.3.0rc1 + gevent 1.4.0 telah berjalan beberapa hari sekarang. Sepertinya bocor dengan cara yang sama seperti Celery 4.2.1 + gevent 1.4.0.

image

Memiliki kebocoran yang sama dengan seledri 4.2.1, python 3.6

Ada pembaruan tentang ini?

mengalami masalah yang sama di sini

Salam pembuka,

Saya mengalami masalah yang serupa, tetapi saya tidak yakin itu sama.

Setelah saya memigrasi aplikasi seledri kami di lingkungan / jaringan yang berbeda, pekerja seledri mulai bocor. Sebelumnya aplikasi seledri dan instance rabbitmq berada di lingkungan / jaringan yang sama.

Konfigurasi saya menggunakan 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)

seledri

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

Aplikasi ini disusun oleh beberapa pekerja dengan eventlet pool, dimulai melalui perintah di supervisord:

[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

Perilaku kebocoran memori terlihat seperti ini, setiap ~ 10 jam biasanya 1 pekerja, maks 2 mulai bocor:
image

Jadi saya telah membuat pesan siaran untuk dieksekusi pada setiap pekerja, untuk menggunakan tracemalloc, ini adalah hasil dari perintah teratas di mesin, ada 1 pekerja hanya bocor dengan 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 TOP 10 hasil pada pekerja yang bocor

[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 dengan 25 bingkai

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)

Saya harap ini bisa membantu, tidak ada kesalahan di log, selain detak jantung yang tidak terjawab di antara para pekerja. Sekarang saya mencoba menggunakan versi yang tepat dari libs yang kami gunakan dengan env lama.

PEMBARUAN: Menggunakan versi lib dependensi yang sama persis dan detak jantung broker setiap 5 menit, aplikasi tampak seperti stabil untuk waktu yang lebih lama: lebih dari 2 hari, daripada bocor lagi.

Ada lonjakan kecil yang berlanjut selama ~ 1 jam dari waktu ke waktu, tetapi "diserap / dikumpulkan" .. yang terakhir sepertinya memulai lonjakan.

Setelah lonjakan pertama, ramp pertama, saya telah menghidupkan kembali pekerja yang bocor .. karena Anda dapat melihat pekerja lain mulai bocor setelahnya atau mungkin sudah bocor, ramp ke-2.

image

Saya akan menguji tanpa detak jantung.

PEMBARUAN: tanpa detak jantung bocor lagi setelah 2 hari, perilaku yang sama

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

MEMPERBARUI:
Menggunakan seledri 4.3.0 sepertinya masalah teratasi dan stabil sejak seminggu
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)

Tolong beri tahu saya jika saya bisa membantu, dengan melengkapi kodenya. Jika perlu berikan tautan dan contoh, silakan.

Terima kasih

Saya juga mengalami kebocoran memori. Sepertinya saya berhasil menemukan penyebabnya.
https://github.com/celery/celery/blob/master/celery/events/dispatcher.py#L75
Saya dapat melihat bahwa buffer ini mulai tumbuh setelah masalah koneksi dengan kelinci. Saya tidak mengerti mengapa akhirnya gagal untuk menghapus peristiwa, itu terus tumbuh dari waktu ke waktu dan mengkonsumsi lebih banyak ram. Meneruskan buffer_while_offline=False sini https://github.com/celery/celery/blob/master/celery/worker/consumer/events.py#L43 tampaknya memperbaiki kebocoran untuk saya. Bisakah seseorang memeriksa apakah ini terkait?

@ yevhen-m terima kasih banyak! Itu membantu kami mengatasi kebocoran memori!

Ada baiknya kita memiliki solusi, tetapi bisakah kita menemukan perbaikan yang tepat?

terus ikuti masalah kebocoran memori ini

image

celery-pod-screencshot-lastweek

Saya menggunakan seledri di lingkungan produksi, dan saya menyebarkannya melalui buruh pelabuhan.
Seperti tangkapan layar, kami mengalami masalah yang sama.
Konfigurasi produksi kami ditunjukkan di bawah ini.

Gambar induk Docker: python 3.6.8-buster
Versi seledri: 4.2.0
Opsi Perintah:

  • konkurensi 4
  • prefetch-multiplier 8
  • Tidak ada result_backend
  • acks_late dan reject_on_worker_lost

Saya ingin tahu apakah memutakhirkan versi seledri ke 4.3.0 menyelesaikan masalah kebocoran memori.

Terima kasih!

seledri 4.4.0 adalah versi stabil terbaru

Tim, apakah ada pembaruan tentang masalah ini? Apakah ini ditangani dan diperbaiki dalam seledri 4.4.0?

Tim, apakah ada pembaruan tentang masalah ini? Apakah ini ditangani dan diperbaiki dalam seledri 4.4.0?

Sayangnya tidak ada. Sekarang ditangani.

Tim, apakah ada pembaruan tentang masalah ini? Apakah ini ditangani dan diperbaiki dalam seledri 4.4.0?

itu akan tersedia di 4.4.1

itu akan tersedia di 4.4.1

apakah sudah diperbaiki dalam versi 4.4.1 saat ini?

@auvipy Masalahnya masih ada di Celery 4.4.2, dan 4.4.6. Kami melihat kebocoran memori yang sama di semua pekerja.

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,
}

Pekerja seledri memulai dengan -O fair --without-heartbeat --without-gossip -c 1 -l flags. Kami juga menggunakan flag -n dan -Q untuk menyetel nama pekerja dan antrian. Berjalan dalam mode prefork. Redis dikonfigurasi sebagai, broker dan penyimpanan hasil.

image

~ Kami melihat banyak detak jantung yang terlewat pada tugas yang berjalan lama. Jadi masalah yang dilaporkan dalam masalah terkait masih berlanjut. ~

Ini sama dengan detak jantung yang cacat.

@jsynowiec Ketika saya menghadapi masalah ini, satu-satunya hal yang berhasil bagi saya adalah menjalankan pekerja dengan gosip dinonaktifkan, saya menyebutkan sesuatu tentang itu di sini https://github.com/celery/celery/issues/4843#issuecomment -459789086

Kami mengalami masalah yang sama dengan seledri 4.4.2 dan redis sebagai broker. Selama rentang waktu 48 jam seledri mengkonsumsi hingga 60 GB RAM hingga akhirnya kehabisan memori.
Tidak ada solusi yang disebutkan di sini yang berpengaruh pada perilaku ini.

Kami mengalami masalah yang sama dengan seledri 4.4.2 dan redis sebagai broker. Selama rentang waktu 48 jam seledri mengkonsumsi hingga 60 GB RAM hingga akhirnya kehabisan memori.
Tidak ada solusi yang disebutkan di sini yang berpengaruh pada perilaku ini.

Apakah Anda mencoba versi tambalan terbaru kami?
Apakah Anda memiliki kondisi yang sama dengan OP?

Kebocoran memori masih ada di v4.4.6 Kami menjalankan pekerja dengan pengaturan yang terdaftar di komentar sebelumnya . OP menggunakan RabbitMQ, kami menggunakan Redis sebagai broker.

image

+1, memperhatikan penggunaan memori secara bertahap meningkat selama 24 jam bahkan dengan sedikit pekerjaan yang dilakukan. Saya pikir masalah ini harus dibuka kembali.

dapatkah Anda membuat profil dan mengetahui akar kebocoran memori Anda?

Kebocoran memori masih ada di v4.4.6 Kami menjalankan pekerja dengan pengaturan yang terdaftar di komentar sebelumnya . OP menggunakan RabbitMQ, kami menggunakan Redis sebagai broker.

image

Sepertinya ini adalah masalah yang berbeda atau perbaikan kami tidak benar.
Karena ini menyelesaikan masalah OP, mungkin itu masalah yang berbeda, bukan?

[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

Apakah klien membocorkan memori? Saya menggunakan celery v4.4.6 dengan gevent, redis sebagai broker dan tidak ada hasil backend.

Mungkin itu juga menjadi masalah. Mungkin di gevent?
CC @jamadden @andccurdy
Bisakah Anda membantu kami menyelesaikan masalah ini dan memastikan tidak ada memori yang bocor di pihak Anda?

Mungkin di gevent?

Kami tidak menggunakan gevent . Pekerja dimulai dengan konkurensi = 1 dan prefork.

Hai teman-teman, tidak yakin mengapa masalah ini ditutup, kami telah mengalami masalah ini selama 2 tahun sekarang, memperbarui ke versi terakhir Celery setiap kali, dan masih memiliki server besar (64-128GB RAM) terus-menerus kehabisan RAM karena masalah kebocoran memori ini.

Apakah ada solusi lain tanpa menurunkan ke Celery 3 atau mengganti Rabbitmq?

Ini membuat Celery benar-benar tidak stabil di lingkungan produksi, saya harap ini bisa diperbaiki, kami tidak dapat menurunkan versi ke Celery 3 jadi kami berencana pindah ke solusi lain (mungkin Dramatiq) untuk berhenti mengkhawatirkan Celery memakan seluruh RAM server di produksi setiap 2 hari.

@arielcamino - Saya telah menggunakan pengaturan worker_max_tasks_per_child untuk mengganti instance pekerja setelah 100 ~ tugas yang telah membantu mempertahankan penggunaan memori, setidaknya untuk server saya. Saya menjalankan contoh kecil 512MB dan ini membantu (sebelumnya akan menghabiskan ram saya) jadi mungkin ini akan membantu Anda.

@Skowt wow, itu sangat membantu, terima kasih banyak! Akan mencoba sekarang.

@arielcamino - Saya telah menggunakan pengaturan worker_max_tasks_per_child untuk mengganti instance pekerja setelah 100 ~ tugas yang telah membantu mempertahankan penggunaan memori, setidaknya untuk server saya. Saya menjalankan contoh kecil 512MB dan ini membantu (sebelumnya akan menghabiskan ram saya) jadi mungkin ini akan membantu Anda.

Terima kasih telah membagikan solusi Anda. Ini tidak membantu di sini - kami menggunakan redis.

@thedrow Saya tidak mengetahui adanya kebocoran memori di redis-py. Jika redis-py mengalami kebocoran, saya berasumsi bahwa seseorang akan menemukannya di luar lingkungan Celery dan melaporkannya ke pelacak masalah redis-py.

Senang membantu di mana saya bisa (saya menggunakan Celery w / Redis sebagai broker di beberapa proyek), tetapi saya belum mengalami masalah ini dalam penerapan saya.

Saya tidak mengetahui adanya kebocoran memori dalam versi gevent saat ini. Saya berasumsi (berharap) seseorang akan mengatakan sesuatu jika mereka menemukannya (itu telah terjadi sekali atau dua kali sebelumnya). Penerapan gevent saya saat ini memiliki banyak pekerja (web dan latar belakang) selama berminggu-minggu pada waktu yang sangat banyak menggunakan gevent dan kami belum mengalami kebocoran memori.

Hai teman-teman, tidak yakin mengapa masalah ini ditutup, kami telah mengalami masalah ini selama 2 tahun sekarang, memperbarui ke versi terakhir Celery setiap kali, dan masih memiliki server besar (64-128GB RAM) terus-menerus kehabisan RAM karena masalah kebocoran memori ini.

Apakah ada solusi lain tanpa menurunkan ke Celery 3 atau mengganti Rabbitmq?

Ini membuat Celery benar-benar tidak stabil di lingkungan produksi, saya harap ini bisa diperbaiki, kami tidak dapat menurunkan versi ke Celery 3 jadi kami berencana pindah ke solusi lain (mungkin Dramatiq) untuk berhenti mengkhawatirkan Celery memakan seluruh RAM server di produksi setiap 2 hari.

Berapa banyak pekerja yang Anda miliki? Berapa banyak tugas yang Anda jalankan? Seberapa sering Anda menjalankan tugas ini dan biasanya berapa lama untuk menyelesaikannya?

Alasan mengapa Rabbitmq / seledri mulai menggunakan banyak ram dapat dikaitkan dengan jumlah tugas yang antri. Jika Anda mengantri terlalu banyak tugas dan pekerja tidak dapat menyelesaikan semuanya, itu akan memperbesar antrian dan antrian ini akan menggunakan lebih banyak RAM dan akhirnya akan menghabiskan semua RAM yang tersedia. Saya yakin masalah ini mungkin terjadi pada Redis juga.

Saya punya teori lain tetapi pertama-tama saya ingin tahu apakah ini mungkin alasan untuk masalah Anda.

@ardilom maaf Saya baru menyadari bahwa kami tidak mengirim data RabbitMQ ke datadog, tetapi saya akan mencoba menjelaskan situasi kami, ini adalah bagaimana beberapa RAM server turun setiap 2 hari:
memory-leaks-1

Kami selalu memeriksa jumlah tugas yang tertunda, dan biasanya sekitar 0 (data ini dari beberapa hari yang lalu):

memory-leaks-2

Kami menjalankan sekitar 250.000 tugas per hari, kami memiliki sekitar 10 pekerja, masing-masing dengan sekitar 4 hingga 10 konkurensi, waktu proses rata-rata sekitar 5 detik, tergantung pada jenis tugasnya.

Kami selalu memeriksa messages_ready untuk memastikan tidak ada terlalu banyak tugas yang antri (ini yang Anda lihat di gambar kedua), apakah menurut Anda tidak masalah untuk mengukur messages_ready ? Kami akhirnya memiliki beberapa puncak, tetapi biasanya ini mendekati 0.

Untuk mengatasi masalah ini, saya hanya me-restart pekerja Celery secara manual dan penggunaan RAM menjadi normal kembali.

Beri tahu saya jika Anda memerlukan yang lain, saya baru saja mengubah pengaturan worker_max_tasks_per_child di salah satu server tugas, untuk melihat apakah ada perbedaan dengan yang lain setelah menerapkan konfigurasi.

Terima kasih!

Hai teman-teman, ini untuk mengonfirmasi bahwa mengubah worker_max_tasks_per_child menjadi 1000 dalam kasus saya, perbaiki masalah 🎉 terima kasih lagi @Skowt

Sesuatu yang tidak saya sebutkan kemarin, saya menggunakan mode "prefork", mungkin pindah ke gevent adalah cara lain untuk menyelesaikan masalah.

@arielcamino Masalah ini telah ditutup karena kami menyelesaikan kebocoran memori tertentu. Kami belum menemukan penyebab lain kebocoran memori. Kami tahu ada masalah tetapi kami tidak tahu bagaimana mereproduksinya.
Kami membutuhkan seseorang yang memiliki akses ke lingkungan produksi tempat bug mereproduksi untuk men-debug masalah.
Jika kami tidak memilikinya, kami harus memutuskan bahwa masalah ini tidak dapat ditindaklanjuti.

Halo, bisakah kita membuka kembali masalah ini? Kami mengalami kebocoran serupa, menggunakan seledri == 4.4.7 (dengan rabbitmq) kami memiliki pekerja yang berjalan stabil selama beberapa jam, terkadang lebih, dan kemudian tiba-tiba mulai bocor perlahan dan berakhir menggunakan semua memori.

Saat ini menggunakan prefork dengan --concurrency=1 dan flag --max-tasks-per-child=100 yang sepertinya tidak membantu karena proses induk tampaknya yang bocor.

celery_leak

Saya dapat memberikan informasi lebih lanjut untuk membantu men-debug masalah ini.

Halo, bisakah kita membuka kembali masalah ini? Kami mengalami kebocoran serupa, menggunakan seledri == 4.4.7 (dengan rabbitmq) kami memiliki pekerja yang berjalan stabil selama beberapa jam, terkadang lebih, dan kemudian tiba-tiba mulai bocor perlahan dan berakhir menggunakan semua memori.

Saat ini menggunakan prefork dengan --concurrency=1 dan flag --max-tasks-per-child=100 yang sepertinya tidak membantu karena proses induk tampaknya yang bocor.

celery_leak

Saya dapat memberikan informasi lebih lanjut untuk membantu men-debug masalah ini.

membuka kembali masalah bukanlah masalah besar, itu adalah kepentingan seseorang yang menghadapinya dalam produksi dan membantu melacak dan berkontribusi memperbaiki atau setidaknya mencari tahu akar penyebab kebocoran dalam produksi.

Saya pasti dapat membantu, tetapi saya kehabisan ide tentang apa yang harus dilakukan, saya menjalankan beberapa alat tetapi tidak dapat mengidentifikasi banyak tentang masalah tersebut. Satu-satunya hal yang agak mempersempitnya adalah snapshot tracemalloc yang saya ambil, yang menunjukkan peningkatan memori di tempat yang sama setiap beberapa menit atau lebih. Ini adalah 10 teratas yang membandingkan dua snapshot:

/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

Masalahnya masih ada
Hal ini terjadi ketika konteks aplikasi akses tugas seledri untuk melakukan suatu fungsi
Itu tidak akan melepaskan atau membuangnya setelah melakukan tugas

--max-tasks-per-child=

tidak membantu

Halo, bisakah kita membuka kembali masalah ini? Kami mengalami kebocoran serupa, menggunakan seledri == 4.4.7 (dengan rabbitmq) kami memiliki pekerja yang berjalan stabil selama beberapa jam, terkadang lebih, dan kemudian tiba-tiba mulai bocor perlahan dan berakhir menggunakan semua memori.
Saat ini menggunakan prefork dengan --concurrency=1 dan flag --max-tasks-per-child=100 yang sepertinya tidak membantu karena proses induk tampaknya yang bocor.
celery_leak
Saya dapat memberikan informasi lebih lanjut untuk membantu men-debug masalah ini.

membuka kembali masalah bukanlah masalah besar, itu adalah kepentingan seseorang yang menghadapinya dalam produksi dan membantu melacak dan berkontribusi memperbaiki atau setidaknya mencari tahu akar penyebab kebocoran dalam produksi.

bagi saya jika saya menambahkan --max-tasks-per-child itu berhasil.
seperti untuk contoh argumen ini --autoscale=5,2 --max-tasks-per-child=40 hasilnya seperti ini

Screenshot 2020-08-13 at 2 26 13 PM

Meskipun saya yakin pembaruan seledri baru-baru ini memperkenalkan kebocoran memori, saya tidak bisa sepenuhnya percaya diri. Saya akan membagikan bahwa pengaturan berikut menyelesaikan kebocoran.

Saya tidak dapat membedakan pengaturan mana yang valid oleh dokumentasi, jadi saya mengatur semua nilai ini dalam file pengaturan Django saya.

CELERY_CONCURRENCY = CELERY_WORKER_CONCURRENCY = 1
CELERY_MAX_TASKS_PER_CHILD = CELERY_WORKER_MAX_TASKS_PER_CHILD = 1

Ini tidak menyelesaikan kebocoran yang kami lihat, seperti yang juga terjadi di kumpulan gevent. Yang saya perhatikan adalah antrian seleryev cukup sibuk. Karena tracemalloc menunjukkan pengiriman acara sebagai salah satu kemungkinan sumber kebocoran, saya secara eksplisit menonaktifkan acara tugas dan mematikan contoh bunga kami, untuk saat ini tampaknya kebocoran tidak terjadi lagi, saya akan membiarkannya berjalan hingga akhir pekan dan membagikan hasilnya disini.

sumber yang mungkin untuk kebocoran Saya secara eksplisit menonaktifkan acara tugas dan mematikan contoh bunga kami

Titik data anekdotal dari seseorang yang telah mengamati masalah ini secara diam-diam sejak awal (dan tidak pernah mengalaminya secara langsung): Saya mengetahui satu proyek lain (dengan beban kerja yang tidak substansial untuk seledri) di mana melakukan hal di atas memiliki hasil yang sama dari menghentikan kebocoran memori. Karena hanya memiliki informasi bekas, saya _obviously_ tidak dapat mengonfirmasi bahwa itu bahkan masalah mendasar yang sama (AFAIK itu adalah rabbitmq, tidak tahu tentang gevent, dll.), Tetapi menarik bahwa itu berkorelasi.

Saya curiga itu ada hubungannya dengan koneksi rabbitmq, tumpukan kami telah mengamati kebocoran ini:

  • seledri (versi terbaru): baik prefork maupun gevent pool, keduanya menunjukkan pola kebocoran yang sama.
  • kelincimq (cloudamqp SaaS)
  • bunga

Kami telah memeriksa semua tugas kami apakah ada kebocoran dan tidak dapat menemukan kebocoran apa pun, jadi itulah mengapa kecurigaan saya sebagai sesuatu di sisi seledri.

Satu fakta menarik adalah bahwa saat ini kami memiliki banyak pekerja yang bekerja, dan saya perhatikan bahwa, begitu seseorang mulai bocor, ia juga menunjukkan bunga sebagai offline.

Ketika saya kehabisan ide di mana mencarinya, saya menonaktifkan bunga dan acara tugas dan akan terus memantau apakah kebocoran akan kembali atau tidak.

Saya terbuka untuk percaya itu adalah bagian lain dari tumpukan saya yang membocorkan memori pada saat ini. Seledri mungkin memiliki perilaku yang tidak disengaja di masa lalu yang berkontribusi untuk mengendalikan kebocoran memori, tetapi kita semua tampaknya tidak memiliki masalah yang cukup serupa untuk mengonfirmasi hal itu. Aku tahu banyak dari kita yang lari ...

  • Sejumlah besar tugas bersarang sekaligus, atau
  • Beberapa monolitik yang memulai pemrosesan multi-inti dalam pekerja

Dalam kasus ini, kita hanya perlu cerdas tentang mengizinkan atau melarang tingkat konkurensi tertentu, antrian tugas, dan tugas per pekerja anak. Selain itu, kita semua harus menggunakan pengamanan bawaan yang dapat menghentikan tugas-tugas yang membutuhkan banyak memori sebelum mereka memiliki kesempatan untuk merusak server kita.

Semakin banyak orang yang menjalankan proses yang terikat dengan CPU dan terikat dengan memori dalam seledri, yang sebenarnya tidak dibuat untuk itu, jadi menurut saya dokumentasi panduan memulai harus menyertakan lebih banyak detail tentang hal ini.

Seperti yang telah disebutkan dalam komentar saya sebelumnya, kami menjalankan pekerja dengan max-tasks-per-child dan konkurensi disetel ke 1 sejak lama. Itu tidak melakukan apa-apa tentang kebocoran memori. Selain itu, kami menggunakan Redis sebagai broker dan backend hasil.

Dari pengamatan saya, ketika RabbitMQ digunakan sebagai broker, jika pengaturan max-tasks-per-child menjadi 1 "memecahkan" kebocoran memori, kemungkinan besar masalah dengan implementasi tugas, bukan seledri.

Apa yang kami amati dan laporkan berbeda. Bahkan jika kita membiarkan pekerja menganggur selama beberapa hari, tanpa memproses satu tugas pun, itu masih membocorkan memori ke titik ketika mencapai batas memori dan dimatikan oleh pengawas. Anda dapat menemukan lebih banyak detail dan bagan memori di komentar sebelumnya.

Dengan pekerja yang memproses satu tugas sesuai jadwal, bagan memori akan lebih atau kurang menunjukkan seperti gelombang persegi, tetapi Anda dapat dengan jelas melihat bahwa penggunaan memori secara keseluruhan hanya meningkat.
Screenshot 2020-08-14 at 20 42 24

Saya telah berhasil memasukkan profil pekerja seledri di peta jalan kami. Saya akan membagikan dump memori dan detail lebih lanjut saat kami mulai mengerjakan ini.

Saya dapat mengonfirmasi bahwa mematikan bunga (dan secara eksplisit menonaktifkan acara tugas melalui pengaturan) memperbaiki kebocoran.

Seperti yang saya sebutkan sebelumnya, pada saat pekerja mulai bocor, saya perhatikan di bunga bahwa itu akan mati dan seledri selalu menunjukkan cukup sibuk, jadi saya melalui cara yang mudah dan mematikan bunga.

Sayangnya saya tidak dapat menemukan bagian kode yang menyebabkan kebocoran. Tapi setidaknya ada pekerjaan ini.

lalu mungkin ini bukan masalah seledri tapi bunga?

@auvipy flower memicu masalah, tetapi kebocoran pasti terjadi pada pekerja (seledri)

@auvipy flower memicu masalah, tetapi kebocoran pasti terjadi pada pekerja (seledri)

cukup adil. Terima kasih telah berbagi.

Saya menggunakan Celery dengan Redis dan Flower, dan saya harus mengatakan bahwa saat ini saya tidak melihat masalah memori apa pun. Ada yang Anda inginkan dari saya terkait data?

@auvipy tidak menggunakan Flower. Pekerja dimulai dengan acara dinonaktifkan.

@auvipy tidak menggunakan Flower. Pekerja dimulai dengan acara dinonaktifkan.

coba debug dan temukan akar dari kebocoran memori. bisa seledri atau bisa. akan lebih baik jika Anda dapat membagikan pengujian unit dan integrasi

coba debug dan temukan akar dari kebocoran memori. bisa seledri atau bisa. akan lebih baik jika Anda dapat membagikan pengujian unit dan integrasi

Disebutkan di sini , bahwa kita melihat OOM karena pekerja seledri membocorkan memori meskipun tidak ada tugas yang diproses oleh pekerja.
Tidak dapat membagikan pengujian unit atau integrasi karena ini akan mengekspos IP perusahaan. Maaf. Tapi saya telah berhasil menambahkan tugas untuk menangkap dump memori pada pekerja produksi di peta jalan internal kami. Akan membagikan counter dan ref untuk beberapa skenario saat selesai.

@jsynowiec Jika Anda dapat membuatnya sebelum 5.0.0 GA (ikuti # 6266 untuk pembaruan) itu akan luar biasa.

Setelah perbaikan bug mendarat di master, itu akan di-backport ke 4.x juga.

@thedrow Kapan GA 5.0 direncanakan? Sayangnya, kami memiliki beberapa kode warisan yang masih akan dipindahkan ke Py3 😞 jadi kami terjebak dengan Celery 4 untuk saat ini.

Kami memiliki satu pemblokir rilis dan beberapa dokumentasi untuk diselesaikan.
Jawabannya segera.

Saya dapat mengonfirmasi bahwa mematikan bunga menghentikan kebocoran. Kami sudah berjalan tanpa kebocoran hampir sebulan sekarang.

Jadi masih ada bug di suatu tempat dalam mekanisme penerbitan acara kami.
Apakah ada yang tahu apa itu?

Kami tidak menggunakan Flower dan pekerja dimulai tanpa --events , namun kami mengalami kebocoran memori yang terus menerus.

Jawabannya segera.

Saya telah berhasil menetapkan prioritas tinggi untuk mendapatkan dump memori dan penghitung objek dari pekerja produksi. Saya harus dapat memposting beberapa data dalam minggu-minggu berikutnya. Kami juga telah meningkatkan prioritas untuk menyelesaikan port py2-> py3 sehingga semuanya harus berjalan, dan diprofilkan, menggunakan Python 3

Yang saya khawatirkan adalah kita membicarakan dua masalah berbeda di sini.

Tampaknya. Salah satunya terkait event dan mungkin Flower, mungkin juga menggunakan RabbitMQ sebagai broker. Menurut masalah yang dilaporkan di sini, di GitHub, itu muncul di sana-sini sejak beberapa tahun. Yang lainnya (yang memengaruhi proyek saya) terkait dengan berbagai komponen dan kemungkinan besar terkait dengan penggunaan Redis sebagai broker. Atau mungkin di root, itu adalah masalah yang sama yang berasal dari kode yang sama siapa tahu 🤷🏼. Seperti yang dengan trail melacak subtugas dan membocorkan contoh AsyncResult 😉

@thedrow @auvipy Sekadar memberi tahu Anda bahwa kami sekarang beralih ke profil memori pekerja.

Selain itu, saat menyelesaikan migrasi Python3, kami mengalami masalah lain yang tampaknya terkait dengan https://github.com/celery/celery/issues/4470 atau https://github.com/celery/celery/issues/5359. Dalam kondisi tertentu pada sistem Linux, saat menggunakan Redis sebagai broker, panggilan ke join_native hang tanpa batas meskipun semua tugas dalam grup sudah selesai. Quick strace menunjuk padanya secara harfiah tergantung pada pembacaan, yang mungkin menunjukkan beberapa hal kernel / lib tingkat rendah. Untuk saat ini kami beralih ke polos, mengumpulkan join karena kami fokus pada kebocoran memori.

Halo semuanya - akhirnya _some_ data: celery-memtrace-1.tar.xz , signature , my key .

Arsip tersebut berisi tracemalloc log dari 8 pekerja setelah ~ 16 hari, grafik penggunaan memori untuk periode tersebut dan beberapa informasi versi (termasuk spanduk startup Celery).

Sejujurnya saya belum menghabiskan banyak waktu untuk menganalisis semua ini, tetapi a) kode kami tidak pernah ada dalam daftar, b) mungkin juga ada beberapa interaksi aneh dengan SQLAlchemy yang juga kami gunakan di mana-mana, jadi bukan tidak mungkin masalahnya di tempat lain, atau itu masalah kombinasi / interaksi.

Jika ada detail lain yang berguna, harap tanyakan. Kami juga terus menjalankan 8 pekerja tersebut dengan pencatatan penggunaan memori ini, jadi mungkin akan dapat mengumpulkan lebih banyak / lebih baik data.

EDIT : Juga komentar dari utas ini terkait - kami masih menggunakan pengaturan yang sama.

Saya harap Anda akan menemukan akar penyebab kebocoran ini.
Saya akan mencoba meluangkan waktu untuk menggali sendiri.

Saya ingin tahu apakah ini bisa membantu mengurangi masalah.
https://reliability.substack.com/p/run-python-servers-more-efficiently

Kami sedang menyelidiki kemungkinan bahwa asal kebocoran memori ada di dalam pustaka permintaan, bukan seledri itu sendiri. Adakah orang lain yang mengalami kebocoran memori dalam seledri menggunakan permintaan dalam tugas?

@ErrorInPersona Ya, kami mendaftarkan OOM pada pekerja dengan dan tanpa permintaan yang sama.

@drbig Ada keberuntungan?

Screenshot_2020-11-17_12-56-28

Nah, lihat "yang hijau", lantainya naik, perlahan tapi pasti ... Jadi kecuali konfirmasi cepat dari "ya, itu masih masalah" sayangnya tidak banyak menambahkan dari sisi saya.

Namun saya telah menelusuri tautan yang disediakan @thedrow dan daftar tugas saya (lubang tanpa dasar) sekarang termasuk - try running some workers with jemalloc forced in , jadi saya akan membahasnya, _eventually_.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat