การดำเนินการแบบไดนามิกเป็นฟีเจอร์ใน Bazel ที่จะเริ่มการดำเนินการเดียวกันแบบคู่ขนานทั้งในเครื่องและจากระยะไกล โดยใช้เอาต์พุตจากสาขาแรกที่ทำเสร็จแล้ว และยกเลิกอีกสาขาหนึ่ง ซึ่งจะรวมประสิทธิภาพการดําเนินการและ/หรือแคชที่แชร์ขนาดใหญ่ของระบบบิลด์ระยะไกลเข้ากับเวลาในการตอบสนองที่ต่ำของการดําเนินการในเครื่อง โดยใช้ข้อดีของทั้ง 2 อย่างในการสร้างบิลด์ที่สะอาดและบิลด์ที่เพิ่มเข้ามา
หน้านี้จะอธิบายวิธีเปิดใช้ ปรับแต่ง และแก้ไขข้อบกพร่องของการดำเนินการแบบไดนามิก หากคุณตั้งค่าทั้งการดำเนินการแบบใช้เครื่องและแบบใช้ระยะไกล และพยายามปรับการตั้งค่า Bazel เพื่อประสิทธิภาพที่ดียิ่งขึ้น หน้านี้เหมาะสำหรับคุณ หากยังไม่ได้ตั้งค่าการดําเนินการจากระยะไกล ให้ไปที่ภาพรวมการดําเนินการจากระยะไกลของ Bazel ก่อน
การเปิดใช้การดำเนินการแบบไดนามิก
โมดูลการดําเนินการแบบไดนามิกเป็นส่วนหนึ่งของ Bazel แต่หากต้องการใช้ประโยชน์จากการดําเนินการแบบไดนามิก คุณต้องคอมไพล์ได้ทั้งในเครื่องและจากระยะไกลจากการตั้งค่า Bazel เดียวกัน
หากต้องการเปิดใช้โมดูลการดำเนินการแบบไดนามิก ให้ส่ง --internal_spawn_scheduler
flag ไปยัง Bazel ซึ่งจะเป็นการเพิ่มกลยุทธ์การดําเนินการใหม่ชื่อ dynamic
ตอนนี้คุณใช้กลยุทธ์นี้กับคําช่วยจําที่ต้องการเรียกใช้แบบไดนามิกได้แล้ว เช่น --strategy=Javac=dynamic
ดูวิธีเลือกคําช่วยจําที่จะเปิดใช้การดําเนินการแบบไดนามิกได้ที่ส่วนถัดไป
สําหรับคําช่วยจําที่ใช้กลยุทธ์แบบไดนามิก ระบบจะนํากลยุทธ์การเรียกใช้จากระยะไกลมาจาก Flag --dynamic_remote_strategy
และกลยุทธ์ในเครื่องมาจาก Flag --dynamic_local_strategy
การส่ง--dynamic_local_strategy=worker,sandboxed
จะตั้งค่าเริ่มต้นสำหรับสาขาการดำเนินการแบบไดนามิกในเครื่องเพื่อลองใช้กับเวิร์กเกอร์หรือการดำเนินการในแซนด์บ็อกซ์ตามลำดับดังกล่าว การส่ง --dynamic_local_strategy=Javac=worker
จะลบล้างค่าเริ่มต้นสำหรับตัวช่วยจำ Javac เท่านั้น เวอร์ชันระยะไกลทํางานในลักษณะเดียวกัน คุณระบุทั้ง 2 การตั้งค่าสถานะได้หลายครั้ง หากการดำเนินการไม่สามารถดำเนินการได้ในพื้นที่ ระบบจะดำเนินการจากระยะไกลตามปกติ และในทางกลับกัน
หากระบบระยะไกลมีแคช FLAG --dynamic_local_execution_delay
จะเพิ่มการหน่วงเวลาเป็นมิลลิวินาทีในการเรียกใช้ในเครื่องหลังจากที่ระบบระยะไกลระบุการพบข้อมูลในแคช วิธีนี้จะช่วยหลีกเลี่ยงการเรียกใช้ในเครื่องเมื่อมีโอกาสที่ระบบจะพบรายการในแคชมากขึ้น ค่าเริ่มต้นคือ 1000 มิลลิวินาที แต่ควรปรับให้นานกว่าเวลาในการ Hit แคชปกติเพียงเล็กน้อย เวลาจริงจะขึ้นอยู่กับทั้งระบบระยะไกลและระยะเวลาในการรับส่งข้อมูล โดยทั่วไป ค่านี้จะเหมือนกันสำหรับผู้ใช้ทั้งหมดของระบบระยะไกลหนึ่งๆ เว้นแต่ว่าผู้ใช้บางรายอยู่ไกลพอที่จะเพิ่มเวลาในการตอบสนองในการรับส่งข้อมูล คุณสามารถใช้ฟีเจอร์การโปรไฟล์ Bazel เพื่อดูระยะเวลาที่การตีข้อมูลแคชตามปกติใช้เวลา
การดำเนินการแบบไดนามิกใช้ได้กับกลยุทธ์ที่ใช้แซนด์บ็อกซ์ในเครื่องและเวิร์กเกอร์แบบถาวร เวิร์กเกอร์แบบถาวรจะทำงานกับแซนด์บ็อกซ์โดยอัตโนมัติเมื่อใช้กับการเรียกใช้แบบไดนามิก และใช้เวิร์กเกอร์แบบมัลติเพล็กซ์ไม่ได้ ในระบบ Darwin และ Windows กลยุทธ์ที่ใช้แซนด์บ็อกซ์อาจทำงานช้า คุณส่ง --reuse_sandbox_directories
เพื่อลดค่าใช้จ่ายในการสร้างแซนด์บ็อกซ์ในระบบเหล่านี้ได้
การดำเนินการแบบไดนามิกยังทํางานร่วมกับกลยุทธ์ standalone
ได้ด้วย แต่เนื่องจากกลยุทธ์ standalone
ต้องล็อกเอาต์พุตเมื่อเริ่มทํางาน จึงจะบล็อกกลยุทธ์ระยะไกลไม่ให้ทํางานเสร็จก่อน FLAG --experimental_local_lockfree_output
ช่วยแก้ปัญหานี้ได้โดยอนุญาตให้การดําเนินการในเครื่องเขียนไปยังเอาต์พุตโดยตรง แต่จะถูกยกเลิกโดยการดำเนินการระยะไกลหากดำเนินการเสร็จสิ้นก่อน
หากสาขาใดสาขาหนึ่งของการดําเนินการแบบไดนามิกทํางานเสร็จก่อนแต่ดำเนินการไม่สําเร็จ การดําเนินการทั้งหมดก็จะไม่สําเร็จ นี่เป็นตัวเลือกที่เราตั้งใจเลือกเพื่อป้องกันไม่ให้ผู้ใช้สังเกตเห็นความแตกต่างระหว่างการดำเนินการแบบในเครื่องกับแบบระยะไกล
ดูข้อมูลเบื้องต้นเพิ่มเติมเกี่ยวกับวิธีการทำงานของการดําเนินการแบบไดนามิกและการล็อกได้ที่บล็อกโพสต์ที่ยอดเยี่ยมของ Julio Merino
ฉันควรใช้การเรียกใช้แบบไดนามิกเมื่อใด
การดำเนินการแบบไดนามิกต้องใช้ระบบการดําเนินการจากระยะไกลรูปแบบใดรูปแบบหนึ่ง ปัจจุบันคุณยังไม่สามารถใช้ระบบระยะไกลที่ใช้แคชอย่างเดียวได้ เนื่องจากระบบจะถือว่าการแคชไม่พบเป็นการดําเนินการที่ล้มเหลว
การดำเนินการบางประเภทไม่เหมาะกับการดำเนินการจากระยะไกล ตัวเลือกที่ดีที่สุดคือตัวเลือกที่ทำงานได้เร็วกว่าในเครื่องอยู่แล้ว เช่น การใช้เวิร์กเกอร์แบบถาวร หรือตัวเลือกที่ทำงานได้เร็วพอที่ค่าใช้จ่ายเพิ่มเติมของการดำเนินการระยะไกลจะส่งผลต่อเวลาดำเนินการ เนื่องจากการดำเนินการแต่ละรายการที่ดำเนินการในเครื่องจะล็อกทรัพยากร CPU และหน่วยความจำบางส่วน การดําเนินการที่ทำงานอยู่ซึ่งไม่อยู่ในหมวดหมู่เหล่านั้นจะแค่ทำให้การดำเนินการของการดำเนินการที่อยู่ในหมวดหมู่เหล่านั้นล่าช้า
ตั้งแต่รุ่น 5.0.0-pre.20210708.4 การวัดประสิทธิภาพจะมีข้อมูลเกี่ยวกับการดำเนินการของเวิร์กเกอร์ รวมถึงเวลาที่ใช้ในการดำเนินการตามคำของานให้เสร็จสิ้นหลังจากแพ้การแข่งขันการดําเนินการแบบไดนามิก หากเห็นเธรดผู้ปฏิบัติงานแบบดำเนินการแบบไดนามิกใช้เวลานานในการรับทรัพยากรหรือใช้เวลานานในasync-worker-finish
แสดงว่าคุณอาจมีการดำเนินการบางอย่างในเครื่องที่ช้าซึ่งทำให้เธรดผู้ปฏิบัติงานล่าช้า
ในโปรไฟล์ด้านบนซึ่งใช้ Javac Worker 8 คน เราพบว่า Javac Worker จำนวนมากแพ้การแข่งขันและทำงานเสร็จใน async-worker-finish
เธรด ปัญหานี้เกิดจากคําช่วยจําที่ไม่ใช่ผู้ทํางานใช้ทรัพยากรมากพอที่จะทําให้เกิดความล่าช้า
เมื่อเรียกใช้เฉพาะ Javac ด้วยการดำเนินการแบบไดนามิก พบว่ามีเพียงเวิร์กเกอร์ที่เริ่มต้นประมาณครึ่งหนึ่งที่แพ้การแข่งขันหลังจากเริ่มทํางาน
ระบบเลิกใช้งานการแจ้งว่าไม่เหมาะสม --experimental_spawn_scheduler
ที่แนะนำก่อนหน้านี้แล้ว
ซึ่งจะเปิดใช้การดำเนินการแบบไดนามิกและตั้งค่า dynamic
เป็นกลยุทธ์เริ่มต้นสำหรับคําช่วยจําทั้งหมด ซึ่งมักจะทําให้เกิดปัญหาประเภทนี้
ประสิทธิภาพ
แนวทางการดําเนินการแบบไดนามิกจะถือว่ามีทรัพยากรเพียงพอในเครื่องและจากระยะไกล ซึ่งคุ้มค่าที่จะใช้ทรัพยากรเพิ่มเติมเพื่อปรับปรุงประสิทธิภาพโดยรวม แต่การใช้ทรัพยากรมากเกินไปอาจทำให้ Bazel หรือเครื่องที่ใช้ทำงานช้าลง หรือสร้างแรงกดดันที่ไม่คาดคิดให้กับระบบระยะไกล การเปลี่ยนลักษณะการทํางานแบบไดนามิกมีหลายตัวเลือก ดังนี้
--dynamic_local_execution_delay
จะเลื่อนเวลาเริ่มต้นของสาขาในเครื่องตามจำนวนมิลลิวินาทีหลังจากที่สาขาระยะไกลเริ่มต้นขึ้น แต่เฉพาะในกรณีที่มีการเรียกใช้แคชระยะไกลระหว่างบิลด์ปัจจุบันเท่านั้น วิธีนี้ช่วยให้บิลด์ที่ใช้ประโยชน์จากการแคชระยะไกลไม่สิ้นเปลืองทรัพยากรในเครื่องเมื่อมีโอกาสที่ระบบจะพบเอาต์พุตส่วนใหญ่ในแคช การลดจำนวนนี้อาจช่วยเพิ่มความเร็วในการบิลด์ได้ ทั้งนี้ขึ้นอยู่กับคุณภาพของแคช แต่อาจต้องใช้ทรัพยากรในเครื่องมากขึ้น
--experimental_dynamic_local_load_factor
เป็นตัวเลือกการจัดการทรัพยากรขั้นสูงเวอร์ชันทดลอง ค่านี้อยู่ในช่วง 0 ถึง 1 โดย 0 หมายถึงปิดฟีเจอร์นี้
เมื่อตั้งค่าเป็นค่าที่มากกว่า 0 แล้ว Bazel จะปรับจำนวนการดำเนินการที่ตั้งเวลาไว้ในพื้นที่เมื่อมีการดำเนินการจำนวนมากที่รอกำหนดเวลา การตั้งค่าเป็น 1 จะช่วยให้กําหนดเวลาการดําเนินการได้จํานวนมากเท่ากับที่มี CPU พร้อมใช้งาน (ตาม --local_cpu_resources
) ค่าที่ต่ำลงจะกําหนดจํานวนการดําเนินการที่กําหนดเวลาไว้ให้น้อยลงตามลําดับเมื่อการดําเนินการจํานวนมากขึ้นพร้อมใช้งาน เรื่องนี้อาจฟังดูขัดแย้ง แต่หากมีระบบระยะไกลที่ดี การดำเนินการในเครื่องจะไม่ช่วยอะไรมากนักเมื่อมีการดำเนินการหลายรายการ และ CPU ในเครื่องจะทํางานได้ดีกว่าเมื่อจัดการการดำเนินการระยะไกล
--experimental_dynamic_slow_remote_time
ให้ความสําคัญกับการเริ่มสาขาในเครื่องเมื่อสาขาระยะไกลทํางานมาแล้วอย่างน้อยเท่านี้ โดยปกติแล้ว การดำเนินการที่ตั้งเวลาไว้ล่าสุดจะได้รับลําดับความสําคัญสูงสุด เนื่องจากมีแนวโน้มที่จะทํางานได้เร็วที่สุด แต่หากระบบระยะไกลค้างหรือใช้เวลานานเกินไปในบางครั้ง การดำเนินการนี้อาจทำให้บิลด์ทำงานต่อไปได้ ตัวเลือกนี้จะไม่เปิดใช้โดยค่าเริ่มต้น เนื่องจากอาจซ่อนปัญหาเกี่ยวกับระบบระยะไกลที่ควรได้รับการแก้ไข อย่าลืมตรวจสอบประสิทธิภาพของระบบระยะไกลหากคุณเปิดใช้ตัวเลือกนี้
--experimental_dynamic_ignore_local_signals
ใช้เพื่อให้สาขาระยะไกลเข้ามาควบคุมได้เมื่อการเริ่มต้นในพื้นที่สิ้นสุดลงเนื่องจากสัญญาณที่ระบุ ซึ่งมีประโยชน์หลักๆ ร่วมกับขีดจำกัดทรัพยากรของเวิร์กเกอร์ (ดู --experimental_worker_memory_limit_mb
, --experimental_worker_sandbox_hardening
และ --experimental_sandbox_memory_limit_mb
) ซึ่งระบบอาจหยุดกระบวนการของเวิร์กเกอร์เมื่อใช้ทรัพยากรมากเกินไป
โปรไฟล์การติดตาม JSON มีกราฟที่เกี่ยวข้องกับประสิทธิภาพจํานวนหนึ่งซึ่งช่วยระบุวิธีปรับปรุงการแลกเปลี่ยนประสิทธิภาพกับการใช้ทรัพยากร
การแก้ปัญหา
ปัญหาเกี่ยวกับการดําเนินการแบบไดนามิกอาจมองไม่เห็นและแก้ไขข้อบกพร่องได้ยาก เนื่องจากอาจแสดงภายใต้การผสมผสานบางอย่างที่เฉพาะเจาะจงของการดำเนินการแบบภายในและแบบระยะไกล
--debug_spawn_scheduler
จะเพิ่มเอาต์พุตเพิ่มเติมจากระบบการดําเนินการแบบไดนามิกที่จะช่วยแก้ไขข้อบกพร่องเหล่านี้ได้ นอกจากนี้ คุณยังปรับFlag --dynamic_local_execution_delay
และจํานวนงานระยะไกลเทียบกับงานในเครื่องเพื่อให้จำลองปัญหาได้ง่ายขึ้นได้ด้วย
หากพบปัญหาเกี่ยวกับการดําเนินการแบบไดนามิกโดยใช้กลยุทธ์ standalone
ให้ลองทํางานโดยไม่ใช้ --experimental_local_lockfree_output
หรือทําการกระทําในพื้นที่เสมือน ซึ่งอาจทำให้บิลด์ช้าลงเล็กน้อย (ดูด้านบนหากคุณใช้ Mac หรือ Windows) แต่จะช่วยขจัดสาเหตุที่เป็นไปได้บางประการของการทำงานที่ไม่สำเร็จ