2009-02-19 19 views
7

मैं एक फर्नीचर कारखाना उत्पादन प्रवाह की निगरानी के लिए एक वेब अनुप्रयोग लिख रहा हूँ। इसे संभालने के लिए हजारों डेटा हैं। अब तक, मैं Mongrel + MySQL पर RoR चलाता हूं और यह वास्तव में वास्तव में धीमा है (कुछ विचारों के लिए 2-4min)। जब मैं RoR लॉग देखता हूं, ऐसा लगता है कि डेटाबेस क्वेरी धीमी नहीं हैं (0-10 मिमी)।रेल पर रूबी धीमी है ...?

क्या आरओआर धीमा है जब यह डेटाबेस डेटा को ऑब्जेक्ट में परिवर्तित करता है? क्या Mongrel धीमा है?

संपादित करें: पहली बात: मैं देव में था। env। उत्पादन वातावरण में, सबसे धीमी दृश्य 2min लेता है (जो एक अच्छे कंप्यूटर पर 1min से भी कम हो जाएगा, मेरा 5 साल पुराना है)। रूबी-प्रोफेसर और थोड़ी सी सामान्य समझ के साथ, मुझे पता चला है कि कौन से तरीके एप्लिकेशन को धीमा कर रहे थे।

ofs = Ofkb.find_by_sql ["..some large sql query..."] 

for of in ofs # About 700-1000 elements 
    ops = Operation.find(..the single query..) 
    etc. 
end 

यहाँ उन तरीकों पर माणिक प्रोफेसर परिणाम::

%self  total  self  wait child calls name 
32.19  97.91 97.91  0.00  0.00  55 IO#gets (ruby_runtime:0} 
28.31  86.39 86.08  0.00  0.32 32128 Mysql#query (ruby_runtime:0} 
    6.14  18.66 18.66  0.00  0.00 12432 IO#write (ruby_runtime:0} 
    0.80  2.53  2.42  0.00  0.11 32122 Mysql::Result#each_hash (ruby_runtime:0} 

समस्या है: मैं वास्तव में उन एकल टाल नहीं सकते समस्या यह है कि एक एसक्यूएल प्रश्नों सबसे बड़े डेटासेट पर छोरों में कहा जाता है है प्रश्नों। मुझे हजारों घटनाएं मिली हैं जिनमें से मुझे जटिल डेटा की गणना करना है। अभी मैं उन विधियों पर memcached का उपयोग कर रहा हूं जो ठीक है जब तक कि आप पृष्ठ का अनुरोध करने वाले पहले व्यक्ति नहीं हैं।

+0

न तो, शायद यह आपके द्वारा लिखा गया कोड है जो धीमा है या तथ्य यह है कि आप विकास में उत्पादन पर चलते हैं। यदि आप विचारों की उचित सामग्री पोस्ट कर सकते हैं तो हम उचित उत्तर दे सकते हैं। – TomHastjarjanto

+0

@ टोम के साथ सहमत हैं - यह सामान्य डेटासेट के साथ भी सामान्य नहीं है। किसी भी तरह का निदान करने के लिए हमें और जानकारी चाहिए। –

+0

यह गूंगा लग सकता है, लेकिन सुनिश्चित करें कि आप उत्पादन मोड में चल रहे हैं।देव मोड प्रत्येक अनुरोध पर सभी वर्गों को फिर से लोड करेगा। –

उत्तर

17

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

रूपरेखा के लिए कुछ युक्तियां:

How to Profile Your Rails Application

Performance Testing Rails Applications

At the Forge - Profiling Rails Applications

एक बार जब आप टोंटी आप पता लगा सकते हैं कि क्या करना है मिल गया है। Railslab Scaling Rails

अब प्रोफेसर परिणामों के आधार पर संशोधित::

ठीक

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

4

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

आप एक बहुत बड़ी संख्या में ऑब्जेक्ट्स के माध्यम से एक लूप पर फिर से गणना कर रहे हैं, तो निश्चित रूप से यह धीमा हो जाएगा।

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

आखिरकार, RubyProf देखें कि यह आपको बाधा खोजने में मदद कर सकता है या नहीं।

+0

"सबसे पहले, रूबीप्रोफ देखें" – srboisvert

+0

प्रोफाइलर का उपयोग करने की वैज्ञानिक तकनीक की बजाय बिट्स और आपके कोड के टुकड़ों पर टिप्पणी करने के लिए प्रोफाइलिंग की विधि क्यों बेहतर नहीं है? – yfeldblum

5

प्रति दृश्य पहुंच में से कितने 0-10ms प्रश्न निष्पादित किए जा रहे हैं? आपके डेटा मॉडल के किन हिस्सों का संदर्भ दिया जा रहा है? क्या आप इसका उपयोग कर रहे हैं: अपने संगठनों पर उत्सुक लोडिंग शामिल करने के लिए शामिल हैं?

रेल जितना धीमा हो उतना धीमा है। समझने के साथ गति (आमतौर पर!)

उपर्युक्त पर विस्तार, क्या आपके पास है_मेनी एसोसिएशन, जहां विशेष रूप से, आपका विचार :include के बिना "कई" पक्ष का संदर्भ दे रहा है? यह आपके तालिका में विस्तार से जुड़ने के लिए मास्टर टेबल पर find(:all) का कारण बनता है - यदि आपके पास बड़ी संख्या में विस्तार रिकॉर्ड हैं और वे सभी को व्यक्तिगत रूप से संसाधित कर रहे हैं, तो यह महंगा हो सकता है।

कुछ इस तरह:

Master.find(:all, :include => :details) 

... मदद कर सकता है। हालांकि, स्पैर जानकारी से अभी भी अनुमान लगाया जा रहा है।

वहाँ विषय here

3

पिछले दो जवाब सहायक होते हैं, विशेष रूप से प्रदर्शन की निगरानी उपकरण का उपयोग कर पर एक पुराने Railscast है।मैं New Relic RPM का उपयोग करता हूं और इससे मुझे अतीत में एक बड़ा सौदा करने में मदद मिली है।

हालांकि, इस तरह के औजार वास्तव में सर्वोत्तम होते हैं, जब आप 3 सेकेंड से 1 सेकेंड से कम गति से कहने की कोशिश कर रहे हैं।

प्रस्तुत करने के लिए 2-4 मिनट किसी भी सामान्य परिस्थितियों में बिल्कुल सामान्य नहीं है।

क्या आप हमें कुछ विकास लॉग दिखा सकते हैं कि बाधाएं कहां हैं?

क्या आप इस कुल माप में छवियों, जावास्क्रिप्ट, या अन्य फ़ाइलों को लोड करने के लिए ब्राउज़र लेते हैं?

+0

Yep New Relic इस सामान को ट्रैक करने के लिए बहुत अच्छा है। –

5

जबकि आर-एन-आर has a reputation of being slow, यह भाषा के साथ एक साधारण समस्या होने के लिए बहुत चरम लगता है।

आपको यह निर्धारित करने के लिए एक प्रोफाइलर चलाया जाना चाहिए कि वास्तव में कौन से फ़ंक्शन धीमे हैं और क्यों। वेब अनुप्रयोग को धीमा करने वाली सबसे आम बात "n+1 problem" है। यही है, जब आपके डेटाबेस में एन डेटा आइटम होते हैं, तो ऐप उन्हें एक क्वेरी बनाने के बजाय डेटाबेस में अलग-अलग प्रश्न बनाता है। लेकिन आप नहीं जानते जब तक आप प्रोफाइलर नहीं चलाते। ruby-prof एक प्रोफाइलर है जिसका मैंने उपयोग किया है।

संपादित करें पर प्रोफ़ाइल परिणाम संपादित आधारित:

मुझे पूरा विश्वास है कि आप हमेशा एक प्रश्न पाश निकाल सकते हैं। जैसा कि माइक वुडहाउस कहते हैं, ऐसा करने के लिए रेल तरीका has_many या अन्य एसोसिएशन के साथ संबंधों को निर्दिष्ट करना है और फिर रेलों को स्वचालित रूप से तालिका में शामिल होने दें, यह स्पष्ट, तेज़ और "रेल मार्ग" है। लेकिन यदि आप बेयर एसक्यूएल के साथ शुरू कर रहे हैं या यदि एसोसिएशन इस मामले में काम नहीं करते हैं, तो आप बस उचित रूप से उचित जुड़ाव कर सकते हैं। और यदि सब कुछ विफल हो जाता है, तो आप एक दृश्य या denormalized तालिका बना सकते हैं जो परिणाम लूप के माध्यम से मिले थे। दरअसल, तथ्य यह है कि आपको उत्पन्न प्रश्नों के माध्यम से पुन: उत्पन्न करना है एक संकेत हो सकता है कि आपकी तालिका डिज़ाइन में कुछ त्रुटियां हैं।

यह सब कहा गया है कि, यदि आपके प्रश्न परिणामों को कैशिंग करना आपके लिए पर्याप्त काम करता है, तो इसके साथ रहें। आवश्यकता होने पर अनुकूलित करें।

+0

कोई टिप्पणी नहीं के साथ, नीचे मतदान किया गया? –

+0

क्षमा करें - -1 मैं था। "आर-एन-आर" (?) धीमा होने के लिए कोई उद्धरण नहीं है, जो तर्कसंगत और अनावश्यक और साथ ही मेरे अनुभव में असत्य लग रहा था। –

+0

कोई उद्धरण नहीं था लेकिन यह एक बहुत आम राय है, सच है या नहीं। – Craig

0

निष्पादन के समय से मुझे लंबे समय तक नेटवर्क समस्या पर संदेह होगा - शायद एक DNS क्वेरी प्राथमिक DNS सर्वर पर समाप्त हो रही है?

0

आप जेआरबीई का उपयोग करने या रूबी 1.9 पर स्विच करने का प्रयास कर सकते हैं।
दोनों में बड़े प्रदर्शन में वृद्धि होनी चाहिए।
जेआरबी के साथ समस्या यह है कि सी का उपयोग करने वाले रत्न संकलित/काम नहीं करेंगे। जावा समकक्ष हैं जो jruby के "मणि" ऐप द्वारा स्थापित किए जाते हैं, लेकिन कुछ रत्न बस काम नहीं करते

आपको मूल रूप से रूबी 1.9 के साथ एक ही समस्या होगी। सिंटैक्स का एक छोटा सा बदल गया, लेकिन मुख्य समस्या यह है कि रत्नों की एक बड़ी मात्रा अब काम नहीं करती है। लोग हालांकि अद्यतन करने की प्रगति में हैं (http://isitruby19.com/ पर प्रगति की जांच करें)

0

क्यों सभी डेटा पूर्व-प्राप्त नहीं करते हैं और आपके लूप को हर बार डेटाबेस से पूछताछ के बजाय स्मृति में स्थानीय रूप से ढूंढते हैं? एक दृश्य के लिए प्रश्नों के 1000s से संकेत मिलता है कि आपके डिजाइन के साथ कुछ गंभीरता से गलत है।

0

कुछ अच्छी स्क्रीन इस विषय http://railslab.newrelic.com/scaling-rails

हालात fragmet कैशिंग और का उपयोग कर की तरह पर डाले हैं: शामिल (n + 1 से बचने के लिए) कर सकते हैं। ऐसा लगता है कि आप पहले से ही memcached का उपयोग कर रहे हैं, तो कैश prefetch करने के लिए यूआरएल curl क्यों नहीं?

0

जब मैं सर्वर को 0.0.0.0 के बजाय बॉक्स आईपी पते पर बाध्य करता हूं, तो यह मेरे लिए चीजों को बढ़ा देता है।

0

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

जैसा कि पहले ही अन्य उत्तर पर कहा कि अगर दोनों मॉडलों से संबंधित हैं आप उत्सुक लोड संघों, जो सक्रिय रिकॉर्ड को निर्देश का मतलब प्रश्नों में शामिल होने के प्रदर्शन करने के लिए करना चाहिए:: आप वैसे भी एक व्यावहारिक प्रोफाइलर here मिल सकती है

#left outer join 
ofkbs=Ofkb.includes(:operation).where(name: "banana") 

आप ofkbs लेकिन केवल आपरेशन की जरूरत नहीं है, तो आप एक आंतरिक में शामिल होने

#inner join (discards the Ofkbs that do not have any operation) 
operations=Operation.joins(:ofkb).where(ofkb:{name:"banana"}) 

यह समाधान केवल एक क्वेरी preforms प्रदर्शन कर सकता है, और आप बाद में डेटा कि पहले से ही ख होगा के माध्यम से चीज़ों को दोहरा सकते een डीबी से एकत्र:

operations=ofkbs.map{|of| of.operations}.flatten 

operations.each do |o| 
    do_whatever_you_want_with_operation(o) 
end 

प्रश्नों बहुत जटिल रहे हैं, तो आप arel बजाय का उपयोग करना चाहिए।

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