2016-03-22 3 views
5

मैं Laravel में एक स्क्रिप्ट है कि लाइन द्वारा एक JSON फ़ाइल लाइन पढ़ता है और मेरी डेटाबेस में सामग्री का आयात करता है का निर्माण किया है के साथ mysql में एक लाख पंक्तियों डालने स्मृति समाप्त हो रहा रोकूँ।मैं कैसे जब php

हालांकि, जब स्क्रिप्ट चलाने, मैं स्मृति त्रुटि के बाहर 80K के बारे में रिकॉर्ड डालने के बाद मिलता है।

mmap() failed: [12] Cannot allocate memory 

mmap() failed: [12] Cannot allocate memory 
PHP Fatal error: Out of memory (allocated 421527552) (tried to allocate 12288 bytes) in /home/vagrant/Code/sandbox/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php on line 1758 

mmap() failed: [12] Cannot allocate memory 
PHP Fatal error: Out of memory (allocated 421527552) (tried to allocate 32768 bytes) in /home/vagrant/Code/sandbox/vendor/symfony/debug/Exception/FatalErrorException.php on line 1 

मैं केवल प्रतिबद्ध एकत्रित आइटम को हर 100 के लिए अस्थायी कतार का एक तरह का निर्माण किया है, लेकिन यह कोई फर्क नहीं बनाया है।

public function callback($json) { 

    if($json) { 

     $this->queue[] = [ 

      'type' => serialize($json['type']), 
      'properties' => serialize($json['properties']), 
      'geometry' => serialize($json['geometry']) 
     ]; 

     if (count($this->queue) == $this->queueLength) { 

      DB::table('features')->insert($this->queue); 

      $this->queue = []; 
     } 
    } 
} 

यह वास्तविक आवेषण (DB::table('features')->insert($this->queue);) कि त्रुटि उत्पन्न कर रहे है, अगर मैं उन बाहर छोड़ मैं पूरी तरह से सब कुछ खत्म पुनरावृति कर सकते हैं:

यह वही मेरी कोड है कि आवेषण करता है का हिस्सा लगता है कि है लाइनों और किसी भी प्रदर्शन के मुद्दों के बिना उन्हें गूंज।

मुझे लगता है कि मैं अधिक स्मृति आवंटित कर सकता हूं, लेकिन संदेह है कि यह एक समाधान होगा क्योंकि मैं 3 मिलियन रिकॉर्ड डालने की कोशिश कर रहा हूं और यह वर्तमान में 8012 के बाद आवंटित 512 एमबी स्मृति के साथ विफल रहा है। इसके अलावा, मैं वास्तव में कम स्क्रिप्ट सर्वर पर इस स्क्रिप्ट को चलाने के लिए चाहता हूं।

समय यह इस स्क्रिप्ट के लिए ले जाता है चलाने के लिए तो अगर मैं किसी भी तरह के रिकॉर्ड की प्रविष्टि को धीमा कर सकता है नीचे है कि एक समाधान मैं के लिए समझौता कर सकता है हो सकता है, किसी भी चिंता का विषय नहीं है।

+0

लारवेल ओवरहेड होने के लिए बाध्य है, इसलिए मैं इसे –

+1

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

+0

आप एक में पास कर सकते हैं अपनी कॉलबैक() विधि में एन पंक्तियों की सीमा निर्धारित करें, जो भी आप * प्रक्रिया कर सकते हैं * एक ही समय में प्रक्रिया कर सकते हैं। अपनी विधि के अंत में, अपनी पंक्ति में अगले बैच को संसाधित करने के लिए एन पंक्तियों + एन की वृद्धि के साथ अपने पृष्ठ पर वापस रीडायरेक्ट करें जब तक यह खाली न हो। – Landjea

उत्तर

0

अपने आवेदन मचान पर मैं itsgoingd/clockwork पैकेज स्थापित। यह एक आदत है जिसे मैंने प्राप्त किया है क्योंकि यह इतना उपयोगी टूल है। (मैं इसे देखने के लिए इसे पढ़ने वाले किसी भी लैरावेल देवों को अनुशंसा करता हूं!)

बेशक यह पैकेज डिबगिंग उद्देश्यों के लिए क्वेरी लॉग करता है और इस प्रकार, अपराधी मेरी सारी याददाश्त खा रहा था।

मेरी कॉन्फ़िगरेशन में अपने सेवा प्रदाता के संदर्भ को हटाकर पैकेज को अक्षम करने से समस्या हल हो गई।

चीयर्स को @ dbushy727 पर मुझे यह समझने के लिए सही दिशा में धक्का देने के लिए।

0

समस्या के बारे में, मुझे लगता है कि आप संदेश कतार (Gearman, खरगोश ...) का उपयोग करना चाहिए इस समस्या को ठीक करने के लिए।

सभी रिकॉर्ड प्राप्त करें और क़तार में धक्का। कतार एक

4

पर प्रक्रिया करेगा यदि आप MySQL 5.7+ का उपयोग करते हैं, तो इसमें LOAD DATA INFILE का उपयोग कर JSON फ़ाइल से डेटा आयात करने की सुविधा है।

LOAD DATA INFILE 'afile.json' INTO TABLE atable (field1, field2, ....); 

आप तो कम MySQL संस्करण का उपयोग करते हैं आप CSV प्रारूप में JSON कन्वर्ट करने के लिए पहली जरूरत है। https://github.com/danmandle/JSON2CSV

LOAD DATA INFILE 'afile.csv' INTO TABLE atable (field1, field2, ....); 

LOAD DATA INFILE के documentation देखें का उपयोग कर उदाहरण के लिए।

+0

अरे, ऐसा कुछ है जिसे मैं नहीं जानता था! दुर्भाग्य से मुझे अपने डेटाबेस में प्रवेश करने से पहले इस डेटा को संरचित करने के तरीके को काफी बदलना होगा। – Vercoutere

+0

लोड डेटा इन्फ्लू सबसे अच्छा है यदि आपके पास एक बार में बहुत बड़ा डेटा डाला जाना है। यह INSERT –

+0

से बहुत तेज होगा, मैं कभी-कभी जिज्ञासा से इसे आजमा सकता हूं। मेरा वर्तमान समाधान हालांकि बहुत तेज़ है! मुझे 3 मिलियन पंक्तियों को आयात करने में लगभग 15 मिनट लगते हैं जिन्हें मैं खुश करता हूं। – Vercoutere

1

यह सुनिश्चित करने के लिए जांचें कि आपकी क्वेरी लॉगिंग बंद है। यदि आपकी क्वेरी लॉगिंग चालू है, भले ही आप $-> कतार को साफ़ कर रहे हों, क्वेरी लॉग तब तक बढ़ रहा है जब तक कि यह एक अप्रबंधनीय आकार तक नहीं बढ़ता है और आप अपनी मेमोरी सीमा को दबाते हैं। यदि क्वेरी लॉगिंग चालू या बंद है

जाँच करने के लिए, इस तरह डीबी मुखौटा का उपयोग करें: यह सच देता है, तो

DB::logging() 

, तो अपने प्रवेश पर है, और यह आपकी समस्या है। यदि यह झूठा रिटर्न देता है, तो यह कुछ अन्य कॉन्फ़िगरेशन है जो आपके प्रश्नों पर हो रहा है।

+0

क्वेरी लॉगिंग बंद है। हालांकि, आपकी टिप्पणी ने मुझे मेरे सुझाव में वर्णित मुद्दे को खोजने के लिए आवश्यक संकेत दिया! – Vercoutere