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

รายงานปัญหา ดูซอร์สโค้ด รุ่น Nightly · 8.0 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

หน้านี้จะอธิบายเกี่ยวกับเวิร์กเกอร์แบบมัลติเพล็กซ์ วิธีเขียนกฎที่เข้ากันได้กับมัลติเพล็กซ์ และวิธีแก้ปัญหาบางอย่างที่จำกัด

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