หน้านี้จะอธิบายเกี่ยวกับ Multiplex Worker วิธีเขียนกฎที่ใช้ได้กับ Multiplex และวิธีแก้ปัญหาข้อจำกัดบางอย่าง
Multiplex worker ช่วยให้ Bazel จัดการคำขอหลายรายการด้วยกระบวนการ Worker เดียวได้ สำหรับ Worker แบบหลายเธรด Bazel สามารถใช้ทรัพยากรน้อยลงเพื่อ ให้ได้ประสิทธิภาพเท่าเดิมหรือดีกว่า ตัวอย่างเช่น แทนที่จะมีกระบวนการทำงาน 1 รายการต่อผู้ปฏิบัติงาน 1 คน Bazel สามารถมีผู้ปฏิบัติงานแบบมัลติเพล็กซ์ 4 คนที่สื่อสารกับกระบวนการทำงานเดียวกัน ซึ่งจะจัดการคำขอแบบขนานได้ สำหรับภาษาอย่าง Java และ Scala การดำเนินการนี้จะช่วยประหยัดเวลาในการวอร์มอัพ JVM และเวลาในการคอมไพล์ JIT และโดยทั่วไปจะช่วยให้ใช้แคชที่แชร์ร่วมกันระหว่างผู้ปฏิบัติงานทุกรายที่มีประเภทเดียวกันได้
ภาพรวม
มี 2 เลเยอร์ระหว่างเซิร์ฟเวอร์ Bazel กับกระบวนการ Worker สำหรับ
การช่วยจำบางอย่างที่เรียกใช้กระบวนการแบบขนานได้ Bazel จะรับ WorkerProxy
จาก
พูลผู้ปฏิบัติงาน WorkerProxy
จะส่งต่อคำขอไปยังกระบวนการของ Worker
ตามลำดับพร้อมกับ request_id
กระบวนการของ Worker จะประมวลผลคำขอ
และส่งการตอบกลับไปยัง WorkerMultiplexer
เมื่อ WorkerMultiplexer
ได้รับคำตอบ ระบบจะแยกวิเคราะห์ request_id
แล้วส่งต่อคำตอบ
กลับไปยัง WorkerProxy
ที่ถูกต้อง เช่นเดียวกับ Worker ที่ไม่ใช่แบบมัลติเพล็กซ์ การสื่อสารทั้งหมดจะดำเนินการผ่านอินพุต/เอาต์พุตมาตรฐาน แต่เครื่องมือไม่สามารถใช้ stderr
สำหรับเอาต์พุตที่ผู้ใช้มองเห็นได้ (ดูด้านล่าง)
ผู้ปฏิบัติงานแต่ละคนจะมีคีย์ Bazel ใช้รหัสแฮชของคีย์ (ประกอบด้วยตัวแปรสภาพแวดล้อม
รูทการดำเนินการ และคำช่วยจำ) เพื่อกำหนดว่าควรใช้ WorkerMultiplexer
ใด WorkerProxy
จะสื่อสารกับ WorkerMultiplexer
เดียวกันหากมีรหัสแฮชเดียวกัน ดังนั้น หากตัวแปรสภาพแวดล้อมและรูทการดำเนินการเหมือนกันในการเรียกใช้ Bazel ครั้งเดียว แต่ละมnemonic ที่ไม่ซ้ำกันจะมีได้เพียง 1 WorkerMultiplexer
และ 1
กระบวนการของ Worker จำนวนผู้ปฏิบัติงานทั้งหมด ซึ่งรวมถึงผู้ปฏิบัติงานทั่วไปและWorkerProxy
ยังคงถูกจำกัดโดย --worker_max_instances
การเขียนกฎที่ใช้ได้กับมัลติเพล็กซ์
กระบวนการทำงานของกฎควรเป็นแบบหลายเธรดเพื่อใช้ประโยชน์จาก
ผู้ปฏิบัติงานแบบมัลติเพล็กซ์ Protobuf ช่วยให้ชุดกฎวิเคราะห์คำขอเดียวได้ แม้ว่าอาจมีคำขอหลายรายการสะสมอยู่ในสตรีม เมื่อใดก็ตามที่
กระบวนการของ Worker แยกวิเคราะห์คำขอจากสตรีม กระบวนการควรจัดการคำขอใน
เธรดใหม่ เนื่องจากเธรดต่างๆ อาจเขียนลงในสตรีมพร้อมกัน กระบวนการ Worker จึงต้องตรวจสอบว่าการตอบกลับได้รับการเขียนแบบอะตอมมิก (ข้อความไม่ทับซ้อนกัน) การตอบกลับต้องมีrequest_id
ของคำขอที่กำลังจัดการ
การจัดการเอาต์พุต Multiplex
ผู้ปฏิบัติงานแบบมัลติเพล็กซ์ต้องระมัดระวังในการจัดการเอาต์พุตมากกว่า
ผู้ปฏิบัติงานแบบซิงเกิลเพล็กซ์ ข้อมูลใดก็ตามที่ส่งไปยัง stderr
จะไปอยู่ในไฟล์บันทึกเดียว
ซึ่งแชร์ใน WorkerProxy
ทั้งหมดประเภทเดียวกัน
โดยจะสลับกันแบบสุ่มระหว่างคำขอที่เกิดขึ้นพร้อมกัน แม้ว่าการเปลี่ยนเส้นทาง stdout
ไปยัง stderr
จะเป็นความคิดที่ดี แต่ก็ไม่ควรเก็บเอาต์พุตนั้นไว้ในฟิลด์ output
ของ WorkResponse
เนื่องจากอาจแสดงเอาต์พุตที่ผู้ใช้เห็นเป็นชิ้นส่วนที่เสียหาย
หากเครื่องมือของคุณส่งเอาต์พุตที่มุ่งเน้นผู้ใช้ไปยัง stdout
หรือ stderr
เท่านั้น คุณจะต้องเปลี่ยนลักษณะการทำงานดังกล่าวก่อนจึงจะเปิดใช้ Multiplex Worker ได้
การเปิดใช้ Multiplex Worker
ระบบจะไม่ได้เปิดใช้ Worker ของ Multiplex โดยค่าเริ่มต้น ชุดกฎสามารถเปิดใช้ Multiplex
Worker ได้โดยใช้แท็ก supports-multiplex-workers
ใน
execution_requirements
ของการดำเนินการ (เช่นเดียวกับแท็ก supports-workers
ที่เปิดใช้ Worker ปกติ) เช่นเดียวกับการใช้ Worker ปกติ คุณต้องระบุกลยุทธ์ Worker ไม่ว่าจะที่ระดับชุดกฎ (เช่น --strategy=[some_mnemonic]=worker
) หรือที่ระดับกลยุทธ์โดยทั่วไป (เช่น --dynamic_local_strategy=worker,standalone
) ไม่จำเป็นต้องใช้ Flag เพิ่มเติม และ supports-multiplex-workers
จะมีความสำคัญเหนือกว่า supports-workers
หากตั้งค่าทั้ง 2 อย่าง คุณปิดใช้ Multiplex Worker
ได้ทั่วโลกโดยส่ง --noworker_multiplex
เราขอแนะนำให้ชุดกฎใช้ Worker แบบมัลติเพล็กซ์หากเป็นไปได้ เพื่อลดแรงกดดันด้านหน่วยความจำและปรับปรุงประสิทธิภาพ อย่างไรก็ตาม ขณะนี้ Worker แบบมัลติเพล็กซ์ยังไม่รองรับการดำเนินการแบบไดนามิก เว้นแต่จะใช้แซนด์บ็อกซ์แบบมัลติเพล็กซ์ การพยายามเรียกใช้ Multiplex Worker ที่ไม่ได้อยู่ในแซนด์บ็อกซ์ด้วยการดำเนินการแบบไดนามิกจะใช้ Singleplex Worker ที่อยู่ในแซนด์บ็อกซ์แทนโดยไม่มีการแจ้งเตือน
แซนด์บ็อกซ์ Multiplex
คุณสามารถแซนด์บ็อกซ์ Worker แบบมัลติเพล็กซ์ได้โดยเพิ่มการรองรับที่ชัดเจนใน การใช้งาน Worker แม้ว่าการแซนด์บ็อกซ์ของ Worker แบบ Singleplex จะทำได้โดยการเรียกใช้กระบวนการ Worker แต่ละรายการในแซนด์บ็อกซ์ของตัวเอง แต่ Worker แบบ Multiplex จะแชร์ไดเรกทอรีการทำงานของกระบวนการระหว่างคำขอแบบขนานหลายรายการ หากต้องการอนุญาตให้ใช้ Sandbox ของ Worker แบบมัลติเพล็กซ์ Worker ต้องรองรับการอ่านจากและเขียนไปยังไดเรกทอรีย่อยที่ระบุในแต่ละคำขอ แทนที่จะอยู่ในไดเรกทอรีการทำงานโดยตรง
หากต้องการรองรับการแซนด์บ็อกซ์แบบมัลติเพล็กซ์ Worker ต้องใช้sandbox_dir
ฟิลด์
จากWorkRequest
และใช้เป็นคำนำหน้าสำหรับการอ่านและเขียนไฟล์ทั้งหมด
แม้ว่าฟิลด์ arguments
และ inputs
จะยังคงเหมือนเดิมจากคำขอที่ไม่ได้อยู่ใน Sandbox
แต่ข้อมูลที่ป้อนจริงจะสัมพันธ์กับ sandbox_dir
Worker ต้อง
แปลเส้นทางไฟล์ที่พบใน arguments
และ inputs
เพื่ออ่านจากเส้นทางที่
แก้ไขนี้ และต้องเขียนเอาต์พุตทั้งหมดที่สัมพันธ์กับ sandbox_dir
ด้วย
ซึ่งรวมถึงเส้นทาง เช่น "." รวมถึงเส้นทางที่พบในไฟล์ที่ระบุ
ในอาร์กิวเมนต์ (เช่น อาร์กิวเมนต์ "argfile")
เมื่อ Worker รองรับแซนด์บ็อกซ์แบบมัลติเพล็กซ์แล้ว ชุดกฎจะประกาศการรองรับนี้ได้โดยการเพิ่ม supports-multiplex-sandboxing
ลงใน
execution_requirements
ของการดำเนินการ จากนั้น Bazel จะใช้แซนด์บ็อกซ์แบบมัลติเพล็กซ์
หากมีการส่งแฟล็ก --experimental_worker_multiplex_sandboxing
หรือหาก
มีการใช้ Worker กับการดำเนินการแบบไดนามิก
ไฟล์ Worker ของ Multiplex Worker ที่อยู่ในแซนด์บ็อกซ์ยังคงสัมพันธ์กับ
ไดเรกทอรีการทำงานของกระบวนการ Worker ดังนั้น หากใช้ไฟล์ทั้งในการเรียกใช้ Worker และเป็นอินพุต คุณต้องระบุทั้งเป็นอินพุตในอาร์กิวเมนต์ flagfile รวมถึงใน tools
, executable
หรือ runfiles