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

รายงานปัญหา ดูแหล่งที่มา Nightly · 8.4 · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

หน้านี้จะอธิบายเกี่ยวกับ 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