Celery: يتم تشغيل نفس المهمة عدة مرات في وقت واحد؟

تم إنشاؤها على ٢٠ نوفمبر ٢٠١٧  ·  43تعليقات  ·  مصدر: celery/celery

المشكلة هي إعادة نشر مشاركة مجموعات Google غير المراقبة _ يتم تشغيل نفس المهمة عدة مرات؟ _

> ./bin/celery -A celery_app report

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

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

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

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

يمكن أن يتكرر هذا عشرات المرات. لاحظ وقت تنفيذ المهمة الأولى 33 ثانية ، واستخدام عمال مختلفين!

ليس لدي أي تفسير لهذا السلوك ، وأود أن أفهم ما يجري هنا.

Redis Broker Redis Results Backend Feedback Needed ✘ Needs Testcase ✘

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

georgepsarakis إذاً إذا تمت جدولة المهمة في المستقبل ، فربما أرى ما سبق؟ "مهلة الرؤية" يعالج ذلك؟ من الوثائق التي ربطتها:

مهلة الرؤية الافتراضية لـ Redis هي ساعة واحدة.

بمعنى أنه إذا لم يقم العامل بتنفيذ المهمة في غضون ساعة (أي تشغيلها؟) ، فسيتم إرسال هذه المهمة إلى عامل آخر لن ينجح ، وهكذا ... في الواقع يبدو أن هذا هو الحال عند النظر إلى قسم التحذيرات في وثائق؛ هذه المشكلة ذات الصلة https://github.com/celery/kombu/issues/337 ؛ أو نقلا عن هذه المدونة :

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

يبدو أن تعيين visibility_timeout إلى 31،540،000 ثانية (سنة واحدة) قد يكون حلًا سريعًا.

ال 43 كومينتر

ربما هذا مرتبط مهلة الرؤية ؟

georgepsarakis هل يمكنك توضيح شكوكك؟

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

georgepsarakis إذاً إذا تمت جدولة المهمة في المستقبل ، فربما أرى ما سبق؟ "مهلة الرؤية" يعالج ذلك؟ من الوثائق التي ربطتها:

مهلة الرؤية الافتراضية لـ Redis هي ساعة واحدة.

بمعنى أنه إذا لم يقم العامل بتنفيذ المهمة في غضون ساعة (أي تشغيلها؟) ، فسيتم إرسال هذه المهمة إلى عامل آخر لن ينجح ، وهكذا ... في الواقع يبدو أن هذا هو الحال عند النظر إلى قسم التحذيرات في وثائق؛ هذه المشكلة ذات الصلة https://github.com/celery/kombu/issues/337 ؛ أو نقلا عن هذه المدونة :

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

يبدو أن تعيين visibility_timeout إلى 31،540،000 ثانية (سنة واحدة) قد يكون حلًا سريعًا.

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

لذلك إذا جمعت:

  • وسيط Redis
  • الإقرار المتأخر
  • ETA يساوي / أعلى مهلة الرؤية
    تحصل على عمليات تنفيذ متعددة في المهمة.

أعتقد أن ما يحدث هو:

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

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

آمل أن يفسر هذا قليلاً العناصر الداخلية للنقل Redis.

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

افتراضي (غير صحيح؟) هو أن:

  • أحدد موعدًا لمهمة مع ETA في أي وقت في المستقبل ؛ ومن بعد
  • المهمة (أي وسائطها المنظمة) و ETA ستجلس في قائمة الانتظار حتى وصول ETA ؛ ومن بعد
  • يبدأ العامل في معالجة المهمة في ETA.

"_أعتقد أن ما يحدث هو: _" أعلاه يختلف تمامًا عن افتراضي.

لقد واجهت أيضًا نفس المشكلة ، هل قمت بحلها؟ تضمين التغريدة

شكرا!

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

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

zivsu ، كما هو مذكور أعلاه ، قمت بتعيين visibility_timeout إلى رقم كبير _very_ ويبدو أن هذا قد أدى إلى حل الأعراض. ومع ذلك ، كما يشير georgepsarakis ، يبدو أن هذا نهج ضعيف.

لا أعرف سبب المشكلة الأصلية ولا كيفية معالجتها بشكل صحيح.

jenstroeger لقد قرأت بعض المدونات ، وتغيير visibility_timeout لا يمكن أن يحل المشكلة تمامًا ، لذلك قمت بتغيير borker إلى rabbitmq .

zivsu ، هل يمكنك من فضلك مشاركة رابط المدونة؟ هل استخدمت Redis من قبل؟

jenstroeger لا يمكنني العثور على المدونة ، لقد استخدمت Redis كوسيط من قبل. بالنسبة لجدول المهام ، اخترت rebbitmq لتجنب حدوث الخطأ مرة أخرى.

لدي نفس المشكلة بالضبط ، التكوين الخاص بي هو:
دجانغو == 1.11.6
الكرفس == 4.2rc2
django-celery-beat == 1.0.1

الإعدادات:

CELERY_ENABLE_UTC = True
# CELERY_TIMEZONE = 'America/Los_Angeles'

وهذا هو المزيج الوحيد العامل من هذه الإعدادات. كما يجب أن أجد مهامي الدورية في التوقيت العالمي المنسق (UTC).
إذا قمت بتمكين CELERY_TIMEZONE أو قمت بتعطيل CELERY_ENABLE_UTC فسيبدأ تشغيل المهام الدورية عدة مرات.

لدي مشكلة الحفظ. تتضاعف مهمة eta مرات عند استخدام redis كوسيط.
بأي حال من الأحوال أن يحل هذا..
يبدو وسيط التغيير من redis إلى rabbitmq لحل هذه المشكلة ..

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

from celery import Celery


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

أتمنى أن يساعد ذلك أي شخص آخر يواجه هذه المشكلة.

أحصل على هذه المشكلة في بعض الأحيان عند إعادة تشغيل وظائف الكرفس بشكل متكرر مع الإيقاع على الأجهزة متعددة النواة. لقد اعتدت تشغيل ps aux | grep celery ثم kill <each_pid> لحلها.

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

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

إذا تحققنا من الطوابع الزمنية للمهمة المستلمة ، فستحصل كل ساعة على مهمة جديدة بنفس المعرف. والنتيجة هي أن جميع رسائل ETA يتم إرسالها أكثر من 10 مرات. يبدو أن rabbitmq هو الخيار الوحيد إذا أردنا استخدام ETA

Rcently تلبية علة مماثلة. أظهر أيضًا ps aux | grep celery عمليات أكثر من التي بدأها العمال ، مرتين أكثر. أدى إلحاق المعلمة --pool gevent لأمر إطلاق عمال الكرفس إلى خفض عدد العمليات لتحديد عدد العمال المبتدئين ونبض الكرفس. والآن أريد أن أقوم بتنفيذ مهامي.

هل يمكن أن يكون الحل الآخر هو تعطيل محاكاة ack تمامًا؟ أي "broker_transport_options": {"ack_emulation": False} . أي عيوب للمهام قصيرة المدى / العد التنازلي؟

هل حصل أي شخص على الإصلاح؟

لقد واجهت نفس المشكلة ، أي حل لها؟

اهتزاز نفس المشكلة.

نفس المشكلة هنا ، باستخدام Redis كوسيط.

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

نفس المشكلة هنا. إصدار الكرفس 4.3.0
celery = Celery ('features'، broker = 'pyamqp: // nosd: sdsd @ rabbit //'، config_from_object = {"broker_transport_options": {'visibility_timeout': 18000}})

الأمر الذي أستخدمه لتشغيل عاملي
الكرفس - عامل مهام --pidfile = / tmp / celery_worker.pid -f = / tmp / celery_worker.log -Q celery_queue --loglevel = info --pool = solo --concurrency = 1 -n worker_celery - فصل - بدون ثرثرة - بدون اختلاط - بدون ضربات قلب

هل يمكنك تجربة الكرفس == 4.4.0rc4؟

يتلقى الكرفس نفس المهمة مرتين ، مع نفس معرف المهمة في نفس الوقت.
هنا السجلات

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

كلاهما يعملان في وقت واحد ،

باستخدام الكرفس == 4.4.0rc4 ، boto3 == 1.9.232 ، kombu == 4.6.6 مع SQS في دورق البايهتون.
في SQS ، تكون مهلة الرؤية الافتراضية 30 دقيقة ، ومهمتي ليست الحصول على ETA وليس ack.

تشغيل عامل مثل ،
عامل الكرفس -A app.jobs.run -l info --pidfile = / var / run / celery / celery.pid --logfile = / var / log / celery / celery.log - time-limit = 7200 --concurrency = 8

auvipy ، أي مساعدة ستكون رائعة.

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

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

باستخدام SQS ، تكون الواجهة الخلفية للنتيجة هي MYSQL ، مع sqlalchemy.
التفاصيل هنا في SO ، https://stackoverflow.com/questions/59123536/celery-is-receiving-same-task-twice-with-same-task-id-at-same-time
auvipy هل يمكنك إلقاء نظرة.

thedrow هل تواجه هذه المشكلة في بلومبيرج؟

@ nitish-itilite: ما المنطقة الزمنية التي تستخدمها للكرفس؟

@ nitish-itilite: ما المنطقة الزمنية التي تستخدمها للكرفس؟

إنه افتراضي التوقيت العالمي المنسق (UTC). بال مربعات ، المنطقة هي شرق الولايات المتحدة (شمال فيرجينيا).

كان لدي حالة مماثلة تشغيل الكرفس مع SQS. قمت بتشغيل مهمة وهمية مع countdown=60 ، بينما مهلة الرؤية في SQS هي 30 ثانية. هذا ما أحصل عليه:

ملاحظة: لقد بدأت الكرفس بـ --concurrency=1 ، لذا هناك خيطان ، أليس كذلك؟

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

ما حدث بالترتيب الزمني:

  1. 14:46:32 تم استلام المهمة ، ووضعها SQS في وضع inflight لمدة 30 ثانية
  2. 14:47:02 تم استلام نفس المهمة ، لأن مهلة الرؤية انتهت صلاحيتها
  3. 14:47:32 يتم تنفيذ كلا المهمتين في نفس الوقت

تخميني هو أن هذا خطأ في الكرفس (؟) ، أعتقد أنه كان يجب التحقق مما إذا كان معرّف الرسالة ( b483a22f-31cc-4335-9709-86041baa8f05 ) قد أخذ بالفعل بواسطة هذا العامل.

ربما يمكن أن تكون هناك قائمة تجزئة تحتوي على جميع معرفات الرسائل ، بحيث يمكن للكرفس أن يقرر ما إذا كانت المهمة المستلمة صالحة للمعالجة. هل يمكن للكرفس أن يفعل ذلك؟

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

يبدو أن هذا يحدث لي أيضًا.

[2020-05-11 15: 31: 23673: INFO / MainProcess] المهمة المستلمة: ee_external_attributes.tasks. إعادة القيم_المحددة [53046bd7-2a19-4f72-808f-d712eaecb0e8]
[2020-05-11 15: 31: 28،673: INFO / MainProcess] المهمة المستلمة: ee_external_attributes.tasks.recreate_specific_values ​​[53046bd7-2a19-4f72-808f-d712eaecb0e8]

(لقد قمت بتعديل اسم المهمة في السجلات للنشر العام.)

نظرًا لقيود التفرد ، ألقى أحد العاملين لديّ خطأً في منتصف المهمة ، وينجح الآخر.

حاولت الإعداد
CELERY_WORKER_PREFETCH_MULTIPLIER = 1
اتضح أن ذلك لم يساعد.

أنا استخدم
الكرفس == 4.4.1
django-celery-results == 1.2.1

وأنا أستخدم AWS SQS لقائمة الانتظار.

لدي نظرية. يبدو أن إعداد "مهلة الرؤية الافتراضية" في قائمة الانتظار الخاصة بي قد تم تعيينه على 5 ثوانٍ فقط. قد يكون أن العامل الثاني سحب الوظيفة بينما كان الأول يعمل عليها ، لأنه افترض أن العامل الأول قد مات. لقد رفعت مهلة الرؤية إلى دقيقتين ، ويبدو أنها تعمل بشكل أفضل. كان لدي الكثير من المهام التي استغرقت 8-12 ثانية ، لذلك قد تكون دقيقتان مبالغة. لكن نأمل أن يحل ذلك.

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

JulieGoldberg ، ستكون هذه طريقة سيئة للكرفس للتعامل مع الوظائف. يجب ألا يبدأ عامل الكرفس أبدًا وظيفة قام عامل آخر بسحبها من قائمة الانتظار ويقوم بمعالجتها بنشاط ؛ أعتقد أنه سيتم كسرها بشكل خطير. (لكنه كرفس ، لا أفاجأ بشيء بعد الآن 😒)

لدي مشكلة مماثلة مع تطبيق يعمل في Kubernetes. في مثال Kubernetes ، لدينا 10 عمال (مثيل تطبيق الكرفس) يستهلكون المهام من Redis.

أعراض:
يقوم عامل الكرفس بجدولة مهمة ETA التي سيتم التخطيط لها بعد 30 دقيقة. إذا تم تدوير حافظة Kubernetes (قتل العامل بواسطة Kubernetes) أو تم نشر إصدار أحدث من التطبيق (تم قتل جميع العمال وإنشاء عمال جدد) ، فسيأخذ جميع العمال المهمة المجدولة ويبدأون في التنفيذ في الوقت المحدد.
بالنسبة للعامل ، حاولت تعيين قيم مختلفة visibility_timeout لعدة ساعات حتى عام واحد ، لكن النتيجة ظلت كما هي. تم الوصول إلى نفس السلوك مع الإعداد enable_utc = True ، أو تقليل worker_prefetch_multiplier = 1 .

لا أعرف ما إذا كان هذا سيساعد أي شخص ولكن هذه كانت مشكلتي:

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

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

JulieGoldberg ، ستكون هذه طريقة سيئة للكرفس للتعامل مع الوظائف. يجب ألا يبدأ عامل الكرفس أبدًا وظيفة قام عامل آخر بسحبها من قائمة الانتظار ويقوم بمعالجتها بنشاط ؛ أعتقد أنه سيتم كسرها بشكل خطير. (لكنه كرفس ، لا أفاجأ بشيء بعد الآن 😒)

بدلاً من الشكوى ، يمكنك مساعدتنا في حل المشكلة من خلال التوصل إلى حل و PR.

لدي مشكلة مماثلة مع تطبيق يعمل في Kubernetes. في مثال Kubernetes ، لدينا 10 عمال (مثيل تطبيق الكرفس) يستهلكون المهام من Redis.

أعراض:
يقوم عامل الكرفس بجدولة مهمة ETA التي سيتم التخطيط لها بعد 30 دقيقة. إذا تم تدوير حافظة Kubernetes (قتل العامل بواسطة Kubernetes) أو تم نشر إصدار أحدث من التطبيق (تم قتل جميع العمال وإنشاء عمال جدد) ، فسيأخذ جميع العمال المهمة المجدولة ويبدأون في التنفيذ في الوقت المحدد.

elMateso لقد واجهت مشكلات مماثلة مع نشر Airflow على k8s (المستهلكين على البودات و redis كقائمة انتظار). لكنني تمكنت من جعل النشر مستقرًا والعمل كما هو متوقع ، ربما تساعدك هذه النصائح:
https://www.polidea.com/blog/application-scalability-kubernetes/#tips -for-hpa

تواجه نفس الشيء هنا.

لا يبدو أن هناك مشكلة في أي تكوين للتوقيت (مهلة الرؤية ، و ETA ، إلخ ..) ، بالنسبة لي على الأقل. في حالتي يحدث ذلك ميكروثانية بين عمليات الإعدام. لم أجد كيف يعمل الكرفس في الواقع على إرسال رسالة ، ولكن إذا كان يعمل بشكل مثالي في rabbitMQ ، فيبدو أنه يمثل مشكلة في التزامن و ACK في Redis.

أرى نفس المشكلة ونستخدم Redis كوسيط أيضًا. التغيير إلى rabbitMQ ليس خيارًا بالنسبة لنا.

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

على سبيل المثال https://docs.celeryproject.org/en/latest/tutorials/task-cookbook.html#ensuring -a-task-is-only -esent-one-at-a-time

ErikKalkoken ينتهي بنا الأمر بفعل ذلك بالضبط.

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

    return wrapper

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

هل يمكن لأحد التحقق من هذا العلاقات العامة https://github.com/vinayinvicible/kombu/commit/a755ba14def558f2983b3ff3358086ba55521dcc

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