2009-04-15 5 views
7

मेरे पास एक निर्धारित कार्य है जो नियमित आधार पर (प्रत्येक घंटे) एक स्क्रिप्ट चलाता है। यह स्क्रिप्ट डेटाबेस और फाइल सिस्टम के साथ कुछ भारी बातचीत करता है और नियमित रूप से चलाने में कई मिनट लगते हैं। समस्या यह है कि, सर्वर की सीपीयू-उपयोग स्पाइक्स जबकि स्क्रिप्ट चल रही है और सामान्य संचालन धीमा कर देती है। क्या इस प्रक्रिया को थ्रॉटल करने का कोई तरीका है ताकि इसमें अधिक समय लगे लेकिन कई संसाधनों का उपभोग नहीं किया जाता है?एक PHP स्क्रिप्ट थ्रॉटलिंग के लिए सुझाव/ट्रिक्स

मैंने PHP के लिए अलग-अलग कॉन्फ़िगरेशन विकल्पों को देखा है लेकिन मेरी आवश्यकताओं के अनुरूप कोई भी ऐसा प्रतीत नहीं होता है।

php.ini में memory_limit को कुछ कम करने के लिए मेरे डेटा ऑब्जेक्ट्स को आसानी से बहने का कारण बनता है।

मैंने इसी तरह की पोस्ट देखी हैं जहां लोगों ने स्क्रिप्ट में कुछ बिंदुओं पर नींद() का उपयोग करने का सुझाव दिया है, लेकिन यह स्क्रिप्ट को सर्वर को घुमाने से नहीं रोकता है।

इष्टतम समाधान लैंप (इस मामले में वैंप) स्टैक को केवल 10% अधिकतम सीपीयू उपयोग का उपयोग करने के लिए कुछ तरीका बताएगा। मैं रनटाइम के बारे में बिल्कुल चिंतित नहीं हूं और यह पसंद करूंगा कि अगर प्रति सेकंड सीपीयू चक्रों को सहेजने का मतलब है तो इसमें अधिक समय लगेगा। मेरा वैकल्पिक समाधान डाटाबेस प्रतिकृति के साथ एक अलग सर्वर स्थापित करना होगा ताकि क्रॉन शहर के बाकी हिस्सों को धीमा किए बिना शहर जा सके।

पर्यावरण: विंडोज सर्वर 2k3, अपाचे 2.2.11, पीएचपी 5.2.9, MySQL 5.1

मैं इस स्थिति के लिए किसी भी जानकारी की सराहना करते हैं।

संपादित करें: मैं सभी उत्तरों की सराहना करता हूं, यहां तक ​​कि * निक्स-विशिष्ट। होस्टिंग पर्यावरण को बदलने के लिए मेरी स्थिति में अभी भी काफी जल्दी है। उम्मीद है कि यह प्रश्न ओएस के बावजूद दूसरों की मदद करेगा।

उत्तर

8

यह एक मुश्किल समस्या है। यदि आप कमांड लाइन के माध्यम से PHP स्क्रिप्ट चला रहे हैं, तो आप प्रक्रिया की शेड्यूलिंग प्राथमिकता को कम (start /low php.exe myscript.php मुझे विश्वास) पर सेट कर सकते हैं। यदि आपकी PHP स्क्रिप्ट वास्तव में आपके सीपीयू को खाने वाली अधिकांश प्रोसेसिंग कर रही है, तो यह काम कर सकती है।हालांकि, आपने कहा कि आप कुछ भारी डेटाबेस और फाइल सिस्टम इंटरैक्शन कर रहे हैं, जो इस समाधान से मदद नहीं करेगा। ऐसा लगता है कि INSERT और अद्यतन क्वेरी के लिए एक MySQL संकेत "LOW_PRIORITY" है जो आपकी मदद कर सकता है, लेकिन मैंने उनको आजमाया नहीं है।

1

यह एक कठिन बदलाव हो सकता है लेकिन यह आपके डेटा संरचनाओं को पुनरावर्तक करने में लायक हो सकता है। साथ ही, यदि आपके कोड में परिपत्र संदर्भ हैं, तो clearReferences() जैसी विधि प्रदान करें जो इन ऑब्जेक्ट्स को अनसेट करता है। यह एक समस्या है जिसे PHP 5.3 में हल किया जाता है।

तो अगर आप हैं:

class Row 
{ 
    public function clearReferences() 
    { 
     $this->_table = null; 
    } 
} 

सब मैं पल के लिए साथ आने कर सकते हैं कि:

class Row 
{ 
    protected $_table; 

    public function __construct($table) 
    { 
     $this->_table = $table; 
    } 
} 

class Table 
{ 
    protected $_row; 

    public function __construct() 
    { 
     $this->_row = new Row($this); 
    } 
} 

एक clearReferences() पंक्ति वर्ग के लिए विधि जोड़ें।

3

You can set processes in Windows to be a lower priority. मुझे यकीन नहीं है कि प्रक्रिया को कैसे लाया जा रहा है, लेकिन यदि आप प्रक्रिया को कम प्राथमिकता के रूप में सेट करते हैं, तो जो भी चाहता है कि CPU संसाधन उन्हें प्राप्त करेंगे यदि आप प्राथमिकता को वास्तव में कम मानते हैं।

0

यदि आपके पास यह (अपाचे) सेवा के रूप में चल रहा है, तो आप विन नियंत्रण केंद्र/सेवाओं में प्राथमिकता सेटिंग्स बदल सकते हैं। आपका सीपीयू उपयोग वैसे भी बढ़ जाएगा, लेकिन शेड्यूलर द्वारा अन्य प्रोग्राम को प्राथमिकता दी जाएगी। अपने अनुप्रयोगों की तुलना में डेटाबेस/सर्वर को एक अलग एचडी पर डालने का प्रयास करें।

2

क्या आप nice का उपयोग करके अपनी स्क्रिप्ट लॉन्च करने के लिए अपनी क्रॉन प्रविष्टि को बदल सकते हैं?

+0

ओह, क्षमा करें। मुझे लगता है कि आप विंडोज चल रहे हैं। मुझे 'दीपक' और 'क्रॉन' टैग से फेंक दिया गया था! – grossvogel

+0

वैसे भी आपके उत्तर के लिए धन्यवाद। पर्यावरण की स्थिति बदलने के लिए मेरी स्थिति में अभी भी संभव है, इसलिए मुझे अभी भी आपका समाधान उपयोगी पाया गया है। –

2

ग्राहकों की सेवा करने और डेटा का विश्लेषण करने के लिए सर्वर का उपयोग करने के लिए कोई अच्छा विचार नहीं है।

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

भले ही आप विश्लेषक सफलतापूर्वक थ्रॉटल कर सकें, फिर भी यह बहुमूल्य संसाधनों का उपयोग करेगा अन्यथा उपयोगकर्ताओं की सेवा के लिए उपलब्ध होगा।

0 * * * * अच्छा -n19 php myscript.php

यह रैम उपयोग में मदद नहीं करेगा:

1

मैं स्क्रिप्ट का एक गुच्छा है कि मैं अच्छा उपयोग कर एक समान तरीके से क्रॉन से चलाने के (केवल स्क्रिप्ट लिखे गए तरीके को बदलकर वह कर सकता है), लेकिन यह केवल सीपीयू का उपयोग करता है जो अन्यथा निष्क्रिय होगा।

संपादित करें: नहीं देखा था कि प्रश्न एक Windows वातावरण शामिल है, खेद ... यह किसी भी * nix ये समस्या हो रही उपयोगकर्ताओं के लिए में छोड़ने ..

3

में यूनिक्स (दीप) मैं करने में कामयाब पाश

function get_server_load($windows = 0) { 
    $os = strtolower(PHP_OS); 
    if(strpos($os, "win") === false) { 
     if(file_exists("/proc/loadavg")) { 
     $load = file_get_contents("/proc/loadavg"); 
     $load = explode(' ', $load); 
     return $load; 
     } 
     elseif(function_exists("shell_exec")) { 
     $load = explode(' ', `uptime`); 
     return $load; 
     } 
     else { 
     return ""; 
     } 
    } 
} 

for(... ... ...){ 
    $data = get_server_load(); 
    if($data[0] < 0.2){ 
    // continue 
    }else{ 
     sleep(1); 
    } 
} 

जारी इस समारोह खिड़कियों पर भी काम करना चाहिए इससे पहले कि सर्वर लोड की जाँच करके समस्या का समाधान लेकिन मैं यह गारंटी नहीं दे सकते। लिनक्स पर यह आपको पिछले 1 मिनट के लोड के साथ एक सरणी देता है, 5 मिनट और 15 मिनट

इसके अलावा, कम प्राथमिकता के साथ अपनी स्क्रिप्ट (यदि सीएलआई द्वारा) शुरू करने पर विचार करें (लिनक्स में, "अच्छा")

आप लूप को जारी रखने से पहले अन्य मानों का भी उपयोग कर सकते हैं, जैसे कि अपाचे सक्रिय प्रक्रियाओं की संख्या (आप पेज 127.0.0.1/server_status?auto को पार्स कर सकते हैं यदि आपने httpd.conf में mod_status को सक्षम किया है), या यह भी MySQL स्थिति (सक्रिय कनेक्शन?)

1

शायद आपकी स्क्रिप्ट बस एक ही बार में बहुत कुछ करने की कोशिश कर रही है। यदि यह तीन बार एक घंटे तक चला तो यह कम होगा?

एक और समाधान सिर्फ इस प्रकार के 'बैकएंड' प्रसंस्करण को चलाने के लिए एक अतिरिक्त सर्वर स्थापित करना हो सकता है। यह विशेष रूप से प्रभावी होगा अगर यह डेटाबेस में अनावश्यक भार नहीं डाल रहा है, बस वेब सर्वर।

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

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