रिमोट कैशिंग

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

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

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

खास जानकारी

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

nginx

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

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;
}

बाज़ल-रिमोट

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

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

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

Google Cloud Storage

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

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

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

  2. Cloud Storage की पुष्टि करने के लिए, Bazel के लिए सेवा खाता बनाएं. सेवा खाता बनाना देखें.

  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 सर्वर को सेट अप किया जा सकता है जो कैश के बैकएंड के तौर पर PUT और GET के साथ काम करता हो. उपयोगकर्ताओं ने Hazelcast, Apache httpd, और AWS S3 जैसे कैशिंग बैकएंड का इस्तेमाल करके सफलता की रिपोर्ट की है.

पुष्टि करना

वर्शन 0.11.0 तक, Bazel में एचटीटीपी की बुनियादी पुष्टि करने की सुविधा जोड़ दी गई थी. रिमोट कैश यूआरएल की मदद से, 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

CAS पर 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:port

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

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

build --remote_upload_local_results=false

चुनिंदा टारगेट को रिमोट कैश का इस्तेमाल करने से रोकें

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

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

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

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

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

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

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

Unix सॉकेट

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

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

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

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

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 पैकेज, $PATH सहित एनवायरमेंट वैरिएबल की व्हाइटलिस्ट के साथ /etc/bazel.bazelrc को इंस्टॉल करने के लिए इस्तेमाल किया जाता है. अगर आपको उम्मीद से कम कैश हिट मिल रहे हैं, तो जांच लें कि आपके एनवायरमेंट में कोई पुरानी /etc/bazel.bazelrc फ़ाइल तो न हो.

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

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

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