การดำเนินการแบบไดนามิก

รายงานปัญหา ดูแหล่งที่มา

การดำเนินการแบบไดนามิกเป็นฟีเจอร์ใน Bazel ที่การดำเนินการทั้งในเครื่องและระยะไกลของการดำเนินการเดียวกันจะเริ่มต้นพร้อมกัน โดยใช้เอาต์พุตจาก Branch แรกที่เสร็จสิ้น ซึ่งเป็นการยกเลิก Branch อื่น โดยผสานรวมพลังการดำเนินการและ/หรือแคชขนาดใหญ่ที่แชร์ของระบบบิลด์ระยะไกลกับเวลาในการตอบสนองต่ำของการดำเนินการในเครื่อง ซึ่งให้สิ่งที่ดีที่สุดทั้ง 2 อย่างสำหรับบิลด์ที่ดูสะอาดตาและเพิ่มขึ้นทีละอย่าง

หน้านี้จะอธิบายวิธีเปิดใช้ ปรับแต่ง และแก้ไขข้อบกพร่องของการดำเนินการแบบไดนามิก หากคุณตั้งค่าการดำเนินการทั้งในเครื่องและระยะไกลไว้และพยายามปรับการตั้งค่า Bazel เพื่อประสิทธิภาพที่ดีขึ้น หน้านี้มีไว้สำหรับคุณ หากยังไม่ได้ตั้งค่าการดำเนินการระยะไกล ให้ไปที่ภาพรวมการดำเนินการระยะไกลของ Bazel ก่อน

เปิดใช้การดำเนินการแบบไดนามิกไหม

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

หากต้องการเปิดใช้โมดูลการดำเนินการแบบไดนามิก ให้ส่งแฟล็ก --internal_spawn_scheduler ไปยัง 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 รายการได้หลายครั้ง หากดำเนินการในเครื่องไม่ได้ ระบบจะเรียกใช้การดำเนินการดังกล่าวจากระยะไกลตามปกติ และในทางกลับกันด้วย

หากระบบระยะไกลมีแคช แฟล็ก --dynamic_local_execution_delay จะเพิ่มการหน่วงเวลาไปยังการดำเนินการในเครื่องเป็นมิลลิวินาทีหลังจากที่ระบบระยะไกลระบุการเกิดแคช ซึ่งจะหลีกเลี่ยงการเรียกใช้การดำเนินการในเครื่องเมื่อมีแนวโน้มที่จะเกิดแคชเพิ่มขึ้น ค่าเริ่มต้นคือ 1, 000 มิลลิวินาที แต่ควรปรับแต่งให้นานกว่าการทำงานของแคชที่ปกติแล้วเกิดขึ้นเล็กน้อย เวลาจริงจะขึ้นอยู่กับระบบระยะไกล และระยะเวลาที่ใช้ในการเดินทางไป-กลับ โดยปกติแล้ว ค่าจะเหมือนกันสำหรับผู้ใช้ทั้งหมดของระบบระยะไกลหนึ่งๆ เว้นแต่ผู้ใช้บางส่วนจะอยู่ไกลพอที่จะเพิ่มเวลาในการตอบสนองไป-กลับ คุณสามารถใช้ฟีเจอร์การทำโปรไฟล์ Bazel เพื่อดูว่า Hit ของแคชโดยทั่วไปใช้เวลานานแค่ไหน

การดำเนินการแบบไดนามิกใช้ได้กับกลยุทธ์แซนด์บ็อกซ์ในเครื่องและผู้ปฏิบัติงานถาวร ผู้ปฏิบัติงานถาวรจะทำงานกับแซนด์บ็อกซ์โดยอัตโนมัติเมื่อใช้กับการดำเนินการแบบไดนามิก และจะใช้โปรแกรมทำงานแบบมัลติเพล็กซ์ไม่ได้ ในระบบของ Darwin และ Windows กลยุทธ์แซนด์บ็อกซ์อาจทำงานช้า คุณสามารถส่ง --reuse_sandbox_directories เพื่อลดค่าใช้จ่ายในการสร้างแซนด์บ็อกซ์ในระบบเหล่านี้

การดำเนินการแบบไดนามิกยังทํางานด้วยกลยุทธ์ standalone ได้ด้วย แต่เนื่องจากกลยุทธ์ standalone ต้องล็อกเอาต์พุตเมื่อเริ่มดําเนินการ จึงบล็อกกลยุทธ์ระยะไกลไม่ให้เสร็จสิ้นก่อนได้อย่างมีประสิทธิภาพ แฟล็ก --experimental_local_lockfree_output ช่วยให้แก้ปัญหานี้ได้โดยอนุญาตให้การดำเนินการในเครื่องเขียนไปยังเอาต์พุตโดยตรง แต่ล้มเลิกการดำเนินการระยะไกลหากการดำเนินการดังกล่าวเสร็จสิ้นก่อน

หากสาขาหนึ่งของการดำเนินการแบบไดนามิกเสร็จสิ้นก่อนแต่ดำเนินการไม่สำเร็จ การดำเนินการทั้งหมดจะล้มเหลว นี่เป็นทางเลือกที่ตั้งใจเพื่อป้องกันการสังเกตความแตกต่างระหว่างการดำเนินการในเครื่องและจากระยะไกล

สำหรับข้อมูลพื้นฐานเพิ่มเติมเกี่ยวกับวิธีการทำงานของการดำเนินการแบบไดนามิกและการล็อก โปรดดูบล็อกโพสต์ที่ยอดเยี่ยมของ JulioMerino

ฉันควรใช้การดำเนินการแบบไดนามิกเมื่อใด

การดำเนินการแบบไดนามิกต้องใช้ระบบการดำเนินการระยะไกลบางรูปแบบ ปัจจุบันยังไม่สามารถใช้ระบบระยะไกลที่เป็นแบบแคชเท่านั้นได้ เนื่องจากการไม่พบแคชจะถือว่าเป็นการดำเนินการที่ล้มเหลว

การดำเนินการบางประเภทไม่เหมาะกับการดำเนินการจากระยะไกล ตัวเลือกที่ดีที่สุดคือผู้ที่ทำงานรวดเร็วกว่าภายในเครื่อง เช่น ผ่านการใช้ผู้ปฏิบัติงานถาวร หรือผู้ที่ทำงานเร็วพอที่โอเวอร์เฮดของการดำเนินการจากระยะไกลจะส่งผลเวลาประมวลผล เนื่องจากการดำเนินการที่ดำเนินการในเครื่องแต่ละรายการจะล็อกทรัพยากร CPU และหน่วยความจำจำนวนหนึ่ง การดำเนินการที่ไม่อยู่ในหมวดหมู่ดังกล่าวจึงเป็นการหน่วงเวลาการดำเนินการสำหรับการดำเนินการดังกล่าวเท่านั้น

ตั้งแต่รุ่น 5.0.0-pre.20210708.4 การทำโปรไฟล์ประสิทธิภาพจะมีข้อมูลเกี่ยวกับการดำเนินการของผู้ปฏิบัติงาน รวมถึงเวลาที่ใช้ในการดำเนินการตามคำของานหลังจากแพ้การแข่งขันด้านการดำเนินการแบบไดนามิก หากเห็นว่าเทรดผู้ปฏิบัติงานที่ดำเนินการแบบไดนามิกต้องใช้เวลาอย่างมากในการรับทรัพยากร หรือใช้เวลานานใน async-worker-finish คุณอาจพบว่าการดำเนินการภายในเครื่องที่ช้าทำให้เทรดของผู้ปฏิบัติงานล่าช้า

การทำโปรไฟล์ข้อมูลมีประสิทธิภาพการดำเนินการแบบไดนามิกไม่ดี

ในโปรไฟล์ด้านบนซึ่งใช้ผู้ปฏิบัติงาน Javac 8 คน เราพบว่าผู้ปฏิบัติงาน Javac จำนวนมากแพ้การแข่งขันและทำงานในชุด async-worker-finish จนเสร็จ ปัญหานี้เกิดจากการที่ผู้ปฏิบัติงานจำไม่ได้ต้องใช้ทรัพยากรมากพอในการหน่วงเวลาผู้ปฏิบัติงาน

ทำโปรไฟล์ข้อมูลด้วยประสิทธิภาพการดำเนินการแบบไดนามิกที่ดียิ่งขึ้น

เมื่อ Javac เพียงอย่างเดียวที่เรียกใช้ด้วยการดำเนินการแบบไดนามิก มีเพียงประมาณครึ่งหนึ่งของผู้ปฏิบัติงานที่เริ่มแล้วเท่านั้นที่จะแพ้การแข่งขันหลังจากเริ่มทำงาน

เลิกใช้งานแฟล็ก --experimental_spawn_scheduler ที่แนะนำก่อนหน้านี้แล้ว โดยจะเปิดการดำเนินการแบบไดนามิกและกำหนดให้ dynamic เป็นกลยุทธ์เริ่มต้นสำหรับการช่วยจำทั้งหมด ซึ่งมักจะทำให้เกิดปัญหาประเภทนี้

การแสดง

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

--dynamic_local_execution_delay ทำให้การเริ่มต้น Branch ในเครื่องล่าช้าไปเป็นจำนวนมิลลิวินาทีหลังจากที่ Branch ระยะไกลเริ่มทำงานแล้ว แต่เฉพาะเมื่อมีการพบแคชระยะไกลในระหว่างบิลด์ปัจจุบันเท่านั้น ซึ่งทำให้บิลด์ที่ได้รับประโยชน์จากการแคชระยะไกลไม่ทำให้เสียทรัพยากรในเครื่องเมื่อมีแนวโน้มที่จะพบเอาต์พุตส่วนใหญ่ได้ในแคช การลดปัญหานี้อาจช่วยปรับปรุงความเร็วในการสร้างได้ ทั้งนี้ขึ้นอยู่กับคุณภาพของแคช ซึ่งจะช่วยลดการใช้ทรัพยากรในเครื่องมากขึ้น

--experimental_dynamic_local_load_factor เป็นตัวเลือกการจัดการทรัพยากรขั้นสูง แบบทดลอง ค่านี้ต้องใช้ค่าตั้งแต่ 0 ถึง 1 และ 0 เพื่อปิดฟีเจอร์นี้ เมื่อตั้งเป็นค่าที่มากกว่า 0 Bazel จะปรับจำนวนการดำเนินการที่กำหนดเวลาไว้ภายในเครื่องเมื่อมีการดำเนินการมากมายที่รอกำหนดเวลาอยู่ การตั้งค่าเป็น 1 จะช่วยให้กำหนดเวลาการดำเนินการได้มากเท่าที่มี CPU ที่ใช้ได้ (ตาม --local_cpu_resources) ค่าที่ต่ำกว่าจะกำหนดจำนวนการดำเนินการที่กำหนดเวลาไว้ให้น้อยลงตามไปด้วยเนื่องจากมีการดำเนินการที่พร้อมเรียกใช้เป็นจำนวนมาก นี่อาจฟังดูไม่สมเหตุสมผล แต่การมีระบบระยะไกลที่ดีจะทำให้การดำเนินการภายในเครื่องไม่ช่วยมากนักเมื่อมีการเรียกใช้การดำเนินการจำนวนมาก และ CPU ภายในเครื่องจะจัดการการดำเนินการระยะไกลได้ดีกว่า

--experimental_dynamic_slow_remote_time ให้ความสำคัญกับการเริ่มต้นสาขาในเครื่อง เมื่อ Branch ระยะไกลทำงานมานานเป็นอย่างน้อยแล้ว โดยปกติแล้ว การดำเนินการตามกำหนดการล่าสุดจะมีลำดับความสําคัญ เนื่องจากมีโอกาสมากที่สุดที่จะชนะการแข่งขัน แต่หากบางครั้งระบบระยะไกลค้างหรือใช้เวลานานมาก ก็อาจทําให้งานสร้างที่คืบหน้าไปได้ ฟีเจอร์นี้ไม่ได้เปิดใช้โดยค่าเริ่มต้น เนื่องจากอาจซ่อนปัญหาเกี่ยวกับระบบระยะไกลที่ควรได้รับการแก้ไข อย่าลืมตรวจสอบประสิทธิภาพของระบบระยะไกลหากคุณเปิดใช้ตัวเลือกนี้

สามารถใช้ --experimental_dynamic_ignore_local_signals เพื่อให้ Branch ระยะไกลทำงานแทนเมื่อมีการออกจากพื้นที่ที่สร้างขึ้นเองเนื่องจากมีสัญญาณที่กำหนด ฟีเจอร์นี้มีประโยชน์เป็นอย่างมากเมื่อใช้ร่วมกับขีดจำกัดทรัพยากรผู้ปฏิบัติงาน (ดู --experimental_worker_memory_limit_mb, --experimental_worker_sandbox_hardening และ --experimental_sandbox_memory_limit_mb)) ซึ่งอาจทำให้กระบวนการของพนักงานหยุดชะงักเมื่อใช้ทรัพยากรมากเกินไป

โปรไฟล์การติดตาม JSON มีกราฟเกี่ยวกับประสิทธิภาพจำนวนหนึ่งที่จะช่วยระบุวิธีปรับปรุงการแลกเปลี่ยนประสิทธิภาพและการใช้งานทรัพยากร

การแก้ปัญหา

ปัญหาเกี่ยวกับการดำเนินการแบบไดนามิกนั้นอาจเป็นปัญหาเล็กๆ น้อยๆ และแก้ไขข้อบกพร่องได้ยาก เนื่องจากปัญหาเหล่านี้จะเกิดขึ้นได้เฉพาะเมื่อใช้การดำเนินการภายในเครื่องร่วมกับการดำเนินการระยะไกลบางรายการเท่านั้น --debug_spawn_scheduler จะเพิ่มเอาต์พุตเพิ่มเติมจากระบบการดำเนินการแบบไดนามิกที่ช่วยแก้ไขข้อบกพร่องของปัญหาเหล่านี้ได้ คุณยังปรับแฟล็ก --dynamic_local_execution_delay และจำนวนงานระยะไกลกับงานในเครื่องได้ด้วย เพื่อให้ทำให้เกิดปัญหาซ้ำได้ง่ายขึ้น

หากพบปัญหาเกี่ยวกับการดำเนินการแบบไดนามิกโดยใช้กลยุทธ์ standalone ให้ลองเรียกใช้โดยไม่ใช้ --experimental_local_lockfree_output หรือเรียกใช้การกระทำเกี่ยวกับสถานที่โดยใช้แซนด์บ็อกซ์ ซึ่งอาจทำให้การสร้างของคุณช้าลงเล็กน้อย (ดูด้านบนหากคุณใช้ Mac หรือ Windows) แต่จะนำสาเหตุบางประการที่อาจทำให้ดำเนินการไม่สำเร็จออก