ผู้ปฏิบัติงาน Multiplex (ฟีเจอร์ทดลอง)

หน้านี้จะอธิบายเกี่ยวกับ Multiplex Worker วิธีเขียนกฎที่เข้ากันได้กับ Multiplex และวิธีแก้ปัญหาข้อจำกัดบางอย่าง

Multiplex Worker ช่วยให้ Bazel จัดการคำขอหลายรายการด้วยกระบวนการ Worker เดียวได้ สำหรับ Worker แบบหลายเธรด Bazel สามารถใช้ทรัพยากรน้อยลงเพื่อให้ได้ประสิทธิภาพเท่าเดิมหรือดีกว่า เช่น แทนที่จะมีโปรแกรมทำงาน 1 รายการต่อโปรแกรมทำงาน 1 รายการ Bazel สามารถมีโปรแกรมทำงานแบบมัลติเพล็กซ์ 4 รายการที่สื่อสารกับโปรแกรมทำงานเดียวกัน ซึ่งจะจัดการคำขอแบบขนานได้ สำหรับภาษาอย่าง Java และ Scala การดำเนินการนี้จะช่วยประหยัดเวลาในการวอร์มอัพ JVM และเวลาในการคอมไพล์ JIT และโดยทั่วไปจะช่วยให้ใช้แคชที่แชร์ร่วมกันระหว่าง Worker ทุกคนในประเภทเดียวกันได้

ภาพรวม

มี 2 เลเยอร์ระหว่างเซิร์ฟเวอร์ Bazel กับกระบวนการ Worker สำหรับ การช่วยจำบางอย่างที่เรียกใช้กระบวนการแบบขนานได้ Bazel จะรับ WorkerProxy จาก พูล Worker WorkerProxy จะส่งต่อคำขอไปยังกระบวนการ Worker ตามลำดับพร้อมกับ request_id กระบวนการ Worker จะประมวลผลคำขอ และส่งการตอบกลับไปยัง WorkerMultiplexer เมื่อ WorkerMultiplexer ได้รับคำตอบ ระบบจะแยกวิเคราะห์ request_id แล้วส่งต่อคำตอบ กลับไปยัง WorkerProxy ที่ถูกต้อง เช่นเดียวกับ Worker ที่ไม่ได้มัลติเพล็กซ์ การสื่อสารทั้งหมดจะดำเนินการผ่านอินพุต/เอาต์พุตมาตรฐาน แต่เครื่องมือไม่สามารถใช้ stderr สำหรับเอาต์พุตที่ผู้ใช้มองเห็นได้ (ดูด้านล่าง)

ผู้ปฏิบัติงานแต่ละคนจะมีคีย์ Bazel ใช้รหัสแฮชของคีย์ (ประกอบด้วยตัวแปร สภาพแวดล้อม รูทการดำเนินการ และมνηนิค) เพื่อกำหนดว่าควรใช้ WorkerMultiplexer ใด WorkerProxyจะสื่อสารกับ WorkerMultiplexer เดียวกันหากมีรหัสแฮชเดียวกัน ดังนั้น หากตัวแปรสภาพแวดล้อมและรูทการดำเนินการเหมือนกันในการเรียกใช้ Bazel ครั้งเดียว แต่ละ Mnemonic ที่ไม่ซ้ำกันจะมีได้เพียง 1 WorkerMultiplexer และ 1 กระบวนการของ Worker จำนวนผู้ปฏิบัติงานทั้งหมด รวมถึงผู้ปฏิบัติงานทั่วไปและWorkerProxy ยังคงถูกจำกัดโดย --worker_max_instances

การเขียนกฎที่ใช้ได้กับมัลติเพล็กซ์

กระบวนการ Worker ของกฎควรเป็นแบบหลายเธรดเพื่อใช้ประโยชน์จาก Worker แบบมัลติเพล็กซ์ Protobuf ช่วยให้ชุดกฎวิเคราะห์คำขอเดียวได้ แม้ว่าอาจมีคำขอหลายรายการสะสมอยู่ในสตรีม เมื่อใดก็ตามที่กระบวนการของ Worker แยกวิเคราะห์คำขอจากสตรีม กระบวนการดังกล่าวควรจัดการคำขอใน เธรดใหม่ เนื่องจากเธรดต่างๆ อาจดำเนินการเสร็จสิ้นและเขียนไปยังสตรีมในเวลาเดียวกัน กระบวนการของ Worker จึงต้องตรวจสอบว่าการตอบกลับได้รับการเขียนแบบอะตอมมิก (ข้อความไม่ทับซ้อนกัน) การตอบกลับต้องมี request_id ของคำขอที่กำลังจัดการ

การจัดการเอาต์พุต Multiplex

ผู้ปฏิบัติงานแบบมัลติเพล็กซ์ต้องระมัดระวังในการจัดการเอาต์พุตมากกว่า ผู้ปฏิบัติงานแบบซิมเพล็กซ์ ข้อมูลใดก็ตามที่ส่งไปยัง stderr จะไปอยู่ในไฟล์บันทึกเดียว ซึ่งแชร์ใน WorkerProxy ประเภทเดียวกันทั้งหมด โดยจะสลับกันแบบสุ่มระหว่างคำขอที่เกิดขึ้นพร้อมกัน แม้ว่าการเปลี่ยนเส้นทาง stdout ไปยัง stderr จะเป็นความคิดที่ดี แต่ก็ไม่ควรรวบรวมเอาเอาต์พุตนั้นไว้ในฟิลด์ output ของ WorkResponse เนื่องจากอาจแสดงเอาต์พุตที่ผู้ใช้เห็นเป็นชิ้นส่วนที่ผิดเพี้ยน หากเครื่องมือของคุณส่งเฉพาะเอาต์พุตที่มุ่งเน้นผู้ใช้ไปยัง stdout หรือ stderr คุณจะต้องเปลี่ยนลักษณะการทำงานดังกล่าวก่อนจึงจะเปิดใช้ 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 อย่าง คุณปิดใช้ Worker แบบมัลติเพล็กซ์ ทั่วโลกได้โดยส่ง --noworker_multiplex

เราขอแนะนำให้ใช้ชุดกฎเพื่อใช้ Worker แบบมัลติเพล็กซ์หากเป็นไปได้ เพื่อลดแรงกดดันด้านหน่วยความจำและปรับปรุงประสิทธิภาพ อย่างไรก็ตาม ขณะนี้ Worker แบบมัลติเพล็กซ์ยังใช้ร่วมกับการดำเนินการแบบไดนามิกไม่ได้ เว้นแต่จะใช้แซนด์บ็อกซ์แบบมัลติเพล็กซ์ การพยายามเรียกใช้ Multiplex Worker ที่ไม่ได้อยู่ในแซนด์บ็อกซ์ ด้วยการดำเนินการแบบไดนามิกจะใช้ Singleplex Worker ที่อยู่ในแซนด์บ็อกซ์ แทนโดยไม่มีการแจ้งเตือน

แซนด์บ็อกซ์ Multiplex

คุณสามารถจำกัดการทำงานของ Multiplex ได้โดยเพิ่มการรองรับอย่างชัดเจนใน การใช้งาน Worker แม้ว่าการแซนด์บ็อกซ์ของ Worker แบบ Singleplex จะทำได้โดย การเรียกใช้กระบวนการ Worker แต่ละรายการในแซนด์บ็อกซ์ของตัวเอง แต่ Worker แบบ Multiplex จะแชร์ ไดเรกทอรีการทำงานของกระบวนการระหว่างคำขอแบบขนานหลายรายการ หากต้องการอนุญาตให้ใช้ Sandbox ของ Worker แบบมัลติเพล็กซ์ Worker ต้องรองรับการอ่านจากและ การเขียนไปยังไดเรกทอรีย่อยที่ระบุในแต่ละคำขอ แทนที่จะอยู่ใน ไดเรกทอรีการทำงานโดยตรง

หากต้องการรองรับการแซนด์บ็อกซ์แบบมัลติเพล็กซ์ Worker ต้องใช้ฟิลด์ sandbox_dir จาก WorkRequest และใช้เป็นคำนำหน้าสำหรับการอ่านและเขียนไฟล์ทั้งหมด แม้ว่าฟิลด์ arguments และ inputs จะยังคงเหมือนเดิมจากคำขอที่ไม่ได้อยู่ในแซนด์บ็อกซ์ แต่ข้อมูลที่ป้อนจริงจะสัมพันธ์กับ 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