लोड परीक्षण: प्रति सेकंड अनुरोध कैसे उत्पन्न करें?


14

मेरे पास एक सर्वर घटक है जो ज़ीरोक-आईसीई पर चलता है। जब मैंने इसे लोड करना चाहा, तो मैंने सोचा कि समानांतर पुस्तकालय बनाने के लिए कई अनुरोध बनाने का उपयोग करेंगे। लेकिन यह उस तरह से खत्म हो गया। C # से समानांतर (Parallel.For) लाइब्रेरी का उपयोग करना स्पष्ट रूप से आसान था, लेकिन यह एक ही पल में समानांतर रूप से सब कुछ उत्पन्न नहीं करता है। इसलिए यह प्रति सेकंड एन अनुरोध बनाने की परिभाषा नहीं हो सकती है। मैं इसे कैसे करूं ? मुझे लगता है कि जो कोई पहले लोड परीक्षण करना चाहता है, वह वास्तव में इस बारे में सोचेगा।

  1. वास्तव में प्रति सेकंड एन अनुरोध बनाने का कुशल तरीका क्या है?

  2. एक अन्य मिथक समानांतर प्रोग्रामिंग के बारे में है। कृपया हमें बताएं, यदि आपने सामान्य रूप से C # या .Net में समानांतर प्रोग्रामिंग पैटर्न का उपयोग किया है। कल्पना कीजिए कि मेरी 5 प्रक्रियाएँ हैं। एक ही समय में सभी पांच प्रक्रियाएं कैसे शुरू होंगी। मेरे संसाधनों के उपभोग का क्या मतलब है? मैंने नेट पर उपलब्ध कई सामग्रियों में पढ़ने की कोशिश की है, लेकिन मुझे अपने सवालों के जवाब देने से ज्यादा से ज्यादा सवाल मिलते हैं।

  3. मैंने Parallel.For का उपयोग किया और N थ्रेड्स बनाए और समय को मापा। तब मैंने टास्क की सुविधा के लिए टास्क.फैक्टरी.स्टार्ट का उपयोग करके यही कोशिश की। नापा गया समय अलग था। तो इनका उपयोग करने के बीच क्या अंतर है? मुझे संबंधित कक्षाओं का उपयोग कब और किन उद्देश्यों के लिए करना चाहिए? हमारे पास अक्सर बहुत सारी दौलत होती है, लेकिन इसका सिर्फ इतना ही नहीं होता है कि हम एक दूसरे से अलग कैसे हो सकते हैं। यह मेरे लिए ऐसा ही एक मामला है, यह पता लगाने में सक्षम नहीं है कि मुझे दूसरे से एक का उपयोग क्यों नहीं करना चाहिए।

  4. मैंने इन समय को मापने के लिए स्टॉपवॉच क्लास का उपयोग किया जो सबसे अच्छा होने का दावा करता है। मुझे एक घटक का परीक्षण लोड करने के परिदृश्य में, प्रतिक्रिया के समय को मापने का तरीका क्या होगा। स्टॉपवॉच मेरे लिए सबसे अच्छा समाधान है। किसी भी राय का स्वागत है।

पीएस: वेब अनुप्रयोगों के लिए कई लोड परीक्षण उपकरण हैं। मेरा सर्वर घटकों का एक अनुकूलित मामला है। और मेरा प्रश्न प्रति सेकंड एन थ्रेड बनाने से संबंधित है।

सभी रायों का स्वागत है। बस यह नहीं लगता कि इसका इतना प्रोग्रामिंग सवाल नहीं है। यह टोना है। यह किसी भी प्रोग्रामर के लिए घंटी बजानी चाहिए जो अपने उत्पाद के प्रदर्शन को जानने के लिए खुद के द्वारा QE सामान चाहता है। मैंने पहले ही खुद को चुना है। मैंने कई विकल्पों की कोशिश की है और फिर वापस गिरना पड़ा कि मुझे वास्तव में यह कैसे करना चाहिए?


फ़ेक कहता है कि क्या यह एक विशिष्ट प्रोग्रामिंग समस्या से संबंधित है और यदि प्रोग्रामिंग पेशे में इसकी व्यावहारिक जवाबदेह समस्या है, तो यह पूछा जा सकता है। जो लोग इस पर संदेह कर रहे हैं और झंडा फहरा रहे हैं। कृपया टिप्पणी करें।
राजा

"एक ही पल" से आपका क्या मतलब है? मुझे आश्चर्य है कि यदि आप किसी भी तरह से TPL या PLinq को प्राप्त करने के लिए बाध्य कर सकते हैं।
गर्ट अर्नोल्ड

मेरा प्रश्न प्रति सेकंड एन अनुरोध उत्पन्न करने के बारे में है। इस परिदृश्य में इतना ही तात्कालिक था कि समानांतर का उपयोग करने की मेरी समझ एक समानांतर फैशन में धागे शुरू करेगी।
राजा

क्या आपने कोई अनुक्रमिक विश्लेषण किया है?

3
यह प्रोग्रामिंग से संबंधित हो सकता है, लेकिन आपके पोस्ट (कम से कम 4) में बहुत सारे प्रश्न हैं। इसे बंद करने से पहले आप उससे एक सवाल पूछना चाहते हैं, क्योंकि यह बहुत व्यापक है। प्रासंगिक जानकारी दें, जैसे कि आपने केवल 10000 का उल्लेख किया है, आपके परीक्षण मशीन में कोर की संख्या)। कोड दिखाना आमतौर पर मदद करता है।
गर्ट अर्नोल्ड

जवाबों:


10

मेरे पास सभी उत्तर नहीं हैं। उम्मीद है कि मैं इस पर कुछ प्रकाश डाल सकता हूं ।

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

मुझे बताएं कि मैं सॉकेट्स का कोई विशेषज्ञ नहीं हूं, और मुझे ज़ेरोक-आइस के बारे में कुछ भी नहीं पता है। मुझे एसिंक्रोनस ऑपरेशन के बारे में कुछ पता नहीं है, और यह वह जगह है जहाँ यह वास्तव में आपकी मदद करेगा। यदि आप सॉकेट के माध्यम से एक तुल्यकालिक अनुरोध भेजते हैं, जब आप कॉल करते हैं Socket.Receive(), तो आपका धागा तब तक ब्लॉक होगा जब तक कि एक अनुरोध प्राप्त नहीं होता है। यह अच्छा नहीं है। आपका धागा अवरुद्ध होने के बाद कोई और अनुरोध नहीं कर सकता। सॉकेट का उपयोग करना। Beginxxxxxx (), I / O अनुरोध बनाया जाएगा और सॉकेट के लिए IRP कतार में रखा जाएगा, और आपका धागा चालू रहेगा। इसका मतलब है, कि आपका धागा वास्तव में बिना किसी अवरोध के लूप में हजारों अनुरोध कर सकता है!

यदि मैं आपको सही तरीके से समझ रहा हूं, तो आप अपने परीक्षण कोड में ज़ीरोक-आइस के माध्यम से कॉल का उपयोग कर रहे हैं, वास्तव में एक http समापन बिंदु तक पहुंचने की कोशिश नहीं कर रहे हैं। अगर ऐसा है, तो मैं स्वीकार कर सकता हूं कि मुझे नहीं पता कि ज़ीरोक-आइस कैसे काम करता है। हालाँकि, मैं यहाँ दी गई सलाह का पालन करने का सुझाव दूंगा , विशेषकर भाग Consider Asynchronous Method Invocation (AMI):। पेज यह दिखाता है:

एएमआई का उपयोग करके, ग्राहक नियंत्रण के धागे को फिर से भेजता है जैसे ही मंगलाचरण भेजा गया है (या, अगर इसे तुरंत नहीं भेजा जा सकता है, तो कतार लगाई गई है), ग्राहक को उस धागे का उपयोग करने की अनुमति देता है ताकि अन्य उपयोगी काम कर सकें। ।

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

स्यूडोकोड में कुछ उदाहरणों ने (जितना संभव हो उतना बर्फ के करीब बनाने की कोशिश की मेरे बिना वास्तव में इसे सीखना है):

var iterations = 100000;
for (int i = 0; i < iterations; i++)
{
    // The thread blocks here waiting for the response.
    // That slows down your loop and you're just wasting
    // CPU cycles that could instead be sending/receiving more objects
    MyObjectPrx obj = iceComm.stringToProxy("whateverissupposedtogohere");
    obj.DoStuff();
}

एक बेहतर तरीका:

public interface MyObjectPrx : Ice.ObjectPrx
{
    Ice.AsyncResult GetObject(int obj, Ice.AsyncCallback cb, object cookie);
    // other functions
}

public static void Finished(Ice.AsyncResult result)
{
    MyObjectPrx obj = (MyObjectPrx)result.GetProxy();
    obj.DoStuff();
}

static void Main(string[] args)
{
    // threaded code...
    var iterations = 100000;
    for (int i = 0; i < iterations; i++)
    {
        int num = //whatever
        MyObjectPrx prx = //whatever
        Ice.AsyncCallback cb = new Ice.AsyncCallback(Finished);
        // This function immediately gets called, and the loop continues
        // it doesn't wait for a response, it just continually sends out socket
        // requests as fast as your CPU can handle them.  The response from the
        // server will be handled in the callback function when the request
        // completes.  Hopefully you can see how this is much faster when 
        // sending sockets.  If your server does not use an Async model 
        // like this, however, it's quite possible that your server won't 
        // be able to handle the requests
        prx.GetObject(num, cb, null);
    }
}

ध्यान रखें कि अधिक धागे! = सॉकेट भेजने की कोशिश करते समय बेहतर प्रदर्शन (या वास्तव में कुछ भी करना)। थ्रेड्स जादू नहीं हैं कि वे अपने आप जो भी समस्या आप पर काम कर रहे हैं, को स्वचालित रूप से हल करेंगे। आदर्श रूप से, आप प्रति कोर 1 थ्रेड चाहते हैं, जब तक कि एक थ्रेड अपना ज्यादा समय इंतजार नहीं कर रहा है, तब आप अधिक होने का औचित्य साबित कर सकते हैं। अपने स्वयं के धागे में प्रत्येक अनुरोध को चलाना एक बुरा विचार है, क्योंकि संदर्भ स्विच घटित होगा और संसाधन बर्बाद होगा। (यदि आप मेरे द्वारा लिखी गई हर चीज को देखना चाहते हैं, तो संपादित करें पर क्लिक करें और इस पोस्ट के पिछले संशोधनों को देखें। मैंने इसे हटा दिया क्योंकि यह केवल मुख्य मुद्दे को हाथ में लेने के लिए प्रतीत होता है।)

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

मुझे आशा है कि वह मदद करेंगे।


आप प्रदर्शन की इतनी बात क्यों कर रहे हैं? ऐसा नहीं लगता कि ओपी चाहता है।
--विक

1
@svick अच्छी तरह से ऑप्स मूल पोस्ट में मूल रूप से 4 प्रश्न थे, और उन्होंने समानांतर बनाम कार्यों के प्रदर्शन के बारे में प्रश्न पूछे, फिर इसे संपादित किया गया, और अब वे वापस आ गए। इसलिए, आपने जो पढ़ा है, उसका बहुत कुछ परिणाम था। अंततः, हालांकि उनके सवाल का प्रदर्शन के साथ क्या करना है, क्योंकि उनके पास सामान्य विचार सही है, लेकिन जाहिर तौर पर उनके कार्यान्वयन में कमी है। मेरा मानना ​​है कि मेरे द्वारा बताए गए सवालों के जवाब के अंत में उन्होंने जवाब नहीं दिया।
क्रिस्टोफर Currens

1
मुझे अपने सवालों को कम करने के लिए मजबूर किया गया क्योंकि वे इसे बंद करने के लिए वोट देना चाहते थे। अब ऐसा लगता है, यहाँ यह उनके लिए मान्य है। कार्य के लिए सूत्र के साथ अंतर के लिए @ChristopherCurrens +1 अच्छा बिंदु। इसने मेरी समझ को चौड़ा किया। लेकिन मैं अभी भी अटका हूं कि प्रति सेकंड कुछ एन अनुरोध कैसे उत्पन्न करना वास्तव में संभव है? वास्तव में ऐसा करने का सबसे अच्छा तरीका क्या है?
राजा

@King - मुझे लगता है कि जैसा मैंने सोचा था कि मैं उतना स्पष्ट नहीं था। पिछले 3-4 पैराग्राफ मुझे लगा कि आपकी मदद करेंगे। मैंने मान लिया था कि आप पहले से ही पहले से ही लूप का इस्तेमाल कर रहे थे। यदि आप ऐसा कर रहे थे, तो समस्या यह है कि आपका सॉकेट भेजता है / प्राप्त अवरुद्ध हो रहा है, और इस प्रकार आपके अनुरोधों को धीमा कर रहा है। शायद मुझे कुछ उदाहरण छद्म कोड पोस्ट करने के लिए कुछ समय मिलेगा।
क्रिस्टोफर Currens

मुझे वास्तव में उन्हें ICE पर भेजने में कोई समस्या नहीं है। समस्या यह है कि कार्यान्वयन को परिभाषित करता है जो वास्तव में एन अनुरोध और कुछ ऐसा बना देगा जो उस संख्या, एन के लिए सच कहा जा सकता है।
राजा

2

मैं प्रश्न 1 पर छोड़ता जा रहा हूं) और # 2 में अधिकार प्राप्त कर रहा हूं, क्योंकि आमतौर पर आप जो खोज रहे हैं उसे पूरा करने का एक स्वीकार्य तरीका है। अतीत में प्रति सेकंड n संदेश प्राप्त करने के लिए आप एक एकल प्रक्रिया बना सकते हैं जो तब p AppDomains लॉन्च करेगी । प्रत्येक AppDomain मूल रूप से बस एक अनुरोध लूप चलाना शुरू कर देता है जब एक निश्चित समय तक पहुंच गया होता है (टाइमर का उपयोग करके)। प्रत्येक AppDomain के लिए यह समय समान होना चाहिए ताकि वे यह सुनिश्चित कर सकें कि वे आपके सर्वर को उसी समय पर हिट करना शुरू कर दें।

आपके अनुरोध भेजने के लिए कुछ इस तरह काम करना चाहिए:

WaitCallback del = state => 
{ 
    ManualResetEvent[] resetEvents = new ManualResetEvent[10000]; 
    WebClient[] clients = new WebClient[10000]; 

    for (int index = 0; index < 10000; index++) 
    { 
        resetEvents[index] = new ManualResetEvent(false); 
        clients[index] = new WebClient(); 

        clients[index].OpenReadCompleted += new OpenReadCompletedEventHandler (client_OpenReadCompleted); 

        clients[index].OpenReadAsync(new Uri(@"<REQUESTURL>"), resetEvents[index]); 
    } 

    bool succeeded = ManualResetEvent.WaitAll(resetEvents, 10000); 
    Complete(succeeded); 

    for (int index = 0; index < 10000; index++) 
    { 
        resetEvents[index].Dispose(); 
        clients[index].Dispose(); 
    } 
}; 

while(running)
{
    ThreadPool.QueueUserWorkItem(del);
    Thread.Sleep(1000);
}

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

अपने तीसरे प्रश्न के लिए, इस लिंक को पढ़ें http://www.albahari.com/threading/

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


2
आपको यहां अलग-अलग AppDomains बनाने के क्या संभावित कारण हो सकते हैं? जो पूरी तरह से अनावश्यक लगता है।
svick

0

धागे से परेशान मत करो, अगर एन यथोचित रूप से छोटा है। प्रति सेकंड एन अनुरोध उत्पन्न करने के लिए, दीवार घड़ी समय ( DateTime.Now) का उपयोग करें । अनुरोध से पहले और बाद में दोनों समय निकालें, फिर Sleepअगले अनुरोध में देरी करने के लिए जोड़ें ।

उदाहरण के लिए, N = 5 (200 एमएस) के साथ:

Before request: 12:33:05.014
After request: 12:33:05.077
Sleep(137)
Before request: 12:33:05.214
After request: 12:33:05.271
Sleep(131)

यह सही नहीं है; आप पा सकते हैं कि Sleepसटीक नहीं है। आप विचलन की चल रही गिनती रख सकते हैं (X'th अनुरोधों से पहले, समय X-1 / N बाद में होना चाहिए) और तदनुसार नींद की अवधि को समायोजित करें।

एक बार N बहुत बड़ा हो जाता है, आप बस M थ्रेड बनाते हैं और प्रत्येक थ्रेड को उसी अंदाज में N / M अनुरोध उत्पन्न करते हैं।


मुझे बहुत अधिक संख्या में अनुरोध करने हैं। इसलिए यह विकल्प नहीं हो सकता है क्योंकि यह 100 थ्रेड्स से पहले ही मेरी मेमोरी (4 जीबी रैम) पी जाएगा।
राजा

मैंने 250K कोड में एक धागे से प्रति सेकंड 20.000 अनुरोध बनाए हैं। आपके पास वैसे भी 100 थ्रेड चलाने के लिए पर्याप्त CPU नहीं है (मशीनों का वर्ग 4GB के साथ नहीं आता है)। अगली समस्या उन सभी अनुरोधों को आगे बढ़ाएगी; क्या आपके लोड निर्माता और आपके सर्वर के बीच 10 Gbit / s ईथरनेट है? इसलिए, आप अपनी वास्तविक आवश्यकताओं की जांच करना चाहते हैं।
15

स्पष्ट करने के लिए, मेरे पास 20+ Gbps जैसा कुछ है। तो यह कोई समस्या नहीं है। मशीनों की श्रेणी के बारे में, आप किसका जिक्र करेंगे? प्रोसेसर की संख्या?
राजा

@King: 100 धागे पुश करने के लिए मुझे 48 कोर मशीन की उम्मीद होगी। उदाहरण के लिए, SGI उस कई कोर के साथ मशीनें बेचता है, लेकिन उन पर आपको आमतौर पर 32GB या उससे अधिक मिलेगा।
16

0

किसी भी .NET प्रोजेक्ट के लिए लोड परीक्षण को प्राप्त करने का सबसे आसान तरीका विज़ुअल स्टूडियो के अंतिम संस्करण को खरीदना है। यह लोड परीक्षण सहित सभी प्रकार के परीक्षणों को बेहतर बनाने में मदद करने के लिए एक एकीकृत परीक्षण उपकरण के साथ आता है। लोड परीक्षण को एक ही पीसी पर आभासी उपयोगकर्ताओं को बनाकर या कई बड़ी संख्या में उपयोगकर्ताओं के लिए वितरित करके प्रीफॉर्म किया जा सकता है, एक छोटा प्रोग्राम भी है जिसे परीक्षण सर्वर पर परीक्षण की अवधि के लिए अतिरिक्त डेटा वापस करने के लिए स्थापित किया जा सकता है।

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


0

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

C # का कार्यान्वयन है (http://msdn.microsoft.com/en-us/library/system.threading.countdownevent(VS.100).aspx)।

उसी समय, यदि आप अपने सिस्टम का परीक्षण कर रहे हैं, तो आप वास्तव में दौड़ की स्थितियों के लिए भी जाँच कर सकते हैं, जिस स्थिति में आप प्रत्येक थ्रेड पर थ्रेड स्लीप पीरियड को सेटअप करना चाहते हैं, जो कि रैंडमाइज्ड फ्रीक्वेंसी और चोटियों / फर्लो के साथ समय के साथ परिकलित हो।

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.