डिस्ट्रिब्यूटेड बिल्ड

किसी समस्या की शिकायत करें स्रोत देखें

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

रिमोट कैशिंग

बिल्ड का सबसे आसान प्रकार वह है जिसमें सिर्फ़ रिमोट कैशिंग का इस्तेमाल किया जाता है, जैसा कि इमेज 1 में दिखाया गया है.

रिमोट तरीके से कैश मेमोरी में सेव करने की सुविधा वाला बिल्ड

पहला डायग्राम. डिस्ट्रिब्यूट किया गया बिल्ड जिसमें रिमोट कैश मेमोरी दिख रही है

डेवलपर के वर्कस्टेशन और लगातार इंटिग्रेशन वाले सिस्टम के साथ-साथ, बिल्ड परफ़ॉर्म करने वाला हर सिस्टम, रिमोट रिमोट कैश सेवा की जानकारी देता है. यह सेवा पूरी तरह से काम करने वाला तेज़ और लोकल स्टोरेज सिस्टम हो सकता है, जैसे कि Redis या Google Cloud Storage जैसी क्लाउड सेवा. जब भी उपयोगकर्ता को आर्टफ़ैक्ट बनाने की ज़रूरत होती है, चाहे वह सीधे तौर पर हो या डिपेंडेंसी के तौर पर हो, तो सिस्टम सबसे पहले रिमोट कैश मेमोरी से यह जांच करता है कि वह आर्टफ़ैक्ट वहां पहले से मौजूद है या नहीं. अगर हां, तो वह आर्टफ़ैक्ट बनाने के बजाय उसे डाउनलोड कर सकता है. अगर नहीं, तो सिस्टम खुद आर्टफ़ैक्ट बनाता है और नतीजे को कैश मेमोरी में वापस अपलोड करता है. इसका मतलब है कि कम-लेवल की डिपेंडेंसी जो अक्सर नहीं बदलती हैं, उन्हें एक बार बनाया जा सकता है और सभी उपयोगकर्ताओं के लिए दोबारा बनाने की ज़रूरत नहीं है. Google में, कई आर्टफ़ैक्ट, शुरुआत से बनाए जाने के बजाय कैश मेमोरी से दिखाए जाते हैं. इससे, हमारे बिल्ड सिस्टम को चलाने में बहुत खर्च होता है.

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

बेशक, रिमोट कैश मेमोरी का फ़ायदा उठाने के लिए किसी आर्टफ़ैक्ट को डाउनलोड करने में, उसे बनाने से ज़्यादा समय लगेगा. हालांकि, ऐसा हमेशा नहीं होता है, खास तौर पर तब, जब कैश सर्वर, मशीन बनाने से बहुत दूर हो. बिल्ड के नतीजों को तुरंत शेयर करने के लिए, Google का नेटवर्क और बिल्ड सिस्टम सावधानी से बनाया गया है.

रिमोट तरीके से पासवर्ड बदलें

रिमोट तरीके से कैश मेमोरी का इस्तेमाल करना, डिस्ट्रिब्यूट नहीं किया गया है. अगर कैश मेमोरी गायब हो जाती है या आप कोई ऐसा छोटा-सा बदलाव करते हैं जिसके लिए सभी चीज़ों को फिर से बनाने की ज़रूरत होती है, तो आपको अपना पूरा बिल्ड स्थानीय रूप से अपनी मशीन पर करना होगा. इसका लक्ष्य, रिमोट तरीके से एक्ज़ीक्यूशन करना है. इस बिल्ड में, कई वर्कर को अलग-अलग काम करने की सुविधा मिलती है. इमेज 2 में, रिमोट प्रोग्राम लागू करने का सिस्टम दिखाया गया है.

रिमोट एक्ज़ीक्यूशन सिस्टम

दूसरी इमेज. एक रिमोट एक्ज़ीक्यूशन सिस्टम

बिल्ड टूल हर उपयोगकर्ता की मशीन पर चलता है (जहां उपयोगकर्ता या तो मानव इंजीनियर या ऑटोमेटिक बिल्ड सिस्टम हैं) किसी सेंट्रल बिल्ड मास्टर को अनुरोध भेजता है. बिल्ड मास्टर अनुरोधों को अपनी कॉम्पोनेंट कार्रवाइयों में बांट देता है और उन कार्रवाइयों को लागू करने के लिए वर्कर लेवल को स्केल करता है. हर वर्कर, उपयोगकर्ता के बताए गए इनपुट के हिसाब से कार्रवाई करता है और नतीजे में मौजूद आर्टफ़ैक्ट को लिखता है. ये आर्टफ़ैक्ट, दूसरी मशीन में इस्तेमाल होने वाली ऐसी कार्रवाइयों के साथ शेयर किए जाते हैं जिनके लिए यह ज़रूरी है कि फ़ाइनल आउटपुट बनाया और उपयोगकर्ता को भेजा जाए.

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

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

Google पर डिस्ट्रिब्यूटेड बिल्ड

2008 से, Google एक डिस्ट्रिब्यूशन बिल्ड सिस्टम का इस्तेमाल कर रहा है. इसमें, तीसरे पक्ष की रिमोट कैशिंग और एक्ज़ीक्यूशन, दोनों का इस्तेमाल किया गया है. इस डायग्राम को डायग्राम 3 में दिखाया गया है.

हाई लेवल बिल्ड सिस्टम

तीसरी इमेज. Google का डिस्ट्रिब्यूटेड बिल्ड सिस्टम

Google के रिमोट कैश को ObjFS कहा जाता है. इसमें एक बैकएंड होता है, जो Bigtables के सभी प्रोडक्शन बेड़े में मौजूद आउटपुट टेबल को इकट्ठा करता है. साथ ही, इसका फ़्रंटएंड FUSE डीमन भी objfsd होता है, जो हर डेवलपर की मशीन पर चलता है. FUSE डीमन की मदद से इंजीनियर, बिल्ड आउटपुट को उसी तरह ब्राउज़ कर सकते हैं जैसे वर्कस्पेस पर सेव की गई सामान्य फ़ाइलें हों. हालांकि, फ़ाइल कॉन्टेंट की मदद से, उपयोगकर्ता की मांग पर ही कुछ फ़ाइलें डाउनलोड की जाती हैं. मांग पर फ़ाइल कॉन्टेंट उपलब्ध कराने से, नेटवर्क और डिस्क, दोनों का इस्तेमाल काफ़ी कम हो जाता है. साथ ही, हम डेवलपर के लोकल डिस्क में मौजूद सभी बिल्ड आउटपुट को सेव करने की तुलना में, सिस्टम को दो गुना ज़्यादा तेज़ी से कॉन्टेंट दिखा पाते हैं.

Google के रिमोट एक्ज़ीक्यूशन सिस्टम को फ़ोर्ज कहा जाता है. ब्लेज़ में एक फ़ोर्ज क्लाइंट (बेजल का आंतरिक सहयोगी), जिसे डिस्ट्रिब्यूटर कहते हैं, शेड्यूलर नाम की हमारे डेटा सेंटर में चल रही नौकरी के हर अनुरोध के लिए अनुरोध भेजता है. शेड्यूलर, कार्रवाई के नतीजों को कैश मेमोरी में रखता है, ताकि सिस्टम के किसी दूसरे उपयोगकर्ता ने कार्रवाई पहले ही बना दी हो. अगर ऐसा नहीं है, तो इससे कार्रवाई एक सूची में आ जाती है. एक्ज़ीक्यूटर के काम से जुड़ा एक बड़ा पूल इस सूची की कार्रवाइयों को लगातार पढ़ता है, उन्हें चलाता है और नतीजों को सीधे ObjFS Bigtables में सेव करता है. ये नतीजे आने वाले समय में, प्रोसेसर के लिए उपलब्ध होते हैं. साथ ही, असली उपयोगकर्ता इन्हें objfsd की मदद से डाउनलोड भी कर सकते हैं.

आखिर का नतीजा एक ऐसा सिस्टम है जो Google में परफ़ॉर्मेंस देने वाले सभी बिल्ड की परफ़ॉर्मेंस को बेहतर बनाने में मदद करता है. और Google के बिल्ड का दायरा बहुत बड़ा है: Google लाखों बिल्ड बनाता है. वह लाखों टेस्ट केस चलाता है और हर दिन करोड़ों सोर्स कोड के पेटाबाइट का प्रोडक्शन करता है. यह न सिर्फ़ हमारे सिस्टम में जटिल कोडबेस बनाने की सुविधा देता है, बल्कि इससे हमें बड़ी संख्या में ऐसे ऑटोमेटेड टूल और सिस्टम को लागू करने की अनुमति भी देता है जो हमारे बिल्ड पर निर्भर करते हैं.