2009-09-15 11 views
35

एक सिस्टम में मैं वर्तमान में काम कर रहा हूं, एक ऐसी प्रक्रिया है जो सॉर्टिंग/एग्रीगेटिंग/जो भी हो, के लिए सरणी में बड़ी मात्रा में डेटा लोड करती है। मुझे पता है कि इस प्रक्रिया को स्मृति उपयोग के लिए अनुकूलित करने की आवश्यकता है, लेकिन अल्प अवधि में इसे केवल काम करने की आवश्यकता है।PHP memory_limit बढ़ाना। यह किस बिंदु पर पागल हो जाता है?

सरणी में लोड किए गए डेटा की मात्रा को देखते हुए, हम स्मृति सीमा को मारते रहते हैं। यह कई बार बढ़ गया है, और मुझे आश्चर्य है कि वहां एक बिंदु है जहां इसे बढ़ाना आम तौर पर एक बुरा विचार बन जाता है? या यह केवल है कि मशीन की कितनी रैम है?

मशीन में 2 जीबी रैम है और स्मृति_लिमिट वर्तमान में 1.5 जीबी पर सेट है। हम आसानी से मशीन में और अधिक रैम जोड़ सकते हैं (और वैसे भी)।

क्या दूसरों को इस तरह की समस्या का सामना करना पड़ा है? और समाधान क्या थे?

+6

ईमानदारी से आपको स्मृति सीमा निर्धारित करने से चिंतित नहीं होना चाहिए, लेकिन यह पता लगाने के साथ कि आपकी मेमोरी लीक कहां है और इसे ठीक कर रहा है। यह स्मृति_लिमिट को बढ़ाने का कोई समाधान नहीं है, यह कोड में एक समस्या से परहेज कर रहा है। देखें कि आप कौन सी ऑब्जेक्ट्स सेट कर रहे हैं और रिसाव को साफ़ करने के लिए मूल्यों को अनसेट कर रहे हैं। – Petrogad

+0

क्या आप डेटा की मात्रा के बारे में विशिष्ट हो सकते हैं? बड़े से आपका क्या मतलब है? – jergason

+8

@ फ़्रेडरिको: ओपी मेमोरी रिसाव को ठीक करने की कोशिश नहीं कर रहा है, वह PHP में बहुत बड़े डेटासेट को संभालने के लिए एक समाधान मांग रहा है। – arul

उत्तर

53

सर्वर वेबपृष्ठों के लिए अपाचे मॉड्यूल के रूप में चल रहे PHP के memory_limit के लिए कॉन्फ़िगरेशन को ध्यान में रखना होगा कि मशीन पर एक ही समय में आप कितनी अपाचे प्रक्रिया कर सकते हैं - अपाचे के लिए MaxClients कॉन्फ़िगरेशन विकल्प देखें।

यदि MaxClients 100 है और आपके पास 2,000 एमबी या रैम है, तो बहुत तेज़ गणना दिखाएगी कि आपको 20 एमबी * से अधिक का उपयोग नहीं करना चाहिए (क्योंकि 20 एमबी * 100 क्लाइंट = 2 जीबी या रैम, यानी कुल राशि स्मृति आपके सर्वर में है) * स्मृति_limit मान के लिए।

और यह इस बात पर विचार किए बिना है कि अन्य सर्वर एक ही सर्वर पर चल रहे हैं, जैसे MySQL, सिस्टम स्वयं ... और यह कि अपाचे शायद पहले से ही कुछ स्मृति का उपयोग कर रहा है।

या पाठ्यक्रम, यह भी एक "सबसे खराब स्थिति परिदृश्य" है, जो मानता है कि प्रत्येक PHP पृष्ठ अधिकतम मेमोरी का उपयोग कर रहा है।


आपके मामले में, यदि आप केवल एक नौकरी के लिए स्मृति की इतनी बड़ी राशि की जरूरत है, मैं memory_limit पीएचपी एक अपाचे मॉड्यूल के रूप में चलाने के लिए वृद्धि नहीं होगी।

इसके बजाय, मैं कमांड लाइन (या एक क्रॉन जॉब के माध्यम से) से उस काम का शुभारंभ, और यह एक और केवल मामले में specificaly एक उच्च memory_limit निर्दिष्ट करना होगा।

यह, php के -d विकल्प के साथ किया जा सकता है जैसे:

$ php -d memory_limit=1GB temp.php 
string(3) "1GB" 

ध्यान में रखते हुए इस मामले में, कि temp.php केवल शामिल हैं:

var_dump(ini_get('memory_limit')); 

मेरी राय में, यह है Apache के लिए PHP मॉड्यूल के लिए memory_limit को बढ़ाने से सुरक्षित तरीका - और यह आमतौर पर तब होता है जब मेरे पास एक बड़ा डेटासेट होता है, या कुछ वास्तव में भारी चीजें जिन्हें मैं अनुकूलित या पेजिनेट नहीं कर सकता।


यदि आपको PHP सीएलआई निष्पादन के लिए कई मान परिभाषित करने की आवश्यकता है, तो आप डिफ़ॉल्ट php के बजाय इसे अन्य कॉन्फ़िगरेशन फ़ाइल का उपयोग करने के लिए भी कह सकते हैं।आरं, -c विकल्प के साथ:

php -c /etc/phpcli.ini temp.php 

इस तरह, आप है:

  • अपाचे के लिए /etc/php.ini, कम memory_limit साथ, कम max_execution_time ...
  • और बैचों के लिए /etc/phpcli.ini आदेश से चलाने -लाइन, लगभग कोई सीमा

यह सुनिश्चित करता है कि आपके बैच चलने में सक्षम होंगे - और आप अभी भी


फिर भी अपनी वेबसाइट (memory_limit और max_execution_time जा रहा है सुरक्षा उपायों) के लिए सुरक्षा है, अगर आप समय अपनी स्क्रिप्ट, आपको चाहिए अनुकूलन करने के लिए है, उदाहरण के लिए, उस तरह की स्थिति में जहां आपको बहुत सारे डेटा से निपटना होगा, पेजिनेशन एक होना चाहिए ;-)

+0

हां, सीमा केवल उस प्रक्रिया के लिए उठाई जा रही है जिसके लिए इसकी आवश्यकता है। दुर्भाग्य से हालांकि, इस मामले में अंकन मदद नहीं करेगा; अंतिम परिणाम केवल एक मुट्ठी भर (20 या तो) सांख्यिकीय संख्या है, यह केवल वह प्रक्रिया है जिसके लिए अंतरिक्ष की आवश्यकता होती है। –

+0

ओह, ठीक है ... फिर, मुझे लगता है कि यह इस बात पर निर्भर करता है कि उस प्रक्रिया को लॉन्च करते समय आपके पास कितनी "मुक्त" मेमोरी है: यदि आप इसे रात के मध्य में लॉन्च करते हैं, जब आपके सर्वर का उपयोग करने वाला लगभग कोई नहीं होता है, हो सकता है कि 1.5 जीबी ठीक हो (मैं कुछ और मेमोरी को सिस्टम के बाकी हिस्सों में जाने के लिए और अधिक उपयोग करूँगा) - लेकिन केवल आप ही कह सकते हैं कि उस समय आपका सर्वर कितना लोड हो गया है। कुछ PHP संस्करणों में –

+4

(उदा। पीएचओ 5.3.15 सुहोसिन-पैच के साथ) सेटिंग 1 जी है, 1 जीबी नहीं है। इसका परीक्षण करें या PHP निम्नतम मान तक सीमा निर्धारित करेगा और आपकी स्क्रिप्ट निष्पादित करने में विफल रहेगी, उदा। 'php -d memory_limit = 1G -r" echo ini_get ('memory_limit') का उपयोग करें; "' –

2

क्या आपने डेटासेट को छोटे हिस्सों में विभाजित करने और उस समय केवल एक ही हिस्से को संसाधित करने का प्रयास किया है?

यदि आप डिस्क फ़ाइल से डेटा प्राप्त करते हैं, तो आप डेटाबेस के मामले में छोटे भाग, या sort of unbuffered db query लोड करने के लिए fread() फ़ंक्शन का उपयोग कर सकते हैं।

मैंने v3.something से PHP की जांच नहीं की है, लेकिन आप क्लाउड कंप्यूटिंग के रूप में भी उपयोग कर सकते हैं। 1 जीबी डेटासेट कई मशीनों पर संसाधित होने के लिए काफी बड़ा प्रतीत होता है।

+0

योजना केवल आवश्यक डेटा को पढ़ने के लिए है (जैसा कि आप फ्रेड() के साथ सुझाव दे रहे हैं), लेकिन यह वही रिफैक्टरिंग है जिसे हमें अभी तक नहीं मिला है। –

+0

यह वास्तविक सही उत्तर है, IMNSHO: जब तक डेटासेट पूरी तरह से सहसंबंधित नहीं होता है, आमतौर पर एक समय में एक भाग को संसाधित करना संभव होता है, और शायद ही कभी इसे स्मृति में रखना आवश्यक है। ओपी नोट्स के रूप में, अक्सर इसे नॉनट्रिविअल रिफैक्टरिंग की आवश्यकता होती है। – Piskvor

1

यह देखते हुए कि आप जानते हैं कि आपकी स्क्रिप्ट के साथ मेमोरी समस्याएं हैं जिन्हें फिक्सिंग की आवश्यकता है और आप केवल अल्पकालिक समाधान की तलाश में हैं, तो मैं go about profiling के तरीकों को संबोधित नहीं करूँगा और आपकी स्मृति समस्याओं को हल नहीं करूँगा। ऐसा लगता है कि आप उस पर पहुंचने जा रहे हैं।

तो, मैं कहूंगा कि मुख्य बातें आप को ध्यान में रखना है कर रहे हैं:

  • सिस्टम पर कुल स्मृति लोड
  • ओएस क्षमताओं

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

ओएस क्षमताओं के संदर्भ में, आपको यह ध्यान रखना चाहिए कि 32-बिट सिस्टम, जो आप चल रहे हैं, केवल विशेष हैंडलिंग के बिना 4 जीबी रैम को संबोधित कर सकते हैं। अक्सर इसका उपयोग कैसे किया जाता है इसके आधार पर सीमा बहुत कम हो सकती है। कुछ विंडोज चिपसेट और कॉन्फ़िगरेशन में वास्तव में सिस्टम के लिए 3 जीबी से कम उपलब्ध हो सकता है, यहां तक ​​कि 4 जीबी या अधिक शारीरिक रूप से स्थापित किया जा सकता है। आपको यह देखने के लिए जांच करनी चाहिए कि आपका सिस्टम कितना संबोधित कर सकता है।

आप कहते हैं कि आपने कई बार स्मृति सीमा में वृद्धि की है, तो जाहिर है कि यह काम दायरे में बड़ा और बड़ा हो रहा है। यदि आप 1.5 जीबी तक हैं, तो 2 जीबी और रैम लगता है जैसे कि यह एक छोटी सी राहत होगी।

क्या दूसरों को इस तरह के समस्या का सामना करना पड़ा है? और समाधान क्या थे?

मुझे लगता है कि आप शायद पहले ही जानते हैं कि एकमात्र असली समाधान तोड़ना है और जल्द ही स्क्रिप्ट को अनुकूलित करने के लिए समय बिताना है, या आप नौकरी के साथ खत्म हो जाएंगे जो दौड़ने के लिए बहुत बड़ा होगा।

+0

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

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