`wrk` के साथ सटीक Performance Testing

API7.ai

November 25, 2022

OpenResty (NGINX + Lua)

इस लेख में, हम प्रदर्शन परीक्षण (performance testing) के बारे में बात करेंगे। यह भाग OpenResty के लिए विशिष्ट नहीं है, बल्कि अन्य बैकेंड सेवाओं पर भी लागू होता है।

प्रदर्शन परीक्षण व्यापक रूप से प्रचलित है, और जब हम उत्पादों को वितरित करते हैं, तो वे सभी प्रदर्शन मेट्रिक्स के साथ आते हैं, जैसे QPS, TPS, विलंबता (latency), समवर्ती रूप से समर्थित कनेक्शन की संख्या, और इसी तरह। ओपन-सोर्स प्रोजेक्ट्स के लिए, हम एक संस्करण जारी करने से पहले भी प्रदर्शन परीक्षण करते हैं ताकि इसे पिछले संस्करण से तुलना कर सकें और देख सकें कि क्या कोई महत्वपूर्ण गिरावट है। ऐसे तटस्थ वेबसाइट्स भी हैं जो समान उत्पादों के तुलनात्मक प्रदर्शन डेटा प्रकाशित करते हैं। मुझे कहना पड़ेगा कि प्रदर्शन परीक्षण हमारे करीब है।

तो, वैज्ञानिक और सख्त प्रदर्शन परीक्षण कैसे करें?

प्रदर्शन परीक्षण उपकरण

अच्छा काम करने के लिए, पहले एक अच्छे उपकरण का उपयोग करना चाहिए। एक अच्छे प्रदर्शन परीक्षण उपकरण का चयन करना आधी सफलता है।

Apache Benchmark टूल, जिसे ab के नाम से भी जाना जाता है, जिससे आप परिचित होने चाहिए, शायद सबसे आसान प्रदर्शन परीक्षण उपकरण है, लेकिन दुर्भाग्य से, यह बहुत उपयोगी नहीं है। ऐसा इसलिए है क्योंकि वर्तमान सर्वर साइड को समवर्ती और अतुल्यकालिक I/O पर आधारित विकसित किया गया है, जिसका प्रदर्शन खराब नहीं है। ab मशीन के मल्टी-कोर का लाभ नहीं उठाता है और उत्पन्न अनुरोध पर्याप्त दबाव में नहीं होते हैं। इस स्थिति में, ab परीक्षण से प्राप्त परिणाम वास्तविक नहीं होते हैं।

इसलिए, हम स्ट्रेस टेस्टिंग टूल के लिए एक मानदंड चुन सकते हैं: टूल स्वयं मजबूत प्रदर्शन वाला हो और सर्वर-साइड प्रोग्राम को पर्याप्त दबाव में लाने के लिए पर्याप्त दबाव उत्पन्न कर सके।

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

OpenResty अभ्यास पर वापस जाते हुए, हमारा अनुशंसित प्रदर्शन परीक्षण उपकरण wrk है। सबसे पहले, हम इसे क्यों चुनते हैं?

पहला, wrk टूल चयन के मानदंड को पूरा करता है। एकल मशीन पर wrk द्वारा उत्पन्न दबाव आसानी से NGINX को 100% CPU उपयोग तक पहुंचा सकता है, अन्य सर्वर-साइड एप्लिकेशन्स की बात तो छोड़िए।

दूसरा, wrk में OpenResty के साथ बहुत सारी समानताएं हैं। wrk एक खरोंच से लिखा गया ओपन-सोर्स प्रोजेक्ट नहीं है; यह LuaJIT और Redis के कंधों पर खड़ा है और सिस्टम के मल्टी-कोर संसाधनों का लाभ उठाता है ताकि अनुरोध उत्पन्न कर सके। इसके अलावा, wrk एक Lua API प्रदान करता है जो आपको अपने Lua स्क्रिप्ट्स को एम्बेड करने की अनुमति देता है ताकि अनुरोध हेडर्स और सामग्री को कस्टमाइज़ कर सकें, जिससे यह बहुत लचीला हो जाता है।

तो हमें wrk का उपयोग कैसे करना चाहिए? यह निम्नलिखित कोड स्निपेट को देखने जितना आसान है।

wrk -t12 -c400 -d30s http://127.0.0.1:8080/index.html

इसका मतलब है कि wrk 12 थ्रेड्स का उपयोग करेगा, 30 सेकंड के लिए 400 लॉन्ग कनेक्शन्स को होल्ड करेगा, और निर्दिष्ट API इंटरफेस पर HTTP अनुरोध भेजेगा। बेशक, यदि आप पैरामीटर्स निर्दिष्ट नहीं करते हैं, तो wrk डिफ़ॉल्ट रूप से दो थ्रेड्स और दस लॉन्ग कनेक्शन्स शुरू करेगा।

परीक्षण वातावरण

परीक्षण उपकरण ढूंढने के बाद, हम सीधे स्ट्रेस टेस्ट शुरू नहीं कर सकते। हमें परीक्षण वातावरण को एक बार जांचना होगा। परीक्षण वातावरण में चार मुख्य आइटम्स हैं जिन्हें जांचना होगा, और मैं उन्हें विस्तार से चर्चा करूंगा।

1. SELinux बंद करें

यदि आपके पास CentOS/RedHat ऑपरेटिंग सिस्टम है, तो यह अनुशंसा की जाती है कि आप SELinux को बंद कर दें। अन्यथा, आपको बहुत सारे अजीब अनुमति समस्याओं का सामना करना पड़ सकता है।

आइए निम्नलिखित कमांड के साथ जांचें कि SELinux चालू है या नहीं।

$ sestatus SELinux status: disabled

यदि यह कहता है कि यह चालू है (enforcing), तो आप इसे अस्थायी रूप से $ setenforce 0 द्वारा बंद कर सकते हैं; साथ ही, /etc/selinux/config फ़ाइल को संशोधित करके इसे स्थायी रूप से बंद करने के लिए SELINUX=enforcing को SELINUX=disabled में बदलें।

2. खुली फ़ाइलों की अधिकतम संख्या

फिर, आपको निम्नलिखित कमांड के साथ वर्तमान सिस्टम की कुल खुली फ़ाइलों की अधिकतम संख्या की जांच करनी होगी।

$ cat /proc/sys/fs/file-nr 3984 0 3255296

यहां अंतिम संख्या 3255296 खुली फ़ाइलों की अधिकतम संख्या है। यदि आपकी मशीन पर यह संख्या छोटी है, तो आपको /etc/sysctl.conf फ़ाइल को संशोधित करके इसे बढ़ाना होगा।

fs.file-max = 1020000 net.ipv4.ip_conntrack_max = 1020000 net.ipv4.netfilter.ip_conntrack_max = 1020000

संशोधन के बाद, आपको सिस्टम सेवा को पुनरारंभ करना होगा ताकि यह प्रभावी हो सके।

sudo sysctl -p /etc/sysctl.conf

3. प्रक्रिया सीमाएं

सिस्टम पर खुली फ़ाइलों की कुल अधिकतम संख्या के अलावा, एक प्रक्रिया द्वारा खोली जा सकने वाली फ़ाइलों की संख्या की भी एक सीमा होती है, जिसे आप ulimit कमांड के साथ जांच सकते हैं।

$ ulimit -n 1024

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

ulimit -n 1024000

आप इसे स्थायी बनाने के लिए कॉन्फ़िगरेशन फ़ाइल /etc/security/limits.conf को भी संशोधित कर सकते हैं।

* hard nofile 1024000 * soft nofile 1024000

4. NGINX कॉन्फ़िगरेशन

अंत में, आपको NGINX कॉन्फ़िगरेशन में एक छोटा सा परिवर्तन करना होगा, जो निम्नलिखित तीन लाइन्स का कोड है।

events { worker_connections 10240; }

यह हमें प्रति वर्कर कनेक्शन्स की संख्या बढ़ाने की अनुमति देता है। चूंकि डिफ़ॉल्ट मान केवल 512 है, यह उच्च स्ट्रेस टेस्ट्स के लिए पर्याप्त नहीं है।

स्ट्रेस टेस्ट से पहले जांच

इस बिंदु पर, परीक्षण वातावरण तैयार है। आप इसे शुरू करने और परीक्षण करने के लिए उत्सुक होंगे, है ना? wrk के साथ परीक्षण शुरू करने से पहले आइए एक बार और जांच कर लें। आखिरकार, लोग गलतियाँ करते हैं, इसलिए क्रॉस-टेस्ट करना आवश्यक है।

यह अंतिम परीक्षण दो चरणों में विभाजित किया जा सकता है।

1. स्वचालित टूल c1000k का उपयोग करें

c1000k SSDB के लेखक से आता है। जैसा कि आप नाम से देख सकते हैं, इस टूल का उद्देश्य यह जांचना है कि क्या आपका वातावरण 10^6 समवर्ती कनेक्शन्स की आवश्यकताओं को पूरा कर सकता है।

इस टूल का उपयोग भी सीधा है। हम एक server और एक client शुरू करते हैं, जो सर्वर प्रोग्राम को पोर्ट 7000 पर सुनने और क्लाइंट प्रोग्राम को स्ट्रेस टेस्ट लॉन्च करने के लिए मेल खाता है ताकि वास्तविक वातावरण में स्ट्रेस टेस्ट का अनुकरण किया जा सके:

. /server 7000 . /client 127.0.0.1 7000

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

2. जांचें कि सर्वर प्रोग्राम सामान्य रूप से चल रहा है या नहीं

यदि सर्वर-साइड प्रोग्राम सही ढंग से काम नहीं कर रहा है, तो स्ट्रेस टेस्ट एक त्रुटि लॉग रिफ्रेश टेस्ट या 404 प्रतिक्रिया टेस्ट बन सकता है।

इसलिए, परीक्षण वातावरण परीक्षण का अंतिम और सबसे महत्वपूर्ण चरण है सर्वर-साइड यूनिट टेस्ट सेट को चलाना या मैन्युअल रूप से कुछ प्रमुख इंटरफेस को कॉल करना ताकि यह सुनिश्चित किया जा सके कि wrk टेस्ट के सभी इंटरफेस, रिटर्न्स, और HTTP प्रतिक्रिया कोड सामान्य हैं और logs/error.log में कोई त्रुटि-स्तर के संदेश नहीं हैं।

अनुरोध भेजना

ठीक है, तो अब सब कुछ तैयार है। आइए wrk के साथ स्ट्रेस टेस्टिंग शुरू करें!

$ wrk -d 30 http://127.0.0.2:9080/hello Running 30s test @ http://127.0.0.2:9080/hello 2 threads and 10 connections Thread Stats Avg Stdev Max +/- Stdev Latency 595.39us 178.51us 22.24ms 90.63% Req/Sec 8.33k 642.91 9.46k 59.80% 499149 requests in 30.10s, 124.22MB read Requests/sec: 16582.76 Transfer/sec: 4.13MB

मैंने यहां पैरामीटर्स निर्दिष्ट नहीं किए हैं ताकि wrk डिफ़ॉल्ट रूप से 2 थ्रेड्स और 10 लॉन्ग कनेक्शन्स शुरू करे। आपको wrk में थ्रेड्स और कनेक्शन्स की संख्या को बहुत बड़ा करने की आवश्यकता नहीं है; जब तक आप लक्ष्य प्रोग्राम को 100% CPU उपयोग तक पहुंचा सकते हैं, तब तक आप ठीक हैं।

लेकिन स्ट्रेस टेस्ट का समय बहुत कम नहीं होना चाहिए क्योंकि कुछ सेकंड का स्ट्रेस टेस्ट अर्थहीन है। अन्यथा, स्ट्रेस टेस्ट समाप्त होने से पहले ही सर्वर प्रोग्राम हॉट रीलोडिंग पूरी कर लेगा। साथ ही, आपको top या htop जैसे मॉनिटरिंग टूल का उपयोग करना होगा ताकि यह जांच सकें कि स्ट्रेस टेस्ट के दौरान सर्वर पर लक्ष्य प्रोग्राम 100% CPU उपयोग पर चल रहा है या नहीं।

प्रतीकात्मक रूप से, यदि CPU पूरी तरह से लोड हो जाता है और टेस्ट रुकने के बाद CPU और मेमोरी उपयोग तेजी से कम हो जाता है, तो बधाई हो, टेस्ट सफलतापूर्वक पूरा हो गया है। हालांकि, यदि निम्नलिखित जैसी कोई असामान्यताएं हैं, तो एक सर्वर-साइड डेवलपर के रूप में, आपको ध्यान देना चाहिए।

  • CPU पूरी तरह से लोड नहीं हो सकता है। यह wrk की समस्या नहीं है; यह नेटवर्क सीमा या आपके कोड में ब्लॉकिंग ऑपरेशन हो सकता है। आप इसे अपने कोड की समीक्षा करके या off CPU फ्लेम ग्राफ का उपयोग करके निर्धारित कर सकते हैं।
  • CPU हमेशा पूरी तरह से लोड रहता है, भले ही स्ट्रेस रुक जाए। यह कोड में एक अनंत लूप का संकेत देता है जो एक रेगुलर एक्सप्रेशन या LuaJIT बग के कारण हो सकता है, जो मैंने वास्तविक वातावरण में अनुभव किया है। इस बिंदु पर, आपको CPU फ्लेम ग्राफ का उपयोग करके यह निर्धारित करना होगा।

अंत में, आइए wrk के आंकड़ों को देखें। इस परिणाम के संबंध में, हम आमतौर पर दो मानों पर ध्यान केंद्रित करते हैं।

पहला है QPS, या Requests/sec: 16582.76, जो एक सटीक आंकड़ा है जो दर्शाता है कि सर्वर साइड पर प्रति सेकंड कितने अनुरोध संसाधित होते हैं।

दूसरा है विलंबता: Latency 595.39us 178.51us 22.24ms 90.63%, जो QPS के समान महत्वपूर्ण है, जो सिस्टम की प्रतिक्रिया गति को दर्शाता है। उदाहरण के लिए, गेटवे एप्लिकेशन्स के लिए, हम विलंबता को 1 ms के भीतर रखना चाहते हैं।

इसके अलावा, wrk एक latency पैरामीटर भी प्रदान करता है जो विलंबता के प्रतिशत वितरण को विस्तार से प्रिंट करता है, उदाहरण के लिए।

Latency Distribution 50% 134.00us 75% 180.00us 90% 247.00us 99% 552.00us

हालांकि, wrk विलंबता वितरण डेटा सटीक नहीं है क्योंकि यह कृत्रिम रूप से नेटवर्क और टूल के परेशानियों को जोड़ता है जो विलंबता को बढ़ाते हैं, जिस पर आपका विशेष ध्यान देने की आवश्यकता है।

सारांश

प्रदर्शन परीक्षण एक तकनीकी काम है; बहुत से लोग इसे सही और अच्छी तरह से नहीं कर सकते हैं। मुझे आशा है कि यह लेख आपको प्रदर्शन परीक्षण की अधिक व्यापक समझ प्रदान करेगा।

अंत में, मैं आपके साथ एक प्रश्न छोड़ता हूं: wrk कस्टम Lua स्क्रिप्ट्स का समर्थन करता है ताकि स्ट्रेस टेस्टिंग की जा सके, तो क्या आप इसके दस्तावेज़ीकरण के आधार पर एक सरल Lua स्क्रिप्ट लिख सकते हैं? यह थोड़ा मुश्किल हो सकता है, लेकिन जब आप इसे पूरा कर लेंगे, तो आप wrk के एक्सपोज़्ड इंटरफेस के इरादे को समझ जाएंगे।

आप इस लेख को अधिक लोगों के साथ साझा करने के लिए स्वागत करते हैं, और हम साथ में प्रगति करेंगे।