रिमोट कैशिंग

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

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

खास जानकारी

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

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

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

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

रिमोट कैश, दो तरह का डेटा स्टोर करता है:

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

ध्यान रखें कि रिमोट कैश के साथ-साथ हर कार्रवाई के लिए स्टाउट और स्टेक्टर भी सेव किए जाते हैं. बज़ेल के sddout/sdderr की जांच करना, कैश हिट का अनुमान लगाने के लिए एक अच्छा सिग्नल नहीं है.

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

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

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

जब आप ऐसा Bezel बिल्ड चलाते हैं जो रिमोट कैश को पढ़ और लिख सकता है, तो बिल्ड इन चरणों का पालन करता है:

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

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

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

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

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

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

निंगक्स

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

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

बैजेल-रिमोट

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

यह कैश, डिस्क पर सामग्री स्टोर करता है. साथ ही, इससे ज़्यादा मेमोरी इस्तेमाल करने और इस्तेमाल नहीं किए गए आर्टफ़ैक्ट को हटाने के लिए कचरा हटाने की सुविधा मिलती है. कैश मेमोरी [डॉक्टर इमेज] के तौर पर उपलब्ध है और इसका कोड 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 से कनेक्ट करें:

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

प्रमाणीकरण

HTTP मूल प्रमाणीकरण के लिए 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... वाली कार्रवाई के लिए कार्रवाई के नतीजे का मेटाडेटा डाउनलोड करने का अनुरोध कुछ इस तरह दिखेगा:

GET /cache/ac/01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b HTTP/1.1
Host: localhost:8080
Accept: */*
Connection: Keep-Alive

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

PUT /cache/cas/15e2b0d3c33891ebb0f1ef609ec419420c20e320ce94c65fbc8c3312448eb225 HTTP/1.1
Host: localhost:8080
Accept: */*
Content-Length: 9
Connection: Keep-Alive

0x310x320x330x340x350x360x370x380x39

रिमोट कैश मेमोरी का इस्तेमाल करके Bazel चलाएं

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

आपको कॉन्फ़िगरेशन कॉन्फ़िगर करने की भी ज़रूरत हो सकती है, जो खास तौर पर आपके चुने गए सर्वर के लिए है.

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

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

रिमोट कैश से पढ़ें और उसमें लिखें

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

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

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

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

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

build --remote_upload_local_results=false

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

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

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

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

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

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

हो सकता है कि आप कैश मेमोरी से कॉन्टेंट को इन कामों के लिए मिटाना चाहें:

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

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

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

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

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

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

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

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

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

ऐसी समस्याएं जिनकी पहले से जानकारी है

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

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

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

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

बैजल, फ़ाइल फ़ोल्डर के बाहर के टूल ट्रैक नहीं करता

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

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