इस पेज पर, रिमोट कैश मेमोरी की सुविधा, कैश मेमोरी को होस्ट करने के लिए सर्वर सेट अप करने, और रिमोट कैश मेमोरी का इस्तेमाल करके बिल्ड चलाने के बारे में जानकारी दी गई है.
रिमोट कैश मेमोरी का इस्तेमाल, डेवलपर की टीम और/या कंटीन्यूअस इंटिग्रेशन (सीआई) सिस्टम, बिल्ड के आउटपुट शेयर करने के लिए करते हैं. अगर आपका बिल्ड, फिर से बनाया जा सकता है, तो एक मशीन से मिले आउटपुट को दूसरी मशीन पर सुरक्षित तरीके से फिर से इस्तेमाल किया जा सकता है. इससे बिल्ड की प्रोसेस काफ़ी तेज़ हो सकती है.
खास जानकारी
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 मॉड्यूल] की मदद से, इसे 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 इमेज] के तौर पर उपलब्ध है. इसका कोड 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"],
)
रिमोट कैश मेमोरी से कॉन्टेंट मिटाना
रिमोट कैश मेमोरी से कॉन्टेंट मिटाना, आपके सर्वर को मैनेज करने का हिस्सा है. रिमोट कैश मेमोरी से कॉन्टेंट मिटाने का तरीका, कैश मेमोरी के तौर पर सेट अप किए गए सर्वर पर निर्भर करता है. आउटपुट मिटाते समय, पूरी कैश मेमोरी मिटाएं या पुराने आउटपुट मिटाएं.
कैश मेमोरी में सेव किए गए आउटपुट, नामों और हैश के सेट के तौर पर सेव होते हैं. कॉन्टेंट मिटाते समय, यह पता लगाने का कोई तरीका नहीं है कि कौनसा आउटपुट, किसी खास बिल्ड से जुड़ा है.
कैश मेमोरी से कॉन्टेंट मिटाने की ये वजहें हो सकती हैं:
- कैश मेमोरी में गड़बड़ी होने के बाद, साफ़ कैश मेमोरी बनाना
- पुराने आउटपुट मिटाकर, स्टोरेज का इस्तेमाल कम करना
यूनिक्स सॉकेट
रिमोट एचटीटीपी कैश मेमोरी, यूनिक्स डोमेन सॉकेट के ज़रिए कनेक्ट होने की सुविधा के साथ काम करती है. इसका व्यवहार, curl के --unix-socket फ़्लैग जैसा होता है. यूनिक्स डोमेन सॉकेट को कॉन्फ़िगर करने के लिए, इसका इस्तेमाल करें:
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 में रिमोट कैश मेमोरी की परफ़ॉर्मेंस की तुलना की है.