หน้านี้จะครอบคลุมการแคชระยะไกล การตั้งค่าเซิร์ฟเวอร์เพื่อโฮสต์แคช และ กำลังใช้บิลด์โดยใช้แคชระยะไกล
ทีมนักพัฒนาแอปใช้แคชระยะไกลและ/หรือการผสานรวมอย่างต่อเนื่อง (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
คำเตือน: สร้างโดยไม่ใช้ไบต์ ไม่สามารถทำงานร่วมกับแคช HTTP หากต้องการเพิ่มประสิทธิภาพสูงสุด ลองใช้แคช gRPC แทนนะ
เรียกใช้ 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_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