1. खास जानकारी
क्लाइंट ऐप्लिकेशन और फ़्रंटएंड वेब डेवलपर, आम तौर पर अपने कोड की परफ़ॉर्मेंस को बेहतर बनाने के लिए, Android Studio सीपीयू प्रोफ़ाइलर या Chrome में शामिल प्रोफ़ाइलिंग टूल जैसे टूल इस्तेमाल करते हैं. हालांकि, बैकएंड सेवाओं का इस्तेमाल करने वाले लोग इनके बराबर ही इन तकनीकों को ऐक्सेस नहीं कर पाते या इन्हें अच्छी तरह अपना नहीं पाते. Cloud Profiler से, डेवलपर को ये सुविधाएं मिलती हैं. भले ही, उनका कोड Google Cloud Platform पर चल रहा हो या किसी दूसरी जगह पर.
यह टूल आपके प्रोडक्शन ऐप्लिकेशन से, सीपीयू के इस्तेमाल और मेमोरी के बंटवारे की जानकारी इकट्ठा करता है. यह इस जानकारी को ऐप्लिकेशन के सोर्स कोड से जोड़ता है. इससे ऐप्लिकेशन के उन हिस्सों की पहचान करने में मदद मिलती है जो सबसे ज़्यादा संसाधनों का इस्तेमाल करते हैं. साथ ही, यह कोड की परफ़ॉर्मेंस के बारे में जानकारी देता है. टूल में इस्तेमाल की जाने वाली, इकट्ठा करने की तकनीकों की कम जगह, इसे प्रोडक्शन एनवायरमेंट में लगातार इस्तेमाल करने के लिहाज़ से सही बनाती है.
इस कोडलैब में, आपको Go प्रोग्राम के लिए Cloud Profiler सेट अप करने का तरीका पता चलेगा. साथ ही, आपको यह भी पता चलेगा कि यह टूल, ऐप्लिकेशन की परफ़ॉर्मेंस के बारे में किस तरह की अहम जानकारी दे सकता है.
आपको इनके बारे में जानकारी मिलेगी
- Cloud Profiler की मदद से प्रोफ़ाइल बनाने के लिए, Go प्रोग्राम को कॉन्फ़िगर करने का तरीका.
- Cloud Profiler की मदद से परफ़ॉर्मेंस डेटा इकट्ठा करने, देखने, और उसका विश्लेषण करने का तरीका.
आपको इन चीज़ों की ज़रूरत होगी
- Google Cloud Platform प्रोजेक्ट
- Chrome या Firefox ब्राउज़र जैसा कोई ब्राउज़र
- Vim, EMAC या Nano जैसे स्टैंडर्ड Linux टेक्स्ट एडिटर के बारे में जानकारी
इस ट्यूटोरियल का इस्तेमाल कैसे किया जाएगा?
Google Cloud Platform के साथ अपने अनुभव को आप कितनी रेटिंग देंगे?
2. सेटअप और ज़रूरी शर्तें
अपने हिसाब से एनवायरमेंट सेटअप करना
- Cloud Console में साइन इन करें और नया प्रोजेक्ट बनाएं या किसी मौजूदा प्रोजेक्ट का फिर से इस्तेमाल करें. अगर आपके पास पहले से Gmail या Google Workspace खाता नहीं है, तो आपको नया खाता बनाना होगा.
प्रोजेक्ट आईडी याद रखें. यह Google Cloud के सभी प्रोजेक्ट के लिए एक खास नाम होता है (ऊपर दिया गया नाम पहले ही ले लिया गया है और यह आपके लिए काम नहीं करेगा!). बाद में, इस कोडलैब को इस कोडलैब में PROJECT_ID
के तौर पर दिखाया जाएगा.
- इसके बाद, आपको Google Cloud के संसाधनों का इस्तेमाल करने के लिए, Cloud Console में बिलिंग की सुविधा चालू करनी होगी.
इस कोडलैब का इस्तेमाल करने पर, आपको ज़्यादा पैसे नहीं चुकाने होंगे. "साफ़ करना" सेक्शन में दिए गए निर्देशों का पालन करना न भूलें सेक्शन में, संसाधनों को बंद करने का तरीका बताया गया है. इससे इस ट्यूटोरियल के अलावा बिलिंग की सुविधा नहीं मिलेगी. Google Cloud के नए उपयोगकर्ता, 300 डॉलर के मुफ़्त ट्रायल वाले प्रोग्राम में हिस्सा ले सकते हैं.
Google Cloud शेल
Google Cloud को आपके लैपटॉप से कहीं से भी ऑपरेट किया जा सकता है. हालांकि, इस कोडलैब में सेटअप को आसान बनाने के लिए, हम Google Cloud Shell का इस्तेमाल करेंगे. यह क्लाउड में चलने वाला कमांड लाइन एनवायरमेंट है.
Cloud Shell चालू करें
- Cloud Console में, Cloud Shell चालू करें पर क्लिक करें.
अगर आपने Cloud Shell का इस्तेमाल पहले कभी नहीं किया है, तो आपको इसके बारे में जानकारी देने वाली एक इंटरमीडिएट स्क्रीन (पेज के फ़ोल्ड के नीचे) दिखेगी. अगर ऐसा है, तो जारी रखें पर क्लिक करें (यह आपको फिर कभी नहीं दिखेगा). एक बार इस्तेमाल होने वाली स्क्रीन कुछ इस तरह दिखती है:
प्रावधान करने और Cloud Shell से कनेक्ट होने में कुछ ही समय लगेगा.
इस वर्चुअल मशीन में ऐसे सभी डेवलपमेंट टूल मौजूद हैं जिनकी आपको ज़रूरत है. यह पांच जीबी की स्थायी होम डायरेक्ट्री उपलब्ध कराता है और Google Cloud में चलता है. इससे नेटवर्क की परफ़ॉर्मेंस और पुष्टि करने की प्रक्रिया को बेहतर बनाने में मदद मिलती है. अगर सभी नहीं, तो इस कोडलैब में आपका बहुत सारा काम बस किसी ब्राउज़र या आपके Chromebook से किया जा सकता है.
Cloud Shell से कनेक्ट करने के बाद, आपको दिखेगा कि आपकी पुष्टि पहले ही हो चुकी है. साथ ही, यह प्रोजेक्ट पहले से ही आपके प्रोजेक्ट आईडी पर सेट है.
- यह पुष्टि करने के लिए Cloud Shell में नीचे दिया गया कमांड चलाएं कि आपकी पुष्टि हो गई है:
gcloud auth list
कमांड आउटपुट
Credentialed Accounts ACTIVE ACCOUNT * <my_account>@<my_domain.com> To set the active account, run: $ gcloud config set account `ACCOUNT`
- Cloud Shell में यह कमांड चलाएं, ताकि यह पुष्टि की जा सके कि gcloud के लिए कमांड को आपके प्रोजेक्ट के बारे में जानकारी है:
gcloud config list project
कमांड आउटपुट
[core] project = <PROJECT_ID>
अगर ऐसा नहीं है, तो आप इसे इस निर्देश की मदद से सेट कर सकते हैं:
gcloud config set project <PROJECT_ID>
कमांड आउटपुट
Updated property [core/project].
3. Cloud Profiler पर जाएं
Cloud Console में, "प्रोफ़ाइलर" पर क्लिक करके प्रोफ़ाइलर यूज़र इंटरफ़ेस (यूआई) पर जाएं से लिंक करने के लिए:
इसके अलावा, प्रोफ़ाइलर यूज़र इंटरफ़ेस (यूआई) पर जाने के लिए, Cloud Console के खोज बार का इस्तेमाल किया जा सकता है. इसके लिए, बस "Cloud Profiler" टाइप करें और पाए गए आइटम को चुनें. दोनों ही मामलों में, आपको "डिसप्ले के लिए कोई डेटा नहीं है" विकल्प के साथ प्रोफ़ाइलर यूज़र इंटरफ़ेस (यूआई) दिखेगा नीचे दिया गया मैसेज लिखें. यह नया प्रोजेक्ट है, इसलिए इसमें अभी तक प्रोफ़ाइलिंग से जुड़ा कोई डेटा इकट्ठा नहीं किया गया है.
अब कुछ प्रोफ़ाइल करने का समय है!
4. मानदंड तय करें
हम GitHub पर उपलब्ध सिंथेटिक Go ऐप्लिकेशन का इस्तेमाल करेंगे. Cloud Shell टर्मिनल में, जो आपने अब भी खोला है (और प्रोफ़ाइलर यूज़र इंटरफ़ेस (यूआई) में "कोई डेटा नहीं है" मैसेज दिख रहा है), तब नीचे दिया गया निर्देश चलाएं:
$ go get -u github.com/GoogleCloudPlatform/golang-samples/profiler/...
फिर ऐप्लिकेशन निर्देशिका पर स् विच करें:
$ cd ~/gopath/src/github.com/GoogleCloudPlatform/golang-samples/profiler/hotapp
इस डायरेक्ट्री में "main.go" शामिल है फ़ाइल पर जाएं, जो एक सिंथेटिक ऐप्लिकेशन है. इसमें प्रोफ़ाइलिंग एजेंट चालू है:
main.go
...
import (
...
"cloud.google.com/go/profiler"
)
...
func main() {
err := profiler.Start(profiler.Config{
Service: "hotapp-service",
DebugLogging: true,
MutexProfiling: true,
})
if err != nil {
log.Fatalf("failed to start the profiler: %v", err)
}
...
}
प्रोफ़ाइलिंग एजेंट, डिफ़ॉल्ट रूप से सीपीयू, हीप, और थ्रेड प्रोफ़ाइल इकट्ठा करता है. यहां दिया गया कोड, म्यूटेक्स (इसे "कन्शन" भी कहा जाता है) प्रोफ़ाइलों को इकट्ठा करने की सुविधा देता है.
अब प्रोग्राम चलाएं:
$ go run main.go
प्रोग्राम के चलने के दौरान, प्रोफ़ाइलिंग एजेंट समय-समय पर कॉन्फ़िगर किए गए पांच टाइप की प्रोफ़ाइलें इकट्ठा करेगा. समय के साथ, कलेक्शन को किसी भी क्रम में लगाया जाता है. इसमें हर टाइप के लिए, एक मिनट की औसतन प्रोफ़ाइल की दर होती है. इसलिए, हर तरह के डेटा को इकट्ठा करने में तीन मिनट तक लग सकते हैं. जब कोई प्रोग्राम प्रोफ़ाइल बनाता है, तो आपको इसकी सूचना मिलती है. ऊपर दिए गए कॉन्फ़िगरेशन में, मैसेज को DebugLogging
फ़्लैग की मदद से चालू किया गया है; अगर ऐसा नहीं होता है, तो एजेंट बिना किसी आवाज़ के काम करता है:
$ go run main.go 2018/03/28 15:10:24 profiler has started 2018/03/28 15:10:57 successfully created profile THREADS 2018/03/28 15:10:57 start uploading profile 2018/03/28 15:11:19 successfully created profile CONTENTION 2018/03/28 15:11:30 start uploading profile 2018/03/28 15:11:40 successfully created profile CPU 2018/03/28 15:11:51 start uploading profile 2018/03/28 15:11:53 successfully created profile CONTENTION 2018/03/28 15:12:03 start uploading profile 2018/03/28 15:12:04 successfully created profile HEAP 2018/03/28 15:12:04 start uploading profile 2018/03/28 15:12:04 successfully created profile THREADS 2018/03/28 15:12:04 start uploading profile 2018/03/28 15:12:25 successfully created profile HEAP 2018/03/28 15:12:25 start uploading profile 2018/03/28 15:12:37 successfully created profile CPU ...
पहली प्रोफ़ाइल इकट्ठा करने के कुछ समय बाद, यूज़र इंटरफ़ेस (यूआई) अपने-आप अपडेट हो जाएगा. इसके बाद, यह अपने-आप अपडेट नहीं होगा. इसलिए, नया डेटा देखने के लिए, आपको प्रोफ़ाइलर के यूज़र इंटरफ़ेस (यूआई) को मैन्युअल तरीके से रीफ़्रेश करना होगा. ऐसा करने के लिए, समय अंतराल पिकर में अभी बटन पर दो बार क्लिक करें:
यूज़र इंटरफ़ेस (यूआई) रीफ़्रेश होने के बाद, आपको कुछ ऐसा दिखेगा:
प्रोफ़ाइल टाइप चुनने के लिए फ़िल्टर चुनने पर, प्रोफ़ाइल के पांच टाइप के विकल्प दिखते हैं:
अब हर तरह की प्रोफ़ाइल और यूज़र इंटरफ़ेस (यूआई) की कुछ अहम क्षमताओं की समीक्षा करते हैं. इसके बाद, कुछ एक्सपेरिमेंट करते हैं. इस चरण में, अब आपको Cloud Shell टर्मिनल की ज़रूरत नहीं है. इसलिए, CTRL-C दबाकर और "बाहर निकलें" टाइप करके, टर्मिनल से बाहर निकला जा सकता है.
5. प्रोफ़ाइलर के डेटा का विश्लेषण करें
अब जबकि हमने कुछ डेटा एकत्र कर लिया है, तो आइए अब इस पर अधिक बारीकी से गौर करें. हम एक ऐसे सिंथेटिक ऐप्लिकेशन का इस्तेमाल कर रहे हैं जिसका सोर्स GitHub पर उपलब्ध है. यह ऐप्लिकेशन, प्रोडक्शन के दौरान परफ़ॉर्मेंस से जुड़ी अलग-अलग तरह की समस्याओं के बारे में नकल करता है.
सीपीयू-इंटेंसिव कोड
चुनें कि सीपीयू प्रोफ़ाइल का टाइप किस तरह का है. यूज़र इंटरफ़ेस (यूआई) के लोड होने के बाद, आपको load
फ़ंक्शन के लिए चार लीफ़ ब्लॉक, फ़्लेम ग्राफ़ में दिखेंगे. ये ब्लॉक सभी सीपीयू के इस्तेमाल की जानकारी देते हैं:
इस फ़ंक्शन को खास तौर पर, बहुत ज़्यादा सीपीयू साइकल का इस्तेमाल करने के लिए बनाया गया है. ऐसा करने के लिए, सटीक लूप में चलाएं:
main.go
func load() {
for i := 0; i < (1 << 20); i++ {
}
}
फ़ंक्शन को अप्रत्यक्ष रूप से busyloop
() से चार कॉल पाथ के ज़रिए कॉल किया जाता है: busyloop
→ {foo1
, foo2
} → {bar
, baz
} → load
. फ़ंक्शन बॉक्स की चौड़ाई, किसी कॉल पाथ की लागत के बारे में बताती है. इस मामले में, सभी चार पाथ की लागत करीब-करीब एक जैसी है. असल में, आपको उन कॉल पाथ को ऑप्टिमाइज़ करने पर फ़ोकस करना है जो परफ़ॉर्मेंस के लिहाज़ से सबसे अहम हों. फ़्लेम ग्राफ़, बड़े बॉक्स वाले ज़्यादा महंगे पाथ दिखाता है. इस वजह से, इन पाथ की पहचान करना आसान हो जाता है.
प्रोफ़ाइल के डेटा फ़िल्टर का इस्तेमाल करके, डिसप्ले कैंपेन को और बेहतर बनाया जा सकता है. उदाहरण के लिए, "स्टैक दिखाएं" जोड़कर देखें "baz" दर्ज करने वाला फ़िल्टर का उपयोग करें. आपको नीचे दिए गए स्क्रीनशॉट की तरह कुछ दिखेगा, जिसमें load()
के लिए दिए गए चार में से सिर्फ़ दो कॉल पाथ दिखाए गए हैं. सिर्फ़ इन दो पाथ का इस्तेमाल किया जाता है जो "baz" स्ट्रिंग वाले फ़ंक्शन से होकर गुज़रते हैं नाम में रखा जाएगा. इस तरह की फ़िल्टर करने की सुविधा तब काम आती है, जब आपको किसी बड़े प्रोग्राम के सब-पार्ट पर फ़ोकस करना हो. उदाहरण के लिए, क्योंकि प्रोग्राम का सिर्फ़ एक हिस्सा आपके पास होता है.
मेमोरी-गहन कोड
अब "हीप" पर स्विच करें प्रोफ़ाइल का टाइप. पिछले एक्सपेरिमेंट में बनाए गए सभी फ़िल्टर हटाना न भूलें. अब आपको एक फ़्लेम ग्राफ़ दिखेगा, जहां alloc
नाम के allocImpl
को ऐप्लिकेशन में मेमोरी के मुख्य उपभोक्ता के तौर पर दिखाया गया है:
फ़्लेम ग्राफ़ के ऊपर मौजूद समरी टेबल से पता चलता है कि ऐप्लिकेशन में इस्तेमाल की गई मेमोरी की कुल मात्रा औसतन ~57.4 एमबी है. इसमें से ज़्यादातर मेमोरी allocImpl
फ़ंक्शन की मदद से इकट्ठा की गई है. इस तरह के फ़ंक्शन के लागू होने की वजह से, यह कोई हैरानी की बात नहीं है:
main.go
func allocImpl() {
// Allocate 64 MiB in 64 KiB chunks
for i := 0; i < 64*16; i++ {
mem = append(mem, make([]byte, 64*1024))
}
}
यह फ़ंक्शन एक बार काम करता है और 64 MiB को छोटे-छोटे टुकड़ों में बांटता है. इसके बाद, इन समूहों के पॉइंटर को ग्लोबल वैरिएबल में स्टोर करता है, ताकि उन्हें कचरा इकट्ठा होने से बचाया जा सके. ध्यान दें कि प्रोफ़ाइलर के लिए इस्तेमाल की गई मेमोरी की मात्रा 64 एमबी से थोड़ी अलग है: गो हीप प्रोफ़ाइलर एक सांख्यिकीय टूल है, इसलिए माप कम ओवरहेड होते हैं, लेकिन बाइट-सटीक नहीं होते. ऐसा ~10% अंतर देखकर हैरान न हों.
IO-इंटेंसिव कोड
अगर आपने "Threads" चुना है, तो प्रोफ़ाइल टाइप चुनने वाले टूल में, डिसप्ले किसी फ़्लेम ग्राफ़ पर स्विच हो जाएगा. इसमें wait
और waitImpl
फ़ंक्शन, चौड़ाई के ज़्यादातर हिस्से को मापते हैं:
फ़्लेम ग्राफ़ के ऊपर दिए गए जवाब में, यह देखा जा सकता है कि wait
फ़ंक्शन से 100 गोरूटिन अपने कॉल स्टैक को बढ़ाते हैं. यह बिलकुल ठीक है, क्योंकि इन इंतज़ार को शुरू करने वाला कोड कुछ ऐसा दिखता है:
main.go
func main() {
...
// Simulate some waiting goroutines.
for i := 0; i < 100; i++ {
go wait()
}
इस तरह की प्रोफ़ाइल से यह समझने में मदद मिलती है कि प्रोग्राम, इंतज़ार के दौरान अचानक कोई समय बिता रहा है या नहीं (जैसे कि I/O). आम तौर पर, ऐसे कॉल स्टैक का सैंपल, सीपीयू प्रोफ़ाइलर नहीं लिया जाता. ऐसा इसलिए, क्योंकि ये सीपीयू समय का ज़्यादा इस्तेमाल नहीं करते. आप अक्सर "स्टैक छिपाएं" का इस्तेमाल करना चाहेंगे Threads प्रोफ़ाइल वाले फ़िल्टर - उदाहरण के लिए, उन सभी स्टैक को छिपाने के लिए जिनके आखिर में gopark,
को कॉल किया जाता है. ऐसा इसलिए, क्योंकि वे अक्सर इस्तेमाल न होने वाले खाते होते हैं और I/O पर इंतज़ार करने वाले उपयोगकर्ताओं की तुलना में कम दिलचस्प होते हैं.
थ्रेड प्रोफ़ाइल टाइप से उस प्रोग्राम में पॉइंट की पहचान करने में भी मदद मिल सकती है जहां थ्रेड लंबे समय तक प्रोग्राम के किसी अन्य हिस्से के मालिकाना हक वाले म्यूटेक्स का इंतज़ार करती हैं. हालांकि, उसके लिए यहां दिया गया प्रोफ़ाइल टाइप ज़्यादा काम का है.
कॉन्टेंट-इंटेंसिव कोड
Contention प्रोफ़ाइल प्रकार सबसे "इच्छित" की पहचान करता है होने से रोकने में मदद मिलती है. यह प्रोफ़ाइल टाइप, Go प्रोग्राम के लिए उपलब्ध है. हालांकि, इसे "MutexProfiling: true
" डालकर साफ़ तौर पर चालू किया जाना चाहिए डालें. कलेक्शन, रिकॉर्डिंग ("कॉन्टेंट" मेट्रिक के तहत) कितनी बार काम करता है. यह ऐसा तब होता है, जब किसी खास लॉक को, जब किसी गोरूटीन A से अनलॉक किया गया हो, तब दूसरे गोरूटीन B ने कितनी बार लॉक खुलने का इंतज़ार किया हो. यह "देर से" मेट्रिक में वह समय भी रिकॉर्ड करता है जब ब्लॉक किए गए गोरूटीन ने लॉक होने का इंतज़ार किया था. इस उदाहरण में, एक विवाद स्टैक है और लॉक होने के लिए कुल 10.5 सेकंड इंतज़ार का समय था:
इस प्रोफ़ाइल को जनरेट करने वाले कोड में, म्यूटेक्स पर लड़ते हुए 4 गोरूटिन शामिल हैं:
main.go
func contention(d time.Duration) {
contentionImpl(d)
}
func contentionImpl(d time.Duration) {
for {
mu.Lock()
time.Sleep(d)
mu.Unlock()
}
}
...
func main() {
...
for i := 0; i < 4; i++ {
go contention(time.Duration(i) * 50 * time.Millisecond)
}
}
6. खास जानकारी
इस लैब में आपने सीखा कि Go प्रोग्राम को Cloud Profiler के साथ इस्तेमाल करने के लिए कैसे कॉन्फ़िगर किया जा सकता है. आपने इस टूल की मदद से परफ़ॉर्मेंस के डेटा को इकट्ठा करने, देखने, और उसका विश्लेषण करने का तरीका भी सीखा है. अब आप अपने नए कौशल को Google Cloud Platform पर चलने वाली असली सेवाओं में लागू कर सकते हैं.
7. बधाई हो!
आपने Cloud Profiler को कॉन्फ़िगर और इस्तेमाल करने का तरीका सीख लिया है!
ज़्यादा जानें
- क्लाउड प्रोफ़ाइलर: https://cloud.google.com/profiler/
- रनटाइम/pprof पैकेज पर जाएं जिसका इस्तेमाल Cloud Profiler करता है: https://golang.org/pkg/runtime/pprof/
लाइसेंस
इस काम को क्रिएटिव कॉमंस एट्रिब्यूशन 2.0 जेनरिक लाइसेंस के तहत लाइसेंस मिला है.