2016-03-17 35 views
7

के लिए अलग डेटाबेस कनेक्शन बनाना I सृजन के बाद कार्य निष्पादित करते समय मजदूर mysql समस्याओं में चलते रहते हैं।प्रत्येक अजवाइन कार्यकर्ता

हम Django 1.3 का उपयोग करें, अजवाइन 3.1.17, djorm-ext-पूल 0.5

हम संगामिति 3. मेरे obeservation अब तक जब कार्यकर्ता प्रक्रिया शुरू, वे सब मिलता है, एक ही mysql के साथ अजवाइन की प्रक्रिया शुरू connecition। हम नीचे डीबी कनेक्शन आईडी लॉग इन करें।

from django.db import connection 
connection.cursor() 
logger.info("Task %s processing with db connection %s", str(task_id), str(connection.connection.thread_id())) 

जब सभी श्रमिकों कार्यों मिलता है, पहले एक को सफलतापूर्वक कार्यान्वित लेकिन अन्य दो अजीब त्रुटियों देता है। यह या तो "MySQL सर्वर चला गया" के साथ त्रुटियां, या ऐसी स्थिति के साथ जहां Django "DoNotExist" त्रुटि फेंकता है। स्पष्ट रूप से वस्तुओं जो Django पूछताछ कर रहे हैं मौजूद हैं।

इस त्रुटि के बाद, प्रत्येक कार्यकर्ता अपना डेटाबेस कनेक्शन प्राप्त करना शुरू कर देता है जिसके बाद हमें कोई समस्या नहीं मिलती है।

अजवाइन का डिफ़ॉल्ट व्यवहार क्या है? क्या यह एक ही डेटाबेस कनेक्शन साझा करने के लिए डिज़ाइन किया गया है। यदि ऐसा है तो इंटर प्रक्रिया संचार कैसे संभाला जाता है? मैं आदर्श रूप से प्रत्येक कार्यकर्ता के लिए अलग डेटाबेस कनेक्शन पसंद करूंगा।

मैंने नीचे दिए गए लिंक में उल्लिखित कोड का प्रयास किया जो काम नहीं करता था। Celery Worker Database Connection Pooling

हमने नीचे सुझाए गए सेलेरी कोड को भी ठीक किया है। https://github.com/celery/celery/issues/2453

जो लोग इस सवाल को कम करते हैं, कृपया मुझे डाउनवोट के कारण बताएं।

+0

क्या आप किसी भी Django कनेक्शन पूलिंग मिडलवेयर का उपयोग कर रहे हैं? Django कॉन्फ़िगरेशन में आपका 'CONN_MAX_AGE' क्या है? मुझे लगता है कि यह प्रभाव django में लगातार कनेक्शन व्यवहार है। यह आपके द्वारा देखे जा रहे व्यवहार से संबंधित हो सकता है, न कि सेलरी के साथ कुछ। –

+0

क्या आप सिर्फ concurrency = 1 चला सकते हैं और एकाधिक श्रमिकों को शुरू कर सकते हैं? –

+0

@AlexLuisArias यह केवल एक कार्यकर्ता प्रक्रिया चलाएगा और उपरोक्त मुद्दे के लिए कोई मामला नहीं है। –

उत्तर

2

अजवाइन मास्टर की प्रक्रिया के हिस्से के रूप में नीचे आदेश

celery -A myproject worker --loglevel=debug --concurrency=3 -Q testqueue 

myproject.py के साथ शुरू किया गया है कार्यकर्ता प्रक्रियाओं forking पहले mysql डेटाबेस के लिए आप कुछ पूछना चाहते बना रही थी।

मुख्य प्रक्रिया में क्वेरी प्रवाह के हिस्से के रूप में, django ORM एक sqlalchemy कनेक्शन पूल बनाता है यदि यह पहले से मौजूद नहीं है। कार्यकर्ता प्रक्रियाओं को तब बनाया जाता है।

डीजेंगो फिक्सअप के हिस्से के रूप में सेलेरी मौजूदा कनेक्शन बंद कर देता है।

def close_database(self, **kwargs): 
    if self._close_old_connections: 
     return self._close_old_connections() # Django 1.6 
    if not self.db_reuse_max: 
     return self._close_database() 
    if self._db_recycles >= self.db_reuse_max * 2: 
     self._db_recycles = 0 
     self._close_database() 
    self._db_recycles += 1 

प्रभाव क्या हो रहा हो सकता है कि, एक अप्रयुक्त db कनेक्शन के साथ SQLAlchemy पूल वस्तु 3 वर्कर प्रोसेस को कॉपी किया हो जाता है जब काँटेदार है। तो 3 अलग-अलग पूलों में 3 कनेक्शन ऑब्जेक्ट्स होते हैं जो एक ही कनेक्शन फ़ाइल डिस्क्रिप्टर को इंगित करते हैं।

डीबी कनेक्शन के लिए पूछे जाने पर कार्यों को निष्पादित करते समय श्रमिक, सभी श्रमिकों को एसक्लाल्चेमी पूल से एक ही अप्रयुक्त कनेक्शन मिलता है क्योंकि यह वर्तमान में अप्रयुक्त है। तथ्य यह है कि सभी कनेक्शन एक ही फ़ाइल डिस्क्रिप्टर को इंगित करते हैं, जिससे MySQL कनेक्शन त्रुटियों को दूर कर देता है।

नए बनाए गए नए कनेक्शन सभी नए हैं और उसी सॉकेट फ़ाइल डिस्क्रिप्टर को इंगित नहीं करते हैं।

समाधान:

मुख्य प्रक्रिया में

from django.db import connection 
connection.cursor() 

जोड़ने से पहले किसी भी आयात किया जाता है। i.e भी djorm-ext-pool मॉड्यूल जोड़ा गया है।

इस तरह सभी डीबी प्रश्न पूल के बाहर django द्वारा बनाए गए कनेक्शन का उपयोग करेंगे। जब सेलेरी django फिक्सअप कनेक्शन बंद कर देता है, कनेक्शन वास्तव में बंद हो जाता है क्योंकि किल्कि पूल में वापस जाने के विरोध में अलकेमी पूल छोड़कर सभी कर्मचारियों को मुकाबला करने के समय इसमें कोई कनेक्शन नहीं होता है। वहां श्रमिकों के डीबी कनेक्शन के लिए पूछने के बाद, sqlalchemy नए बनाए गए कनेक्शनों में से एक लौटाता है।

संबंधित मुद्दे