2015-07-23 10 views
12

मेरे मकड़ी में गंभीर मेमोरी लीक है .. 15 मिनट के बाद इसकी मेमोरी 5 जीबी और स्केपर बताती है (prefs() का उपयोग करके) कि 900k ऑब्जेक्ट्स अनुरोध करता है और यह सब कुछ है। इस उच्च संख्या में जीवित अनुरोध वस्तुओं का कारण क्या हो सकता है? अनुरोध केवल ऊपर जाता है और नीचे नहीं जाता है। अन्य सभी वस्तुओं शून्य के करीब हैं।स्केपर स्पाइडर मेमोरी लीक

मेरे मकड़ी इस तरह दिखता है: वरीयता() के उत्पादन में

class ExternalLinkSpider(CrawlSpider): 
    name = 'external_link_spider' 
    allowed_domains = [''] 
    start_urls = [''] 

    rules = (Rule(LxmlLinkExtractor(allow=()), callback='parse_obj', follow=True),) 

    def parse_obj(self, response): 
    if not isinstance(response, HtmlResponse): 
     return 
    for link in LxmlLinkExtractor(allow=(), deny=self.allowed_domains).extract_links(response): 
     if not link.nofollow: 
      yield LinkCrawlItem(domain=link.url) 

यहाँ

HtmlResponse      2 oldest: 0s ago 
ExternalLinkSpider     1 oldest: 3285s ago 
LinkCrawlItem      2 oldest: 0s ago 
Request      1663405 oldest: 3284s ago 

100k स्क्रैप के लिए मेमोरी पृष्ठों (उदाहरण के लिए victorinox.com पर कुछ साइटों पर 40gb निशान हिट कर सकते हैं यह 100k स्क्रैप किए गए पृष्ठों के निशान पर 35 जीबी मेमोरी तक पहुंचें)। दूसरे पर यह बहुत कम है।

यूपीडी।

Objgraph for oldest request after some time of run

enter image description here

उत्तर

7

कुछ संभावित मुद्दों मैं अभी देख रहे हैं।

हालांकि शुरू करने से पहले, मैं यह उल्लेख करना चाहता था कि prefs() कतारबद्ध अनुरोधों की संख्या नहीं दिखाता है, यह जीवित अनुरोध() ऑब्जेक्ट्स की संख्या दिखाता है। अनुरोध ऑब्जेक्ट को संदर्भित करना और इसे जीवित रखना संभव है, भले ही इसे डाउनलोड करने के लिए कतारबद्ध न हो।

मुझे आपके द्वारा प्रदान किए गए कोड में वास्तव में कुछ भी नहीं दिखाई देता है जो इसका कारण बनता है, हालांकि आपको इसे ध्यान में रखना चाहिए।

बल्ले से बाहर, मैं पूछूंगा: क्या आप कुकीज़ का उपयोग कर रहे हैं? यदि नहीं, तो साइटें जो एक जीईटी वैरिएबल के रूप में सत्र आईडी के आसपास गुज़रती हैं, प्रत्येक पृष्ठ विज़िट के लिए एक नया सत्र आईडी उत्पन्न करेगी। आप अनिवार्य रूप से एक ही पृष्ठ को बार-बार कतारबद्ध करना जारी रखेंगे। उदाहरण के लिए, victorinox.com में कुछ नए पेज लोड के लिए आईडी बदलते हुए, URL की स्ट्रिंग में "jsessionid = 18537CBA2F198E3C1A5C9EE17B6C63AD" जैसा कुछ होगा।

दूसरा, आप यह कर सकते हैं कि आप एक मकड़ी जाल मार रहे हैं। यही वह पृष्ठ है जो एक नई अनंत लिंक के साथ, खुद को पुनः लोड करता है। "अगले महीने" और "पिछले महीने" के लिंक वाले कैलेंडर के बारे में सोचें। हालांकि, मैं victorinox.com पर सीधे किसी को नहीं देख रहा हूं।

तीसरा, प्रदत्त कोड से आपका स्पाइडर किसी विशिष्ट डोमेन पर बाध्य नहीं है। यह प्रत्येक पृष्ठ पर मिलने वाले प्रत्येक लिंक को निकाल देगा, प्रत्येक पर parse_obj चला रहा है। उदाहरण के लिए victorinox.com का मुख्य पृष्ठ http://www.youtube.com/victorinoxswissarmy का एक लिंक है। यह बदले में आपके अनुरोधों को कई YouTube लिंक के साथ भर देगा।

हालांकि, क्या हो रहा है, यह जानने के लिए आपको और समस्या निवारण करने की आवश्यकता होगी।

कुछ रणनीतियों आप उपयोग करना चाहते हो सकता है:

  1. एक नया डाउनलोडर मिडिलवेयर (डेटाबेस एक फाइल करने के लिए, या) बनाएँ और अपने अनुरोध के सभी लॉग इन करें। विषम व्यवहार के अनुरोधों की समीक्षा करें।
  2. गहराई को सीमित करें ताकि इसे खरगोश छेद को अनंत काल तक जारी रखने से रोका जा सके।
  3. यह जांचने के लिए डोमेन को सीमित करें कि यह अभी भी एक समस्या है।

आप पाते हैं आप वैध तरीके से सिर्फ कई अनुरोध करने के लिए पैदा कर रहे हैं, और स्मृति एक मुद्दा है, तो लगातार काम कतार सक्षम और डिस्क के लिए अनुरोध बचाने के लिए, बजाय। मैं इसके खिलाफ एक पहले चरण के रूप में सिफारिश करता हूं, हालांकि, यह अधिक संभावना है कि आपका क्रॉलर काम नहीं कर रहा है जैसा आप चाहते थे।

+0

तीसरा - मेरा कोड एक डोमेन तक सीमित है। लेकिन डोमेन किसी भी द्वारा कर सकते हैं। आईएम सेटिंग ने डोमेन को गतिशील रूप से अनुमति दी है, इसलिए मैं एक समय में केवल एक डोमेन को पकड़ रहा हूं। कुकीज़ के लिए - अच्छा बिंदु। निरंतर कतार - मैंने स्केपर उपयोगकर्ता समूह में बताया है कि वे बड़ी संख्या में अनुरोधों के साथ बहुत धीमे हैं, इसलिए यह कोई विकल्प नहीं है :( – Aldarund

+0

ठीक है, जो आपके कोड में नहीं दिखाया गया था, यही कारण है कि मैंने इसका उल्लेख किया! निरंतर कतार है धीमा, हालांकि, और यह पंक्तियों को रोकने/फिर से शुरू करने के लिए और अधिक डिज़ाइन किया गया है, मुझे विश्वास है। इस उदाहरण में गति अंतर वास्तव में मेमोरी बनाम डिस्क है। – Rejected

+0

मैं भी एक FifoMemoryQueue कतार सेट करता हूं लेकिन अभी भी सबसे पुराना अनुरोध ऑब्जेक्ट स्पाइडर जितना पुराना है ऑब्जेक्ट। इसे संसाधित नहीं किया जाना चाहिए और जारी किया जाना चाहिए? – Aldarund

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