रिमोट कैशिंग

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

इस पेज में रिमोट कैशिंग, कैश मेमोरी को होस्ट करने के लिए सर्वर सेट अप करने, और रिमोट कैश का इस्तेमाल करके बिल्ड चलाने के बारे में बताया गया है.

रिमोट कैश का इस्तेमाल, डेवलपर की टीम और/या लगातार इंटिग्रेशन (सीआई) सिस्टम, बिल्ड आउटपुट शेयर करने के लिए करता है. अगर आपका बिल्ड फिर से बनाया जा सकता है, तो एक मशीन के आउटपुट का इस्तेमाल, दूसरी मशीन पर सुरक्षित तरीके से किया जा सकता है. इससे बिल्ड की प्रोसेस काफ़ी तेज़ हो सकती है.

खास जानकारी

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

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

रिमोट कैश मेमोरी का इस्तेमाल करने के लिए:

  • कैश मेमोरी के बैकएंड के तौर पर सर्वर सेट अप करना
  • रिमोट कैश मेमोरी का इस्तेमाल करने के लिए, Bazel बिल्ड को कॉन्फ़िगर करना
  • Bazel का 0.10.0 या इसके बाद का वर्शन इस्तेमाल करना

रिमोट कैश मेमोरी में दो तरह का डेटा सेव होता है:

  • ऐक्शन कैश मेमोरी, जो ऐक्शन के नतीजे के मेटाडेटा के लिए ऐक्शन हैश का एक मैप है.
  • आउटपुट फ़ाइलों का कॉन्टेंट-एड्रेसेबल स्टोर (सीएएस).

ध्यान दें कि रिमोट कैश मेमोरी, हर कार्रवाई के लिए stdout और stderr को अलग से सेव करती है. इसलिए, Bazel के स्टैंडआउट/स्टैंडर्ड गड़बड़ी की जानकारी वाले आउटपुट की जांच करना, कैश मेमोरी में हिट का अनुमान लगाने के लिए अच्छा सिग्नल नहीं है.

कोई बिल्ड, रिमोट कैश मेमोरी का इस्तेमाल कैसे करता है

किसी सर्वर को रिमोट कैश मेमोरी के तौर पर सेट अप करने के बाद, कैश मेमोरी का इस्तेमाल कई तरीकों से किया जा सकता है:

  • रिमोट कैश मेमोरी को पढ़ना और उसमें डेटा सेव करना
  • चुनिंदा टारगेट को छोड़कर, रिमोट कैश मेमोरी में डेटा सेव करने की अनुमति दें और/या उसमें बदलाव करें
  • सिर्फ़ रिमोट कैश मेमोरी से पढ़ना
  • रिमोट कैश मेमोरी का इस्तेमाल बिलकुल न करना

अगर आपके पास ऐसा बैजल बिल्ड है जो रिमोट कैश मेमोरी में सेव डेटा को पढ़ सकता है और उसमें बदलाव कर सकता है, तो बिल्ड इस तरीके का पालन करता है:

  1. Bazel, उन टारगेट का ग्राफ़ बनाता है जिन्हें बिल्ड करना है. इसके बाद, ज़रूरी कार्रवाइयों की सूची बनाता है. इनमें से हर कार्रवाई के लिए, इनपुट और आउटपुट फ़ाइल के नाम तय किए गए हैं.
  2. Baज़ल, मौजूदा बिल्ड आउटपुट के लिए आपकी लोकल मशीन की जांच करता है और मिलने वाली किसी भी मशीन को दोबारा इस्तेमाल करता है.
  3. Bazel, मौजूदा बिल्ड आउटपुट के लिए कैश मेमोरी की जांच करता है. आउटपुट मिलने पर, Baze आउटपुट को वापस हासिल करता है. यह कैश मेमोरी का हिट है.
  4. ज़रूरी कार्रवाइयों के लिए, जिनका आउटपुट नहीं मिला था उनके लिए Bazel, कार्रवाइयों को स्थानीय तौर पर लागू करता है और ज़रूरी बिल्ड आउटपुट बनाता है.
  5. नए बिल्ड आउटपुट, रिमोट कैश मेमोरी में अपलोड किए जाते हैं.

कैश मेमोरी के बैकएंड के तौर पर सर्वर सेट अप करना

आपको एक सर्वर सेट अप करना होगा, ताकि वह कैश मेमोरी के बैकएंड के तौर पर काम कर सके. एक एचटीटीपी/1.1 सर्वर, बैजल के डेटा को ओपेक बाइट के तौर पर इस्तेमाल कर सकता है. साथ ही, कई मौजूदा सर्वर का इस्तेमाल रिमोट कैश मेमोरी बैकएंड के तौर पर किया जा सकता है. Bazel का एचटीटीपी कैश मेमोरी प्रोटोकॉल, रिमोट कैश मेमोरी के साथ काम करता है.

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

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

रिमोट कैश मेमोरी के लिए, कई बैकएंड का इस्तेमाल किया जा सकता है. कुछ विकल्पों में ये शामिल हैं:

nginx

nginx एक ओपन सोर्स वेब सर्वर है. इसके [WebDAV मॉड्यूल] की मदद से, इसका इस्तेमाल Bazel के लिए रिमोट कैश के तौर पर किया जा सकता है. Debian और Ubuntu पर आप nginx-extras पैकेज इंस्टॉल कर सकते हैं. macOS पर, Homebrew की मदद से nginx इंस्टॉल किया जा सकता है:

brew tap denji/nginx
brew 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;
}

बेज़ल-रिमोट

baaz-remote एक ओपन सोर्स रिमोट बिल्ड कैश है जिसका इस्तेमाल आप अपने इंफ़्रास्ट्रक्चर पर कर सकते हैं. साल 2018 की शुरुआत से, कई कंपनियों ने इसे प्रोडक्शन में इस्तेमाल किया है. ध्यान दें कि Bazel प्रोजेक्ट, bazel-remote के लिए तकनीकी सहायता नहीं देता.

यह कैश मेमोरी, डिस्क पर कॉन्टेंट सेव करती है. साथ ही, स्टोरेज की तय सीमा लागू करने और इस्तेमाल न किए गए आर्टफ़ैक्ट को हटाने के लिए, गै़रबज कलेक्शन की सुविधा भी देती है. कैश मेमोरी [docker image] के तौर पर उपलब्ध है और इसका कोड GitHub पर उपलब्ध है. REST और gRPC, दोनों रिमोट कैश एपीआई काम करते हैं.

इसका इस्तेमाल करने का तरीका जानने के लिए, GitHub पेज पर जाएं.

Google Cloud Storage

[Google Cloud Storage], पूरी तरह से मैनेज किया जाने वाला ऑब्जेक्ट स्टोर है. यह एक ऐसा एचटीटीपी एपीआई उपलब्ध कराता है जो Bazel के रिमोट कैश मेमोरी प्रोटोकॉल के साथ काम करता है. इसके लिए, आपके पास बिलिंग की सुविधा वाला Google Cloud खाता होना चाहिए.

Cloud Storage को कैश मेमोरी के तौर पर इस्तेमाल करने के लिए:

  1. स्टोरेज बकेट बनाएं. पक्का करें कि आपने अपनी जगह के सबसे नज़दीक की बकेट लोकेशन चुनी हो, क्योंकि रिमोट कैश मेमोरी के लिए नेटवर्क बैंडविड्थ ज़रूरी है.

  2. Cloud Storage के लिए पुष्टि करने के लिए, Baज़र के लिए सेवा खाता बनाएं. सेवा खाता बनाना लेख पढ़ें.

  3. एक सीक्रेट JSON कुंजी जनरेट करें और फिर पुष्टि के लिए, उसे Bazel को पास करें. कुंजी को सुरक्षित तरीके से सेव करें, क्योंकि जिस व्यक्ति के पास कुंजी है वह आपके GCS (जीसीएस) बकेट से आर्बिट्रेरी डेटा पढ़ और लिख सकता है.

  4. अपने Bazel कमांड में ये फ़्लैग जोड़कर, Cloud Storage से कनेक्ट करें:

    • फ़्लैग का इस्तेमाल करके, Bazel को यह यूआरएल दें: --remote_cache=https://storage.googleapis.com/bucket-name जहां bucket-name आपके स्टोरेज बकेट का नाम है.
    • ऐप्लिकेशन की पुष्टि करने की सुविधा का इस्तेमाल करने के लिए, फ़्लैग: --google_credentials=/path/to/your/secret-key.json या --google_default_credentials का इस्तेमाल करके पुष्टि करने की कुंजी पास करें.
  5. Cloud Storage को कॉन्फ़िगर करके, पुरानी फ़ाइलों को अपने-आप मिटाया जा सकता है. ऐसा करने के लिए, ऑब्जेक्ट लाइफ़साइकल मैनेज करना लेख पढ़ें.

अन्य सर्वर

कैश मेमोरी के बैकएंड के तौर पर, किसी भी ऐसे एचटीटीपी/1.1 सर्वर को सेट अप किया जा सकता है जो पुट और GET का इस्तेमाल करता हो. उपयोगकर्ताओं ने Hazelcast, Apache httpd, और AWS S3 जैसे कैश मेमोरी वाले बैकएंड के साथ काम करने की जानकारी दी है.

पुष्टि करना

Bazel के 0.11.0 वर्शन में, एचटीटीपी बुनियादी पुष्टि करने की सुविधा जोड़ी गई थी. रिमोट कैश मेमोरी के यूआरएल की मदद से, Bazel को उपयोगकर्ता नाम और पासवर्ड दिया जा सकता है. इसका सिंटैक्स https://username:password@hostname.com:port/path है. ध्यान दें कि एचटीटीपी बुनियादी पुष्टि की सुविधा, नेटवर्क पर उपयोगकर्ता नाम और पासवर्ड को साफ़ टेक्स्ट में भेजती है. इसलिए, इसका इस्तेमाल हमेशा एचटीटीपीएस के साथ करना ज़रूरी है.

एचटीटीपी कैश मेमोरी प्रोटोकॉल

Bazel, एचटीटीपी/1.1 के ज़रिए रिमोट कैश मेमोरी का इस्तेमाल करता है. प्रोटोकॉल सैद्धांतिक रूप से आसान है: बाइनरी डेटा (BLOB) को 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 चलाना

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

आपको पुष्टि करने की सुविधा को भी कॉन्फ़िगर करना पड़ सकता है. यह सुविधा, आपके चुने गए सर्वर के हिसाब से होती है.

आपके पास इन फ़्लैग को .bazelrc फ़ाइल में जोड़ने का विकल्प है, ताकि आपको हर बार Bazel चलाते समय उन्हें बताने की ज़रूरत न पड़े. अपने प्रोजेक्ट और टीम की डाइनैमिक के हिसाब से, .bazelrc फ़ाइल में फ़्लैग जोड़े जा सकते हैं:

  • आपकी लोकल मशीन पर
  • आपके प्रोजेक्ट के फ़ाइल फ़ोल्डर में, टीम के साथ शेयर किया गया
  • सीआई सिस्टम पर

रिमोट कैश मेमोरी से डेटा पढ़ें और उसमें बदलाव करें

ध्यान रखें कि रिमोट कैश मेमोरी में कौन लिख सकता है. हो सकता है कि आप सिर्फ़ अपने सीआई सिस्टम को रिमोट कैश मेमोरी में डेटा लिखने की अनुमति देना चाहें.

रिमोट कैश मेमोरी से पढ़ने और उसमें लिखने के लिए, इस फ़्लैग का इस्तेमाल करें:

build --remote_cache=http://your.host:port

HTTP के अलावा, ये प्रोटोकॉल भी काम करते हैं: HTTPS, grpc, grpcs.

सिर्फ़ रिमोट कैश मेमोरी से पढ़ने के लिए, ऊपर दिए गए फ़्लैग के साथ इस फ़्लैग का इस्तेमाल करें:

build --remote_upload_local_results=false

रिमोट कैश मेमोरी का इस्तेमाल करने से कुछ टारगेट को बाहर रखना

किसी खास टारगेट को रिमोट कैश मेमोरी का इस्तेमाल करने से रोकने के लिए, टारगेट को no-remote-cache से टैग करें. उदाहरण के लिए:

java_library(
    name = "target",
    tags = ["no-remote-cache"],
)

रिमोट कैश मेमोरी से कॉन्टेंट मिटाएं

रिमोट कैश से कॉन्टेंट मिटाना आपके सर्वर को मैनेज करने का हिस्सा है. रिमोट कैश मेमोरी से कॉन्टेंट मिटाने का तरीका, इस बात पर निर्भर करता है कि आपने कैश मेमोरी के तौर पर किस सर्वर को सेट अप किया है. आउटपुट मिटाते समय, पूरी कैश मेमोरी मिटाएं या पुराने आउटपुट मिटाएं.

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

कैश मेमोरी से कॉन्टेंट मिटाने की ये वजहें हो सकती हैं:

  • कैश मेमोरी में गलत डेटा डालने के बाद, कैश मेमोरी को खाली करना
  • पुराने आउटपुट मिटाकर, इस्तेमाल किया जा रहा स्टोरेज कम करें

यूनिक्स सॉकेट

रिमोट एचटीटीपी कैश, यूनिक्स डोमेन सॉकेट से कनेक्ट करने की सुविधा देता है. इसकी सुविधा, curl के --unix-socket फ़्लैग से मिलती-जुलती है. यूनिक्स डोमेन सॉकेट को कॉन्फ़िगर करने के लिए, इनका इस्तेमाल करें:

   build --remote_cache=http://your.host:port
   build --remote_proxy=unix:/path/to/socket

यह सुविधा Windows पर काम नहीं करती.

डिस्क कैश मेमोरी

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

build --disk_cache=path/to/build/cache

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

कचरा इकट्ठा करना

Bazel 7.4 से, --experimental_disk_cache_gc_max_size और --experimental_disk_cache_gc_max_age का इस्तेमाल करके, डिस्क कैश के लिए ज़्यादा से ज़्यादा साइज़ या अलग-अलग कैश एंट्री की उम्र सेट की जा सकती है. Bazel, डिस्क कैश को अपने-आप इकट्ठा करेगा. ऐसा तब होगा, जब एक बिल्ड के खत्म होने के बाद, अगला बिल्ड शुरू न हुआ हो. --experimental_disk_cache_gc_idle_delay का इस्तेमाल करके, इंतज़ार के समय को सेट किया जा सकता है. डिफ़ॉल्ट रूप से, यह समय पांच मिनट का होता है.

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

पहले से मालूम समस्याएं

बिल्ड के दौरान इनपुट फ़ाइल में बदलाव करना

बिल्ड के दौरान किसी इनपुट फ़ाइल में बदलाव किए जाने पर, Basel रिमोट कैश मेमोरी में अमान्य नतीजे अपलोड कर सकता है. --experimental_guard_against_concurrent_changes फ़्लैग की मदद से, बदलाव का पता लगाने की सुविधा चालू की जा सकती है. इस सुविधा से जुड़ी कोई समस्या नहीं है. आने वाले समय में रिलीज़ होने वाले नए वर्शन में, यह सुविधा डिफ़ॉल्ट रूप से चालू रहेगी. अपडेट के लिए [समस्या #3360] देखें. आम तौर पर, बाइल्ड के दौरान सोर्स फ़ाइलों में बदलाव करने से बचें.

एनवायरमेंट वैरिएबल किसी कार्रवाई में लीक हो रहे हैं

ऐक्शन की परिभाषा में एनवायरमेंट वैरिएबल शामिल होते हैं. इससे, अलग-अलग मशीनों पर रिमोट कैश मेमोरी हिट शेयर करने में समस्या आ सकती है. उदाहरण के लिए, अलग-अलग $PATH वैरिएबल वाले एनवायरमेंट, कैश मेमोरी हिट शेयर नहीं करेंगे. सिर्फ़ वे एनवायरमेंट वैरिएबल, ऐक्शन की परिभाषा में शामिल किए जाते हैं जिन्हें --action_env के ज़रिए साफ़ तौर पर व्हाइटलिस्ट किया गया हो. Bazel का Debian/Ubuntu पैकेज, /etc/bazel.bazelrc को $PATH जैसे एनवायरमेंट वैरिएबल की व्हाइटलिस्ट के साथ इंस्टॉल करने के लिए इस्तेमाल किया जाता है. अगर आपको उम्मीद से कम कैश मेमोरी हिट मिल रहे हैं, तो देखें कि आपके एनवायरमेंट में कोई पुरानी /etc/bazel.bazelrc फ़ाइल तो नहीं है.

Bazzल, वर्कस्पेस के बाहर टूल को ट्रैक नहीं करता है

फ़िलहाल, Bazel किसी वर्कस्पेस के बाहर के टूल को ट्रैक नहीं करता. उदाहरण के लिए, अगर कोई कार्रवाई /usr/bin/ के कंपाइलर का इस्तेमाल करती है, तो उस कार्रवाई से समस्या हो सकती है. इसके बाद, अलग-अलग कंपाइलर इंस्टॉल किए हुए दो उपयोगकर्ता, कैश मेमोरी में हिट को गलत तरीके से शेयर करेंगे. ऐसा इसलिए होगा, क्योंकि उनके आउटपुट अलग-अलग होंगे, लेकिन उनके पास एक ही ऐक्शन हैश होगा. अपडेट के लिए, समस्या #4558 देखें.

डॉकर कंटेनर में बिल्ड चलाने पर, इन-मेमोरी में क्रमिक तौर पर होने वाले बदलावों की स्थिति मिट जाती है Bazel, सिंगल डॉकर कंटेनर में चलने पर भी सर्वर/क्लाइंट आर्किटेक्चर का इस्तेमाल करता है. सर्वर की तरफ़, Basel की मेमोरी में स्थिति बनी रहती है. इससे बिल्ड की स्पीड बढ़ती है. सीआई जैसे डकर कंटेनर में बिल्ड चलाने पर, मेमोरी में सेव की गई स्थिति मिट जाती है और रिमोट कैश मेमोरी का इस्तेमाल करने से पहले, Bazel को उसे फिर से बनाना पड़ता है.