इस पेज पर, रिमोट कैश मेमोरी की सुविधा, कैश मेमोरी को होस्ट करने के लिए सर्वर सेट अप करने, और रिमोट कैश मेमोरी का इस्तेमाल करके बिल्ड चलाने के बारे में बताया गया है.
डेवलपर की टीम और/या लगातार इंटिग्रेशन (सीआई) सिस्टम, बिल्ड के आउटपुट शेयर करने के लिए रिमोट कैश मेमोरी का इस्तेमाल करते हैं. अगर आपका बिल्ड फिर से बनाया जा सकता है, तो एक मशीन से मिले आउटपुट को दूसरी मशीन पर सुरक्षित तरीके से फिर से इस्तेमाल किया जा सकता है. इससे बिल्ड की प्रोसेस काफ़ी तेज़ हो सकती है.
खास जानकारी
Bazel, बिल्ड को अलग-अलग चरणों में बांटता है. इन्हें ऐक्शन कहा जाता है. हर ऐक्शन में इनपुट, आउटपुट के नाम, कमांड लाइन, और एनवायरमेंट वैरिएबल होते हैं. हर ऐक्शन के लिए, ज़रूरी इनपुट और अनुमानित आउटपुट साफ़ तौर पर तय किए जाते हैं.
बिल्ड के आउटपुट के लिए, रिमोट कैश मेमोरी के तौर पर काम करने के लिए सर्वर सेट अप किया जा सकता है. ये आउटपुट, ऐक्शन के आउटपुट होते हैं. इन आउटपुट में, आउटपुट फ़ाइल के नामों की सूची और उनके कॉन्टेंट के हैश शामिल होते हैं. रिमोट कैश मेमोरी की मदद से, हर नए आउटपुट को स्थानीय तौर पर बनाने के बजाय, किसी दूसरे उपयोगकर्ता के बिल्ड से मिले आउटपुट को फिर से इस्तेमाल किया जा सकता है.
रिमोट कैश मेमोरी की सुविधा का इस्तेमाल करने के लिए:
- किसी सर्वर को कैश मेमोरी के बैकएंड के तौर पर सेट अप करें
- Bazel बिल्ड को रिमोट कैश मेमोरी का इस्तेमाल करने के लिए कॉन्फ़िगर करें
- Bazel के 0.10.0 या उसके बाद के वर्शन का इस्तेमाल करें
रिमोट कैश मेमोरी में दो तरह का डेटा सेव किया जाता है:
- ऐक्शन कैश मेमोरी. यह ऐक्शन हैश को ऐक्शन के नतीजों के मेटाडेटा पर मैप करती है.
- आउटपुट फ़ाइलों का कॉन्टेंट-ऐड्रेसबल स्टोर (सीएएस).
ध्यान दें कि रिमोट कैश मेमोरी में, हर ऐक्शन के लिए stdout और stderr भी सेव किए जाते हैं. इसलिए, Bazel के stdout/stderr की जांच करना, कैश मेमोरी हिट का अनुमान लगाने के लिए सही तरीका नहीं है कैश मेमोरी हिट का अनुमान लगाना.
बिल्ड, रिमोट कैश मेमोरी की सुविधा का इस्तेमाल कैसे करता है
किसी सर्वर को रिमोट कैश मेमोरी के तौर पर सेट अप करने के बाद, कैश मेमोरी का इस्तेमाल कई तरीकों से किया जा सकता है:
- रिमोट कैश मेमोरी में डेटा पढ़ना और लिखना
- खास टारगेट को छोड़कर, रिमोट कैश मेमोरी में डेटा पढ़ना और/या लिखना
- सिर्फ़ रिमोट कैश मेमोरी से डेटा पढ़ना
- रिमोट कैश मेमोरी का इस्तेमाल न करना
जब Bazel का कोई ऐसा बिल्ड चलाया जाता है जो रिमोट कैश मेमोरी में डेटा पढ़ और लिख सकता है, तो बिल्ड इन चरणों को फ़ॉलो करता है:
- Bazel, उन टारगेट का ग्राफ़ बनाता है जिन्हें बिल्ड करना होता है. इसके बाद, ज़रूरी ऐक्शन की सूची बनाता है. इनमें से हर ऐक्शन के लिए, इनपुट और आउटपुट फ़ाइल के नाम तय किए जाते हैं.
- Bazel, आपकी स्थानीय मशीन पर मौजूद बिल्ड के आउटपुट की जांच करता है और मिलने वाले आउटपुट को फिर से इस्तेमाल करता है.
- Bazel, कैश मेमोरी में मौजूद बिल्ड के आउटपुट की जांच करता है. अगर आउटपुट मिल जाता है, तो Bazel उसे वापस लाता है. इसे कैश मेमोरी हिट कहा जाता है.
- जिन ज़रूरी ऐक्शन के लिए आउटपुट नहीं मिले हैं उनके लिए, Bazel स्थानीय तौर पर ऐक्शन करता है और ज़रूरी बिल्ड आउटपुट बनाता है.
- बिल्ड के नए आउटपुट, रिमोट कैश मेमोरी में अपलोड किए जाते हैं.
किसी सर्वर को कैश मेमोरी के बैकएंड के तौर पर सेट अप करना
आपको किसी सर्वर को कैश मेमोरी के बैकएंड के तौर पर सेट अप करना होगा. एचटीटीपी/1.1 सर्वर, Bazel के डेटा को अपारदर्शी बाइट के तौर पर ट्रीट कर सकता है. इसलिए, मौजूदा कई सर्वर को रिमोट कैश मेमोरी के बैकएंड के तौर पर इस्तेमाल किया जा सकता है. Bazel का एचटीटीपी कैश मेमोरी प्रोटोकॉल, रिमोट कैश मेमोरी की सुविधा के साथ काम करता है.
कैश मेमोरी में सेव किए गए आउटपुट को स्टोर करने के लिए, बैकएंड सर्वर चुनने, सेट अप करने, और उसका रखरखाव करने की ज़िम्मेदारी आपकी है. सर्वर चुनते समय, इन बातों का ध्यान रखें:
- नेटवर्किंग की स्पीड. उदाहरण के लिए, अगर आपकी टीम एक ही ऑफ़िस में है, तो अपना स्थानीय सर्वर चलाया जा सकता है.
- सुरक्षा. रिमोट कैश मेमोरी में आपकी बाइनरी सेव होंगी. इसलिए, इसे सुरक्षित रखना ज़रूरी है.
- मैनेज करने में आसानी. उदाहरण के लिए, Google Cloud Storage एक पूरी तरह से मैनेज की जाने वाली सेवा है.
रिमोट कैश मेमोरी के लिए, कई बैकएंड का इस्तेमाल किया जा सकता है. कुछ विकल्प यहां दिए गए हैं:
nginx
nginx एक ओपन सोर्स वेब सर्वर है. इसके [WebDAV module] का इस्तेमाल, Bazel के लिए रिमोट कैश मेमोरी के तौर पर किया जा सकता है. Debian और Ubuntu पर, nginx-extras पैकेज इंस्टॉल किया जा सकता है. macOS पर, nginx, Homebrew के ज़रिए उपलब्ध है:
brew tap denji/nginxbrew install nginx-full --with-webdav
यहां nginx के लिए कॉन्फ़िगरेशन का एक उदाहरण दिया गया है. ध्यान दें कि आपको /path/to/cache/dir को किसी मान्य डायरेक्ट्री में बदलना होगा. इस डायरेक्ट्री में nginx के पास डेटा लिखने और पढ़ने की अनुमति होनी चाहिए. अगर आपके पास बड़ी आउटपुट फ़ाइलें हैं, तो आपको client_max_body_size विकल्प को बड़ी वैल्यू में बदलना पड़ सकता है. सर्वर को पुष्टि करने की सुविधा जैसे अन्य कॉन्फ़िगरेशन की ज़रूरत होगी.
nginx.conf में server सेक्शन के लिए कॉन्फ़िगरेशन का उदाहरण:
location /cache/ {
# The path to the directory where nginx should store the cache contents.
root /path/to/cache/dir;
# Allow PUT
dav_methods PUT;
# Allow nginx to create the /ac and /cas subdirectories.
create_full_put_path on;
# The maximum size of a single file.
client_max_body_size 1G;
allow all;
}
bazel-remote
bazel-remote, रिमोट बिल्ड कैश मेमोरी की सुविधा देने वाला एक ओपन सोर्स टूल है. इसका इस्तेमाल, अपने इन्फ़्रास्ट्रक्चर पर किया जा सकता है. साल 2018 की शुरुआत से, कई कंपनियां इसका इस्तेमाल प्रोडक्शन में कर रही हैं. ध्यान दें कि Bazel प्रोजेक्ट, bazel-remote के लिए तकनीकी सहायता उपलब्ध नहीं कराता.
इस कैश मेमोरी में, डिस्क पर कॉन्टेंट सेव किया जाता है. साथ ही, इसमें गार्बेज कलेक्शन की सुविधा भी मिलती है. इससे स्टोरेज की ऊपरी सीमा लागू की जा सकती है और इस्तेमाल न किए गए आर्टफ़ैक्ट को हटाया जा सकता है. यह कैश मेमोरी, [docker image] के तौर पर उपलब्ध है. इसका कोड GitHub पर उपलब्ध है. इसमें, REST और gRPC, दोनों तरह के रिमोट कैश मेमोरी एपीआई काम करते हैं.
इसका इस्तेमाल करने के निर्देशों के लिए, GitHub पेज देखें.
Google Cloud Storage
[Google Cloud Storage], ऑब्जेक्ट स्टोर करने की पूरी तरह से मैनेज की जाने वाली सेवा है. यह एक एचटीटीपी एपीआई उपलब्ध कराती है, जो Bazel के रिमोट कैश मेमोरी प्रोटोकॉल के साथ काम करता है. इसके लिए, आपके पास बिलिंग की सुविधा चालू किया गया Google Cloud खाता होना ज़रूरी है.
कैश मेमोरी के तौर पर Cloud Storage का इस्तेमाल करने के लिए:
स्टोरेज बकेट बनाएं. पक्का करें कि आपने ऐसी बकेट की जगह चुनी हो जो आपके सबसे पास हो, क्योंकि रिमोट कैश मेमोरी के लिए नेटवर्क बैंडविथ ज़रूरी है.
Bazel के लिए एक सेवा खाता बनाएं, ताकि Cloud Storage पर पुष्टि की जा सके. सेवा खाता बनाना देखें .
सीक्रेट JSON कुंजी जनरेट करें. इसके बाद, पुष्टि करने के लिए इसे Bazel को पास करें. कुंजी को सुरक्षित तरीके से सेव करें, क्योंकि कुंजी वाले किसी भी व्यक्ति के पास, आपके GCS बकेट में डेटा पढ़ने और लिखने की अनुमति होती है.
Cloud Storage से कनेक्ट करने के लिए, अपने Bazel कमांड में ये फ़्लैग जोड़ें:
- Bazel को यह यूआरएल पास करने के लिए, इस फ़्लैग का इस्तेमाल करें:
--remote_cache=https://storage.googleapis.com/bucket-name. यहांbucket-nameआपकी स्टोरेज बकेट का नाम है. - पुष्टि करने की कुंजी पास करने के लिए, इस फ़्लैग का इस्तेमाल करें:
--google_credentials=/path/to/your/secret-key.json. इसके अलावा,--google_default_credentialsऐप्लिकेशन की पुष्टि करने की सुविधा का इस्तेमाल करने के लिए, Application Authentication का इस्तेमाल करें.
- Bazel को यह यूआरएल पास करने के लिए, इस फ़्लैग का इस्तेमाल करें:
Cloud Storage को पुरानी फ़ाइलों को अपने-आप मिटाने के लिए कॉन्फ़िगर किया जा सकता है. इसके लिए, ऑब्जेक्ट के लाइफ़साइकल मैनेज करना देखें.
अन्य सर्वर
कैश मेमोरी के बैकएंड के तौर पर, एचटीटीपी/1.1 का कोई भी ऐसा सर्वर सेट अप किया जा सकता है जो PUT और GET के साथ काम करता हो. उपयोगकर्ताओं ने Hazelcast, Apache httpd, और AWS S3 जैसे कैश मेमोरी बैकएंड के साथ सफलता की रिपोर्ट की है.
पुष्टि करना
Bazel के 0.11.0 वर्शन में, एचटीटीपी की बुनियादी पुष्टि करने की सुविधा जोड़ी गई है.
रिमोट कैश मेमोरी के यूआरएल के ज़रिए, Bazel को उपयोगकर्ता नाम और पासवर्ड पास किया जा सकता है. इसका सिंटैक्स https://username:password@hostname.com:port/path है. ध्यान दें कि एचटीटीपी की बुनियादी पुष्टि करने की सुविधा, नेटवर्क पर उपयोगकर्ता नाम और पासवर्ड को सादे टेक्स्ट में ट्रांसमिट करती है. इसलिए, इसका इस्तेमाल हमेशा एचटीटीपीएस के साथ करना ज़रूरी है.
एचटीटीपी कैश मेमोरी प्रोटोकॉल
Bazel, एचटीटीपी/1.1 के ज़रिए रिमोट कैश मेमोरी की सुविधा के साथ काम करता है. यह प्रोटोकॉल, कॉन्सेप्ट के तौर पर आसान है: बाइनरी डेटा (बीएलबी) को PUT अनुरोधों के ज़रिए अपलोड किया जाता है और GET अनुरोधों के ज़रिए डाउनलोड किया जाता है.
ऐक्शन के नतीजों का मेटाडेटा, /ac/ पाथ के तहत सेव किया जाता है. वहीं, आउटपुट फ़ाइलें, /cas/ पाथ के तहत सेव की जाती हैं.
उदाहरण के लिए, मान लें कि रिमोट कैश मेमोरी, http://localhost:8080/cache के तहत काम कर रही है.
SHA256 हैश 01ba4719... वाले किसी ऐक्शन के लिए, ऐक्शन के नतीजों का मेटाडेटा डाउनलोड करने का Bazel अनुरोध इस तरह दिखेगा:
GET /cache/ac/01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b HTTP/1.1
Host: localhost:8080
Accept: */*
Connection: Keep-Alive
सीएएस में, SHA256 हैश 15e2b0d3... वाली आउटपुट फ़ाइल अपलोड करने का Bazel अनुरोध इस तरह दिखेगा:
PUT /cache/cas/15e2b0d3c33891ebb0f1ef609ec419420c20e320ce94c65fbc8c3312448eb225 HTTP/1.1
Host: localhost:8080
Accept: */*
Content-Length: 9
Connection: Keep-Alive
0x310x320x330x340x350x360x370x380x39
रिमोट कैश मेमोरी का इस्तेमाल करके Bazel चलाना
किसी सर्वर को रिमोट कैश मेमोरी के तौर पर सेट अप करने के बाद, रिमोट कैश मेमोरी का इस्तेमाल करने के लिए, आपको अपने Bazel कमांड में फ़्लैग जोड़ने होंगे. कॉन्फ़िगरेशन और उनके फ़्लैग की सूची यहां दी गई है.
आपको पुष्टि करने की सुविधा को भी कॉन्फ़िगर करना पड़ सकता है. यह आपके चुने गए सर्वर के हिसाब से अलग-अलग होती है.
.bazelrc फ़ाइल में ये फ़्लैग जोड़े जा सकते हैं, ताकि Bazel को हर बार चलाते समय इन्हें तय न करना पड़े. अपने प्रोजेक्ट और टीम के हिसाब से, .bazelrc फ़ाइल में फ़्लैग जोड़े जा सकते हैं. यह फ़ाइल:
- आपकी स्थानीय मशीन पर मौजूद हो
- आपके प्रोजेक्ट के वर्कस्पेस में मौजूद हो और टीम के साथ शेयर की गई हो
- सीआई सिस्टम पर मौजूद हो
रिमोट कैश मेमोरी में डेटा पढ़ना और लिखना
ध्यान रखें कि रिमोट कैश मेमोरी में डेटा लिखने की अनुमति किसे है. ऐसा हो सकता है कि आपको सिर्फ़ अपने सीआई सिस्टम को रिमोट कैश मेमोरी में डेटा लिखने की अनुमति देनी हो.
रिमोट कैश मेमोरी में डेटा पढ़ने और लिखने के लिए, इस फ़्लैग का इस्तेमाल करें:
build --remote_cache=http://your.host:portHTTP के अलावा, इन प्रोटोकॉल के साथ भी काम किया जा सकता है: HTTPS, grpc, grpcs.
रिमोट कैश मेमोरी से सिर्फ़ डेटा पढ़ने के लिए, ऊपर दिए गए फ़्लैग के अलावा, इस फ़्लैग का इस्तेमाल करें:
build --remote_upload_local_results=falseरिमोट कैश मेमोरी का इस्तेमाल करने से खास टारगेट को बाहर रखना
रिमोट कैश मेमोरी का इस्तेमाल करने से खास टारगेट को बाहर रखने के लिए, टारगेट को no-cache टैग करें. उदाहरण के लिए:
java_library(
name = "target",
tags = ["no-cache"],
)
रिमोट कैश मेमोरी से कॉन्टेंट मिटाना
रिमोट कैश मेमोरी से कॉन्टेंट मिटाना, आपके सर्वर को मैनेज करने का हिस्सा है. रिमोट कैश मेमोरी से कॉन्टेंट मिटाने का तरीका, कैश मेमोरी के तौर पर सेट अप किए गए सर्वर पर निर्भर करता है. आउटपुट मिटाते समय, पूरी कैश मेमोरी मिटाएं या पुराने आउटपुट मिटाएं.
कैश मेमोरी में सेव किए गए आउटपुट, नामों और हैश के सेट के तौर पर सेव किए जाते हैं. कॉन्टेंट मिटाते समय, यह पता नहीं लगाया जा सकता कि कौनसे आउटपुट, किसी खास बिल्ड से जुड़े हैं.
कैश मेमोरी से कॉन्टेंट मिटाने की वजहें:
- कैश मेमोरी में गड़बड़ी होने के बाद, नई कैश मेमोरी बनाना
- पुराने आउटपुट मिटाकर, इस्तेमाल किए गए स्टोरेज की मात्रा कम करना
Unix सॉकेट
रिमोट एचटीटीपी कैश मेमोरी, Unix डोमेन सॉकेट के ज़रिए कनेक्ट होने की सुविधा के साथ काम करती है. इसका व्यवहार, curl के --unix-socket फ़्लैग जैसा होता है. Unix डोमेन सॉकेट को कॉन्फ़िगर करने के लिए, इसका इस्तेमाल करें:
build --remote_cache=http://your.host:port
build --remote_cache_proxy=unix:/path/to/socketWindows पर यह सुविधा काम नहीं करती.
डिस्क की कैश मेमोरी
Bazel, फ़ाइल सिस्टम पर मौजूद किसी डायरेक्ट्री को रिमोट कैश मेमोरी के तौर पर इस्तेमाल कर सकता है. यह सुविधा, ब्रांच स्विच करते समय और/या एक ही प्रोजेक्ट के कई वर्कस्पेस पर काम करते समय, बिल्ड आर्टफ़ैक्ट शेयर करने के लिए काम की है. जैसे, कई चेकआउट. Bazel, डायरेक्ट्री से गार्बेज कलेक्शन नहीं करता. इसलिए, इस डायरेक्ट्री को समय-समय पर साफ़ करने की प्रोसेस को ऑटोमेट किया जा सकता है. डिस्क की कैश मेमोरी को इस तरह चालू करें:
build --disk_cache=path/to/build/cache--disk_cache फ़्लैग को, उपयोगकर्ता के हिसाब से पाथ पास करने के लिए, ~ एलियास का इस्तेमाल किया जा सकता है. Bazel, मौजूदा उपयोगकर्ता की होम डायरेक्ट्री को बदल देगा. यह सुविधा तब काम आती है, जब प्रोजेक्ट की चेक इन की गई .bazelrc फ़ाइल के ज़रिए, प्रोजेक्ट के सभी डेवलपर के लिए डिस्क की कैश मेमोरी चालू की जाती है.
ज्ञात समस्याएं
बिल्ड के दौरान, इनपुट फ़ाइल में बदलाव करना
बिल्ड के दौरान, इनपुट फ़ाइल में बदलाव करने पर, Bazel, रिमोट कैश मेमोरी में अमान्य नतीजे अपलोड कर सकता है. --experimental_guard_against_concurrent_changes फ़्लैग की मदद से, बदलाव का पता लगाने की सुविधा चालू की जा सकती है. फ़िलहाल, इससे जुड़ी कोई समस्या नहीं है. आने वाले वर्शन में, यह सुविधा डिफ़ॉल्ट रूप से चालू होगी.
अपडेट के लिए, [समस्या #3360] देखें. आम तौर पर, बिल्ड के दौरान सोर्स फ़ाइलों में बदलाव करने से बचें.
किसी ऐक्शन में एनवायरमेंट वैरिएबल लीक होना
किसी ऐक्शन की परिभाषा में एनवायरमेंट वैरिएबल शामिल होते हैं. अलग-अलग मशीनों पर, रिमोट कैश मेमोरी हिट शेयर करने में इससे समस्या हो सकती है. उदाहरण के लिए, अलग-अलग $PATH वैरिएबल वाले एनवायरमेंट, कैश मेमोरी हिट शेयर नहीं करेंगे. किसी ऐक्शन की परिभाषा में, सिर्फ़ वे एनवायरमेंट वैरिएबल शामिल होते हैं जिन्हें --action_env के ज़रिए साफ़ तौर पर अनुमति दी गई है. Bazel के Debian/Ubuntu पैकेज का इस्तेमाल करके, /etc/bazel.bazelrc इंस्टॉल किया जाता था. इसमें, $PATH सहित एनवायरमेंट वैरिएबल की अनुमति वाली सूची शामिल होती थी. अगर आपको उम्मीद से कम कैश मेमोरी हिट मिल रही हैं, तो देखें कि आपके एनवायरमेंट में /etc/bazel.bazelrc की पुरानी फ़ाइल तो नहीं है.
Bazel, वर्कस्पेस के बाहर मौजूद टूल को ट्रैक नहीं करता
फ़िलहाल, Bazel, वर्कस्पेस के बाहर मौजूद टूल को ट्रैक नहीं करता. इससे समस्या हो सकती है. उदाहरण के लिए, अगर कोई ऐक्शन, /usr/bin/ से कंपाइलर का इस्तेमाल करता है. इसके बाद, अलग-अलग कंपाइलर इंस्टॉल करने वाले दो उपयोगकर्ता, कैश मेमोरी हिट को गलत तरीके से शेयर करेंगे, क्योंकि आउटपुट अलग-अलग हैं, लेकिन उनके पास एक ही ऐक्शन हैश है. अपडेट के लिए,
समस्या #4558 देखें.
Docker कंटेनर में बिल्ड चलाने पर, इन-मेमोरी स्टेट का इंक्रीमेंटल डेटा मिट जाता है Bazel, सिंगल Docker कंटेनर में चलने पर भी सर्वर/क्लाइंट आर्किटेक्चर का इस्तेमाल करता है. सर्वर की ओर, Bazel, इन-मेमोरी स्टेट बनाए रखता है. इससे बिल्ड की प्रोसेस तेज़ होती है. सीआई में, Docker कंटेनर में बिल्ड चलाने पर, इन-मेमोरी स्टेट का डेटा मिट जाता है. इसलिए, Bazel को रिमोट कैश मेमोरी का इस्तेमाल करने से पहले, इसे फिर से बनाना पड़ता है.
बाहरी लिंक
Your Build in a Datacenter: Bazel की टीम ने FOSDEM 2018 में, रिमोट कैश मेमोरी और एक्ज़ीक्यूशन के बारे में बात की थी.
Faster Bazel builds with remote caching: a benchmark: Nicolò Valigi ने एक ब्लॉग पोस्ट लिखी है. इसमें उन्होंने Bazel में रिमोट कैश मेमोरी की परफ़ॉर्मेंस की तुलना की है.