หน้านี้จะครอบคลุมการแคชระยะไกล การตั้งค่าเซิร์ฟเวอร์เพื่อโฮสต์แคช และ กำลังใช้บิลด์โดยใช้แคชระยะไกล
ทีมนักพัฒนาแอปใช้แคชระยะไกลและ/หรือการผสานรวมอย่างต่อเนื่อง (CI) สำหรับแชร์เอาต์พุตของบิลด์ หากบิลด์ของคุณทำซ้ำได้ เอาต์พุตจากเครื่องหนึ่งสามารถนำมาใช้ซ้ำอย่างปลอดภัยกับอีกเครื่องหนึ่งได้ ซึ่ง ทำให้งานสร้างเร็วขึ้นมาก
ภาพรวม
Bazel แบ่งโครงสร้างออกเป็นขั้นตอนต่างๆ ที่แยกจากกัน ซึ่งเรียกว่าการกระทำ การดำเนินการแต่ละรายการ มีอินพุต ชื่อเอาต์พุต บรรทัดคำสั่ง และตัวแปรสภาพแวดล้อม จำเป็น ระบบจะประกาศอินพุตและเอาต์พุตที่คาดไว้อย่างชัดเจนสำหรับการดำเนินการแต่ละรายการ
คุณตั้งค่าเซิร์ฟเวอร์เป็นแคชระยะไกลสำหรับเอาต์พุตของบิลด์ได้ ซึ่งมีดังต่อไปนี้ เอาต์พุตจากการทำงาน เอาต์พุตเหล่านี้จะประกอบด้วยรายการชื่อไฟล์เอาต์พุตและ แฮชเนื้อหา เมื่อใช้แคชระยะไกล คุณจะใช้เอาต์พุตของบิลด์ซ้ำได้ จากบิลด์ของผู้ใช้อีกราย แทนการสร้างเอาต์พุตใหม่แต่ละรายการในเครื่อง
วิธีใช้การแคชระยะไกล
- ตั้งค่าเซิร์ฟเวอร์เป็นแบ็กเอนด์ของแคช
- กำหนดค่าบิลด์ Bazel เพื่อใช้แคชระยะไกล
- ใช้ Bazel เวอร์ชัน 0.10.0 ขึ้นไป
แคชระยะไกลจะจัดเก็บข้อมูล 2 ประเภทดังนี้
- แคชการดำเนินการ ซึ่งเป็นการแมปแฮชการดำเนินการกับข้อมูลเมตาของผลลัพธ์การดำเนินการ
- พื้นที่เก็บข้อมูลที่ระบุเนื้อหา (CAS) ของไฟล์เอาต์พุต
โปรดทราบว่าแคชระยะไกลจะจัดเก็บ stdout และ stderr เพิ่มเติมสำหรับทุกๆ การดำเนินการ การตรวจสอบ stdout/stderr ของ Bazel ดังนั้นจึงไม่ใช่สัญญาณที่ดีสำหรับ การประมาณการพบแคช
วิธีที่บิลด์ใช้การแคชระยะไกล
เมื่อตั้งค่าเซิร์ฟเวอร์เป็นแคชระยะไกลแล้ว คุณจะใช้แคชในหลาย ด้วยวิธีต่อไปนี้
- อ่านและเขียนไปยังแคชระยะไกล
- อ่านและ/หรือเขียนไปยังแคชระยะไกล ยกเว้นเป้าหมายเฉพาะ
- อ่านจากแคชระยะไกลเท่านั้น
- ไม่ใช้แคชระยะไกลเลย
เมื่อคุณเรียกใช้บิลด์ Bazel ที่อ่านและเขียนไปยังแคชระยะไกลได้ บิลด์ดังกล่าวจะทำตามขั้นตอนต่อไปนี้
- Bazel สร้างกราฟของเป้าหมายที่ต้องสร้างขึ้น แล้วสร้าง รายการการดำเนินการที่จำเป็น การดำเนินการแต่ละรายการเหล่านี้ได้ประกาศอินพุตแล้ว และชื่อไฟล์เอาต์พุต
- Bazel ตรวจสอบเครื่องของคุณเองเพื่อหาเอาต์พุตของบิลด์ที่มีอยู่และนำไปใช้งานซ้ำ ที่พบ
- Bazel ตรวจสอบแคชสำหรับเอาต์พุตของบิลด์ที่มีอยู่ หากพบผลลัพธ์ที่ต้องการ Bazel เรียกเอาต์พุต นี่เป็นการพบแคช
- สำหรับการทำงานที่จำเป็นซึ่งไม่พบเอาต์พุต Bazel จะเรียกใช้ ภายในเครื่องและสร้างเอาต์พุตของบิลด์ที่จำเป็น
- อัปโหลดเอาต์พุตของบิลด์ใหม่ไปยังแคชระยะไกลแล้ว
การตั้งค่าเซิร์ฟเวอร์เป็นแบ็กเอนด์ของแคช
คุณต้องตั้งค่าเซิร์ฟเวอร์ให้ทำหน้าที่เป็นแบ็กเอนด์ของแคช HTTP/1.1 เซิร์ฟเวอร์สามารถจัดการข้อมูลของ Bazel ในแบบไบต์ทึบ และเซิร์ฟเวอร์ที่มีอยู่จำนวนมาก สามารถใช้เป็นแบ็กเอนด์การแคชระยะไกล บาเซล โปรโตคอลการแคช HTTP คือสิ่งที่รองรับจากระยะไกล การแคช
คุณมีหน้าที่รับผิดชอบในการเลือก ตั้งค่า และดูแลรักษาแบ็กเอนด์ เซิร์ฟเวอร์ที่จะจัดเก็บเอาต์พุตที่แคชไว้ เมื่อเลือกเซิร์ฟเวอร์ ให้พิจารณาถึงสิ่งต่อไปนี้
- ความเร็วของเครือข่าย ตัวอย่างเช่น ถ้าทีมของคุณอยู่ในสำนักงานเดียวกัน คุณอาจ ต้องการใช้งานเซิร์ฟเวอร์ภายในของคุณเอง
- ความปลอดภัย แคชระยะไกลจะมีไบนารีของคุณ ดังนั้นจึงต้องมีความปลอดภัย
- การจัดการที่ง่ายดาย เช่น Google Cloud Storage เป็นบริการที่มีการจัดการครบวงจร
มีแบ็กเอนด์มากมายที่สามารถใช้สำหรับแคชระยะไกล ตัวเลือกบางรายการ รวมข้อมูลต่อไปนี้
nginx
nginx เป็นเว็บเซิร์ฟเวอร์แบบโอเพนซอร์ส ด้วย[โมดูล WebDAV] ทำให้คุณสามารถ
ใช้เป็นแคชระยะไกลสำหรับ Bazel ใน Debian และ Ubuntu คุณสามารถติดตั้ง
แพ็กเกจ nginx-extras
ใน macOS nginx พร้อมให้ใช้งานผ่าน Homeภาษาของ
brew tap denji/nginx
brew install nginx-full --with-webdav
ด้านล่างคือตัวอย่างการกำหนดค่าสำหรับ nginx โปรดทราบว่าคุณจะต้อง
เปลี่ยน /path/to/cache/dir
เป็นไดเรกทอรีที่ถูกต้องที่ nginx มีสิทธิ์
เพื่อเขียนและอ่านได้ คุณอาจต้องเปลี่ยนตัวเลือก client_max_body_size
เป็น
จะมีค่ามากขึ้นหากคุณมีไฟล์เอาต์พุตขนาดใหญ่ เซิร์ฟเวอร์จะกำหนดให้มี
การกำหนดค่า เช่น การตรวจสอบสิทธิ์
ตัวอย่างการกำหนดค่าสำหรับส่วน server
ใน nginx.conf
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
bazel-remote เป็นแคชบิลด์ระยะไกลแบบโอเพนซอร์สที่คุณใช้ได้ใน โครงสร้างพื้นฐานของคุณ มีการนำโซลูชันไปใช้ในเวอร์ชันที่ใช้งานจริงเรียบร้อยแล้วเมื่อ บริษัทหลายแห่งตั้งแต่ต้นปี 2018 โปรดทราบว่าโปรเจ็กต์ Bazel ไม่ได้ให้การสนับสนุนด้านเทคนิคสําหรับ bazel-remote
แคชนี้จัดเก็บเนื้อหาในดิสก์และยังมีการเก็บข้อมูลขยะด้วย เพื่อบังคับใช้ขีดจำกัดพื้นที่เก็บข้อมูลสูงสุดและล้างอาร์ติแฟกต์ที่ไม่ได้ใช้ แคชจะ มีให้บริการเป็น [รูปภาพ Docker] และโค้ดของรูปภาพมีอยู่ใน GitHub รองรับทั้ง API แคชระยะไกลของ REST และ gRPC
โปรดดูที่ GitHub เพื่อดูวิธีการใช้งาน
Google Cloud Storage
[Google Cloud Storage] เป็นที่จัดเก็บออบเจ็กต์ที่มีการจัดการครบวงจรซึ่งมอบ HTTP API ที่เข้ากันได้กับโปรโตคอลการแคชระยะไกลของ Bazel ต้องการ คุณมีบัญชี Google Cloud ที่เปิดใช้การเรียกเก็บเงิน
วิธีใช้ Cloud Storage เป็นแคช
สร้างที่เก็บข้อมูลของพื้นที่เก็บข้อมูล ตรวจสอบว่าคุณเลือกตำแหน่งที่เก็บข้อมูลที่อยู่ใกล้กับคุณที่สุด เช่น แบนด์วิดท์ของเครือข่าย เป็นสิ่งสำคัญสำหรับแคชระยะไกล
สร้างบัญชีบริการสำหรับ Bazel เพื่อตรวจสอบสิทธิ์กับ Cloud Storage โปรดดู การสร้างบัญชีบริการ
สร้างคีย์ JSON ลับแล้วส่งไปให้ Bazel ตรวจสอบสิทธิ์ ร้านค้า คีย์ได้อย่างปลอดภัย เนื่องจากทุกคนที่มีคีย์จะอ่านและเขียนข้อมูลที่กำหนดเองได้ to/จากที่เก็บข้อมูล GCS
เชื่อมต่อกับ Cloud Storage โดยเพิ่มแฟล็กต่อไปนี้ในคำสั่ง Bazel
- ส่งต่อ URL ต่อไปนี้ไปยัง Bazel โดยใช้แฟล็ก
--remote_cache=https://storage.googleapis.com/bucket-name
โดยที่bucket-name
คือชื่อของที่เก็บข้อมูลของพื้นที่เก็บข้อมูล - ส่งคีย์การตรวจสอบสิทธิ์โดยใช้แฟล็ก:
--google_credentials=/path/to/your/secret-key.json
หรือ--google_default_credentials
เพื่อใช้ Application Authentication
- ส่งต่อ URL ต่อไปนี้ไปยัง Bazel โดยใช้แฟล็ก
คุณกำหนดค่า Cloud Storage ให้ลบไฟล์เก่าโดยอัตโนมัติได้ โดยดูที่ การจัดการวงจรของออบเจ็กต์
เซิร์ฟเวอร์อื่นๆ
คุณสามารถตั้งค่าเซิร์ฟเวอร์ HTTP/1.1 ที่สนับสนุน PUT และ GET เป็น แบ็กเอนด์ ผู้ใช้ได้รายงานว่าประสบความสำเร็จกับแบ็กเอนด์การแคช เช่น Hazelcast Apache httpd และ AWS S3
การตรวจสอบสิทธิ์
ตั้งแต่เวอร์ชัน 0.11.0 ได้มีการเพิ่มการสนับสนุนการตรวจสอบสิทธิ์พื้นฐานของ HTTP ไปยัง Bazel
คุณส่งชื่อผู้ใช้และรหัสผ่านไปยัง Bazel ผ่าน URL ของแคชระยะไกลได้
ไวยากรณ์คือ https://username:password@hostname.com:port/path
โปรดทราบว่า
การตรวจสอบสิทธิ์พื้นฐานของ HTTP จะส่งชื่อผู้ใช้และรหัสผ่านในรูปแบบข้อความธรรมดาผ่าน
เครือข่าย และ ดังนั้นจึงจำเป็นที่จะต้องใช้กับ HTTPS ทุกครั้ง
โปรโตคอลการแคช HTTP
Bazel รองรับการแคชระยะไกลผ่าน HTTP/1.1 โปรโตคอลมีหลักการที่เรียบง่าย ดังนี้
ข้อมูลไบนารี (BLOB) มีการอัปโหลดผ่านคำขอ PUT และดาวน์โหลดผ่านคำขอ GET
ข้อมูลเมตาของผลการดำเนินการจัดเก็บอยู่ในเส้นทาง /ac/
และจัดเก็บไฟล์เอาต์พุตไว้
ใต้เส้นทาง /cas/
ตัวอย่างเช่น ลองพิจารณาแคชระยะไกลที่ทำงานภายใต้ http://localhost:8080/cache
คำขอ Bazel เพื่อดาวน์โหลดข้อมูลเมตาของผลการดำเนินการสำหรับการดำเนินการที่มี SHA256
แฮช 01ba4719...
จะมีลักษณะดังนี้
GET /cache/ac/01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b HTTP/1.1
Host: localhost:8080
Accept: */*
Connection: Keep-Alive
คำขอ Bazel เพื่ออัปโหลดไฟล์เอาต์พุตที่มีแฮช SHA256 15e2b0d3...
ไปยัง
CAS จะมีลักษณะดังนี้
PUT /cache/cas/15e2b0d3c33891ebb0f1ef609ec419420c20e320ce94c65fbc8c3312448eb225 HTTP/1.1
Host: localhost:8080
Accept: */*
Content-Length: 9
Connection: Keep-Alive
0x310x320x330x340x350x360x370x380x39
เรียกใช้ Bazel โดยใช้แคชระยะไกล
เมื่อตั้งค่าเซิร์ฟเวอร์เป็นแคชระยะไกล เพื่อใช้แคชระยะไกล ต้องเพิ่มแฟล็กในคำสั่ง Bazel ของคุณ ดูรายการการกำหนดค่าและ ธงของตนที่ด้านล่าง
นอกจากนี้ คุณอาจต้องกำหนดค่าการตรวจสอบสิทธิ์ ซึ่งเป็นข้อมูลเฉพาะ เซิร์ฟเวอร์ที่เลือก
คุณอาจต้องการเพิ่ม Flag เหล่านี้ในไฟล์ .bazelrc
เพื่อไม่ให้
คุณต้องระบุไว้ทุกครั้งที่คุณเรียกใช้ Bazel ทั้งนี้ขึ้นอยู่กับโปรเจ็กต์และ
ของทีมแบบไดนามิก คุณจะสามารถเพิ่ม Flag ในไฟล์ .bazelrc
ที่มีลักษณะดังนี้
- ในเครื่องของคุณ
- แชร์กับทีมในพื้นที่ทำงานของโปรเจ็กต์
- ในระบบ CI
อ่านและเขียนไปยังแคชระยะไกล
ตรวจสอบว่าใครเขียนลงในแคชระยะไกลได้บ้าง คุณอาจต้องการ เฉพาะระบบ CI ของคุณเท่านั้นที่สามารถเขียนไปยังแคชระยะไกลได้
ใช้แฟล็กต่อไปนี้เพื่ออ่านและเขียนไปยังแคชระยะไกล
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
แคช HTTP ระยะไกลรองรับการเชื่อมต่อผ่านซ็อกเก็ตโดเมน Unix ลักษณะการทำงาน
คล้ายกับ Flag --unix-socket
ของ Curl ใช้รายการต่อไปนี้เพื่อกำหนดค่า Unix
ซ็อกเก็ตโดเมน:
build --remote_cache=http://your.host:port
build --remote_cache_proxy=unix:/path/to/socket
ฟีเจอร์นี้ไม่รองรับใน Windows
ดิสก์แคช
Bazel ใช้ไดเรกทอรีในระบบไฟล์เป็นแคชระยะไกลได้ นี่คือ มีประโยชน์ในการแชร์อาร์ติแฟกต์ของบิลด์เมื่อเปลี่ยน Branch และ/หรือขณะทำงาน บนพื้นที่ทำงานหลายแห่งของโปรเจ็กต์เดียวกัน เช่น จุดชำระเงินหลายรายการ ตั้งแต่ปี Bazel ไม่ได้รวบรวมข้อมูลไดเรกทอรี คุณอาจต้องทำให้ไดเรกทอรี การล้างไดเรกทอรีนี้เป็นระยะ เปิดใช้ดิสก์แคชดังนี้
build --disk_cache=path/to/build/cache
คุณส่งเส้นทางเฉพาะผู้ใช้ไปยังแฟล็ก --disk_cache
ได้โดยใช้ชื่อแทน ~
(Bazel จะแทนที่ไดเรกทอรีหน้าแรกของผู้ใช้ปัจจุบัน) มีประโยชน์
เมื่อเปิดใช้ดิสก์แคชสำหรับผู้พัฒนาโปรเจ็กต์ทุกคนผ่าน
เช็คอิน .bazelrc
ไฟล์
ปัญหาที่ทราบ
ป้อนข้อมูลการแก้ไขไฟล์ระหว่างบิลด์
เมื่อไฟล์อินพุตมีการแก้ไขระหว่างการสร้าง Bazel อาจอัปโหลดที่ไม่ถูกต้อง
ผลลัพธ์ไปยังแคชระยะไกล คุณเปิดใช้การตรวจหาการเปลี่ยนแปลงได้ด้วย
ธง--experimental_guard_against_concurrent_changes
เรียบร้อย
ไม่ใช่ปัญหาที่ทราบแล้ว และจะเปิดใช้โดยค่าเริ่มต้นในรุ่นถัดไป
ดูการอัปเดตใน [ปัญหา #3360] โดยทั่วไปแล้ว ให้หลีกเลี่ยงการแก้ไขไฟล์ต้นฉบับในระหว่าง
งานสร้าง
ตัวแปรสภาพแวดล้อมรั่วไหลสู่การทำงาน
คำจำกัดความการดำเนินการมีตัวแปรสภาพแวดล้อม นี่อาจเป็นปัญหาสำหรับ
แชร์การพบแคชระยะไกลข้ามเครื่องได้ ตัวอย่างเช่น สภาพแวดล้อมที่มี
ตัวแปร $PATH
ที่ต่างกันจะไม่แชร์ Hit ของแคช เฉพาะตัวแปรสภาพแวดล้อม
รายการที่อนุญาตอย่างชัดแจ้งผ่าน --action_env
รวมอยู่ในการดำเนินการ
ของเรา แพ็กเกจ Debian/Ubuntu ของ Bazel ที่ใช้ติดตั้ง /etc/bazel.bazelrc
ด้วยรายการที่อนุญาตพิเศษของตัวแปรสภาพแวดล้อม ซึ่งรวมถึง $PATH
หากคุณกำลัง
พบแคชน้อยกว่าที่คาดไว้ โปรดตรวจสอบว่าสภาพแวดล้อมไม่มี
/etc/bazel.bazelrc
ไฟล์
Bazel ไม่ติดตามเครื่องมือนอกพื้นที่ทำงาน
ขณะนี้ Bazel ไม่ได้ติดตามเครื่องมือนอกพื้นที่ทำงาน ค่านี้อาจเป็น
ตัวอย่างเช่น หากการดำเนินการใช้คอมไพเลอร์จาก /usr/bin/
จากนั้นให้ทำดังนี้
ผู้ใช้ 2 รายที่ติดตั้งคอมไพเลอร์ไว้แตกต่างกันจะแชร์ Hit ของแคชอย่างไม่ถูกต้อง
เนื่องจากเอาต์พุตแตกต่างกัน แต่มีแฮชการดำเนินการเหมือนกัน โปรดดู
ปัญหา #4558 สำหรับการอัปเดต
สถานะในหน่วยความจำที่เพิ่มขึ้นหายไปเมื่อเรียกใช้บิลด์ภายในคอนเทนเนอร์ Docker Bazel ใช้สถาปัตยกรรมของเซิร์ฟเวอร์/ไคลเอ็นต์แม้จะทำงานในคอนเทนเนอร์ Docker เดี่ยว ในฝั่งเซิร์ฟเวอร์ Bazel จะมีสถานะในหน่วยความจำซึ่งช่วยเร่งการสร้างให้เร็วขึ้น เมื่อเรียกใช้บิลด์ภายในคอนเทนเนอร์ Docker เช่น ใน CI สถานะในหน่วยความจำจะหายไป และ Bazel จะต้องสร้างใหม่ ก่อนจึงจะใช้แคชระยะไกล
ลิงก์ภายนอก
บิลด์ของคุณในศูนย์ข้อมูล: ทีม Bazel ได้พูดคุยเกี่ยวกับการแคชและการดำเนินการจากระยะไกลที่ FOSDEM 2018
สร้าง Bazel ที่รวดเร็วขึ้นด้วยการแคชระยะไกล: ตัวเปรียบเทียบ: Nicolò Valigi เขียน บล็อกโพสต์ ที่ใช้เปรียบเทียบการแคชระยะไกลใน Bazel