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