डिस्ट्रिब्यूट किए गए बिल्ड

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

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

रिमोट कैशिंग

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

रिमोट कैशिंग के साथ डिस्ट्रिब्यूट किया गया बिल्ड

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

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

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

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

रिमोट तरीके से एक्ज़ीक्यूट करें

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

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

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

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

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

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

Google पर डिस्ट्रिब्यूट किए गए बिल्ड

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

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

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

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

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

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