Bazel นั้นซับซ้อนและทำสิ่งต่างๆ ได้มากมายตลอดการสร้าง ซึ่งบางอย่างอาจมีผลต่อประสิทธิภาพการทำงาน หน้านี้พยายามแมป แนวคิดบางส่วนของ Bazel เกี่ยวกับผลกระทบต่อประสิทธิภาพบิลด์ ขณะที่ ไม่ได้ครอบคลุมกรณีใดๆ เราได้รวมตัวอย่างบางส่วนของวิธีตรวจหาประสิทธิภาพของบิลด์ ปัญหาผ่านการดึงข้อมูลเมตริก และวิธีแก้ไข เราหวังว่าคุณจะนำแนวคิดเหล่านี้ไปใช้ เมื่อตรวจสอบการถดถอยของประสิทธิภาพของบิลด์
บิลด์ที่สะอาดเทียบกับบิลด์ที่เพิ่มขึ้น
บิลด์ที่สะอาดตาคือบิลด์ที่สร้างทุกอย่างขึ้นมาใหม่ได้ ทั้งหมดในขณะที่ นำงานที่ทำเสร็จแล้วบางส่วนมาใช้ซ้ำ
เราขอแนะนำให้ดูบิลด์ที่เพิ่มขึ้นและสะอาดแยกกัน โดยเฉพาะเมื่อ ที่คุณกำลังรวบรวม / รวบรวมเมตริกที่ขึ้นอยู่กับสถานะของ แคชของ Bazel (ตัวอย่างเช่น เมตริกขนาดคำขอสร้าง ) อื่นๆ และยังแสดงถึงประสบการณ์ของผู้ใช้ 2 แบบที่แตกต่างกัน เมื่อเทียบกับการเริ่มต้น การสร้างใหม่ทั้งหมดตั้งแต่ต้น (ซึ่งใช้เวลานานกว่าเนื่องจาก Cold Cache) เพิ่ม เกิดขึ้นบ่อยครั้งกว่าที่นักพัฒนาซอฟต์แวร์ทำซ้ำโค้ด (โดยทั่วไปคือ เนื่องจากแคชมักจะร้อนอยู่แล้ว)
คุณสามารถใช้ฟิลด์ CumulativeMetrics.num_analyses
ใน BEP เพื่อจัดประเภท
งานสร้าง หากเป็น num_analyses <= 1
แสดงว่าเป็นบิลด์ที่สะอาด ไม่เช่นนั้น เราสามารถ
จัดหมวดหมู่ให้เป็นบิลด์ที่เพิ่มขึ้น - ผู้ใช้อาจเปลี่ยน
กับ Flag หรือเป้าหมายที่แตกต่างกัน ทำให้เกิดการสร้างที่สะอาดตาอย่างมีประสิทธิภาพ ช่วง
คำนิยามของส่วนเพิ่มที่เข้มงวดขึ้น
มักจะต้องมีรูปแบบ
ของการเรียนรู้ เช่น การดูจำนวนแพ็กเกจที่โหลด
(PackageMetrics.packages_loaded
)
เมตริกบิลด์เชิงกำหนดเป็นตัวแทนสำหรับประสิทธิภาพของบิลด์
การวัดผลประสิทธิภาพของบิลด์อาจทำได้ยากเนื่องจากมีลักษณะที่ไม่ได้กำหนด เมตริกบางรายการ (เช่น เวลา CPU ของ Bazel หรือเวลาในคิวบนรีโมต คลัสเตอร์) ด้วยเหตุนี้ การใช้เมตริกเชิงกำหนดเป็นพร็อกซีสำหรับ จำนวนผลงานที่ Bazel ทำ ซึ่งก็ส่งผลต่อประสิทธิภาพการทำงาน
ขนาดของคำขอบิลด์อาจมีนัยสำคัญอย่างยิ่งต่อบิลด์ ด้านประสิทธิภาพ งานสร้างที่ใหญ่ขึ้นอาจแสดงถึงงานด้านการวิเคราะห์และ ในการสร้างกราฟบิลด์ การเติบโตแบบออร์แกนิกของสิ่งที่สร้างขึ้นนั้นมาพร้อมกับ เมื่อมีการเพิ่ม/สร้างทรัพยากร Dependency มากขึ้น จึงทำให้ความซับซ้อนเพิ่มมากขึ้น และมีราคาแพงขึ้น
เราสามารถแบ่งปัญหานี้ออกเป็นระยะต่างๆ ของบิลด์ และใช้รายการต่อไปนี้ เป็นเมตริกพร็อกซีสำหรับงานที่ทำในแต่ละระยะ ดังนี้
PackageMetrics.packages_loaded
: จำนวนแพ็กเกจที่โหลดสำเร็จ การถดถอยนี้แสดงถึงงานอื่นๆ ที่ต้องทำให้เสร็จเพื่ออ่านและแยกวิเคราะห์ ไฟล์ BUILD เพิ่มเติมแต่ละไฟล์ในระยะการโหลดTargetMetrics.targets_configured
: แสดงจำนวนเป้าหมายและ ด้านต่างๆ ที่กำหนดค่าไว้ในบิลด์ การถดถอยแสดงถึงงานเพิ่มเติมใน สร้างและข้ามผ่านกราฟเป้าหมายที่กำหนดค่าไว้- กรณีนี้มักเกิดจากการเพิ่มทรัพยากร Dependency และจำเป็นต้องสร้าง กราฟการปิดแบบสกรรม
- ใช้ cquery เพื่อค้นหาตำแหน่งใหม่ อาจมีการเพิ่มทรัพยากร Dependency แล้ว
ActionSummary.actions_created
: แสดงการดำเนินการที่สร้างในบิลด์ และการถดถอยแสดงถึงงานที่มากขึ้นในการสร้างกราฟการทำงาน หมายเหตุ จะรวมถึงการดำเนินการที่ไม่ได้ใช้ซึ่งอาจไม่ได้ดำเนินการด้วย- ใช้ aquery เพื่อแก้ไขข้อบกพร่องการเกิดปัญหาซ้ำ
เราขอแนะนำให้เริ่มต้นด้วย
--output=summary
ก่อนที่จะดูข้อมูลเจาะลึกเพิ่มเติม--skyframe_state
- ใช้ aquery เพื่อแก้ไขข้อบกพร่องการเกิดปัญหาซ้ำ
เราขอแนะนำให้เริ่มต้นด้วย
ActionSummary.actions_executed
: จำนวนการดำเนินการที่ทำ การถดถอยจะหมายถึงการทำงานที่มากขึ้นในการดำเนินการเหล่านี้โดยตรง- BEP จะเขียนสถิติการกระทำ
ActionData
ที่แสดงประเภทการดำเนินการที่ดำเนินการมากที่สุด โดยค่าเริ่มต้น จะรวบรวมประเภทการดำเนินการ 20 อันดับแรก แต่คุณสามารถส่ง--experimental_record_metrics_for_all_mnemonics
เพื่อรวบรวมข้อมูลนี้สำหรับการดำเนินการทุกประเภทที่ได้ดำเนินการ - ข้อมูลนี้จะช่วยให้คุณทราบว่าระบบได้ดำเนินการประเภทใดไปแล้วบ้าง (เพิ่มเติม)
- BEP จะเขียนสถิติการกระทำ
BuildGraphSummary.outputArtifactCount
: จำนวนอาร์ติแฟกต์ที่สร้างโดย การดำเนินการที่ดำเนินการไปแล้ว- หากจำนวนของการดำเนินการที่ไม่เพิ่มขึ้น อาจเป็นไปได้ว่า มีการเปลี่ยนแปลงการใช้กฎ
เมตริกเหล่านี้ได้รับผลกระทบจากสถานะแคชในเครื่องทั้งหมด ดังนั้นคุณจะต้อง ต้องการตรวจสอบว่าบิลด์ที่คุณแยกเมตริกเหล่านี้ออกมา บิลด์สะอาด
เราพบว่าการถดถอยในเมตริกเหล่านี้อาจมาพร้อมกับ การเกิดปัญหาซ้ำเกี่ยวกับเวลาจริง เวลา CPU และการใช้งานหน่วยความจำ
การใช้ทรัพยากรในเครื่อง
Bazel ใช้ทรัพยากรมากมายในเครื่องของคุณ (ทั้งสำหรับการวิเคราะห์ กราฟบิลด์และการขับเคลื่อนการดำเนินการ และการเรียกใช้การกระทำเกี่ยวกับสถานที่) อาจส่งผลต่อประสิทธิภาพ / ความพร้อมใช้งานของเครื่องของคุณในการดำเนินการ และงานอื่นๆ ได้ด้วย
เวลาที่ใช้
บางทีเมตริกที่เสี่ยงต่อสัญญาณรบกวนมากที่สุด (และอาจแตกต่างกันไปตามรุ่น
คือเวลาที่เหมาะสม โดยเฉพาะอย่างยิ่ง เวลาใช้งานจริง เวลา CPU และเวลาของระบบ คุณสามารถ
ใช้ bazel-bench เพื่อ
การเปรียบเทียบสำหรับเมตริกเหล่านี้ และเมื่อมี --runs
จำนวนมากพอ คุณจะสามารถ
เพิ่มนัยสำคัญทางสถิติของการวัด
เวลากำแพง คือเวลาที่ผ่านไปในชีวิตจริง
- หากเวลาการแสดงผลถดถอยเท่านั้น เราขอแนะนําให้รวบรวม โปรไฟล์การติดตาม JSON และการดู เพื่อดูความแตกต่าง มิฉะนั้น การใช้ ให้ตรวจสอบเมตริกอื่นๆ ที่เกิดปัญหาซ้ำเนื่องจากเมตริกดังกล่าวอาจส่งผลต่อการจำกัดการเข้าชม
เวลาของ CPU คือเวลาที่ CPU ใช้งานโค้ดผู้ใช้
- หากเวลา CPU ถดถอยจากการคอมมิต 2 โปรเจ็กต์ เราขอแนะนำให้รวบรวม
โปรไฟล์ CPU ของ Starlark และคุณควรใช้
--nobuild
ด้วยเพื่อ จำกัดบิลด์ให้อยู่ในระยะการวิเคราะห์เนื่องจากเป็นส่วนที่ ใช้ CPU หนักมากแล้ว
- หากเวลา CPU ถดถอยจากการคอมมิต 2 โปรเจ็กต์ เราขอแนะนำให้รวบรวม
โปรไฟล์ CPU ของ Starlark และคุณควรใช้
เวลาของระบบคือเวลาที่ CPU ในเคอร์เนลใช้
- หากเวลาของระบบถดถอย ส่วนใหญ่จะสัมพันธ์กับ I/O เมื่อ Bazel อ่าน จากระบบไฟล์ของคุณ
การทำโปรไฟล์ภาระงานทั้งระบบ
การใช้
--experimental_collect_load_average_in_profiler
ที่เปิดตัวใน Bazel 6.0
เครื่องมือสร้างโปรไฟล์การติดตาม JSON จะรวบรวม
ค่าเฉลี่ยการโหลดของระบบในระหว่างการเรียกใช้
รูปที่ 1 โปรไฟล์ที่มีค่าเฉลี่ยการโหลดของระบบ
ภาระงานที่เพิ่มขึ้นระหว่างการเรียกใช้ Bazel อาจบ่งชี้ว่า Bazel กำหนดเวลา
มีการทำงานในเครื่องพร้อมกันสำหรับเครื่องของคุณมากเกินไป คุณอาจต้องดูข้อมูลเกี่ยวกับ
กำลังปรับ
--local_cpu_resources
และ --local_ram_resources
โดยเฉพาะในสภาพแวดล้อมคอนเทนเนอร์ (อย่างน้อยจนถึง
ผสาน #16512 แล้ว)
การตรวจสอบการใช้งานหน่วยความจำ Bazel
ดูข้อมูลการใช้งานหน่วยความจำของ Bazel ได้จาก 2 แหล่งที่มาหลัก ได้แก่ Bazel info
และ
BEP
bazel info used-heap-size-after-gc
: จำนวนหน่วยความจำที่ใช้ในหน่วยไบต์หลังผ่านไป โทรหาSystem.gc()
- ม้านั่งบาเซล ให้ตัวเปรียบเทียบสำหรับเมตริกนี้ด้วย
- นอกจากนี้ยังมี
peak-heap-size
max-heap-size
used-heap-size
และcommitted-heap-size
(โปรดดู เอกสารประกอบ) แต่ ไม่ค่อยเกี่ยวข้อง
ของ BEP
MemoryMetrics.peak_post_gc_heap_size
: ขนาดของฮีป JVM สูงสุดใน ไบต์หลัง GC (ต้องตั้งค่า--memory_profile
ที่พยายามบังคับให้ GC เต็มรูปแบบ)
การใช้หน่วยความจำถดถอยมักเป็นผลมาจากการถดถอยใน สร้างเมตริกขนาดคำขอ ซึ่งมักเกิดจากการเพิ่มทรัพยากร Dependency หรือมีการเปลี่ยนแปลงกฎ การใช้งานของคุณ
หากต้องการวิเคราะห์การใช้หน่วยความจำของ Bazel ในระดับที่ละเอียดยิ่งขึ้น เราขอแนะนำให้ใช้ เครื่องมือสร้างโปรไฟล์หน่วยความจำในตัว สำหรับกฎต่างๆ
การทำโปรไฟล์หน่วยความจำของผู้ปฏิบัติงานถาวร
ในขณะที่ผู้ปฏิบัติงานอย่างต่อเนื่องสามารถช่วยเร่งการสร้างได้
อย่างมาก (โดยเฉพาะภาษาที่แปลโดยอินเทอร์พรีเตอร์) ร่องรอยความทรงจำ
สร้างปัญหาได้ Bazel รวบรวมเมตริกเกี่ยวกับผู้ปฏิบัติงาน โดยเฉพาะ
ฟิลด์ WorkerMetrics.WorkerStats.worker_memory_in_kb
บอกจำนวนหน่วยความจำ
ที่ผู้ปฏิบัติงานใช้ (ตามความสามารถในการจำ)
เครื่องมือสร้างโปรไฟล์การติดตาม JSON ยัง
เก็บรวบรวมการใช้งานหน่วยความจำของผู้ปฏิบัติงานถาวรระหว่างการเรียกใช้โดยการส่งผ่าน
--experimental_collect_system_network_usage
(ใหม่ใน Bazel 6.0)
รูปที่ 2 โปรไฟล์ที่มีการใช้งานหน่วยความจำของผู้ปฏิบัติงาน
การลดค่าของ
--worker_max_instances
(ค่าเริ่มต้น 4) อาจช่วย
ปริมาณหน่วยความจำที่ผู้ปฏิบัติงานถาวรใช้ เรากำลังพัฒนาอย่างต่อเนื่อง
ทำให้ตัวจัดการทรัพยากรและเครื่องจัดตารางเวลาของ Bazel ฉลาดขึ้น ซึ่งทำให้การปรับแต่ง
จะไม่ค่อยเกิดขึ้นในอนาคต
การตรวจสอบการจราจรของข้อมูลในเครือข่ายสำหรับบิลด์ระยะไกล
ในการดำเนินการระยะไกล Bazel จะดาวน์โหลดอาร์ติแฟกต์ที่สร้างขึ้นจาก ด้วยเหตุนี้ แบนด์วิดท์ของเครือข่ายอาจส่งผลต่อประสิทธิภาพการทำงาน ของงานสร้างของคุณ
หากใช้การดำเนินการระยะไกลสำหรับบิลด์ คุณอาจต้องพิจารณา
การตรวจสอบการจราจรของข้อมูลในเครือข่ายระหว่างการเรียกใช้โดยใช้
NetworkMetrics.SystemNetworkStats
Proto จาก BEP
(ต้องผ่าน --experimental_collect_system_network_usage
)
นอกจากนี้ โปรไฟล์การติดตาม JSON
ช่วยให้คุณดูการใช้งานเครือข่ายทั้งระบบได้ตลอดช่วงบิลด์
ด้วยการติดธง --experimental_collect_system_network_usage
(ใหม่ใน Bazel
6.0)
รูปที่ 3 โปรไฟล์ที่มีการใช้งานเครือข่ายทั้งระบบ
การใช้งานเครือข่ายระดับสูงแต่ค่อนข้างแบนเมื่อใช้การดำเนินการจากระยะไกลอาจบ่งชี้ว่า
เครือข่ายนั้นเป็นจุดคอขวดในบิลด์ของคุณ ถ้าคุณยังไม่ได้ใช้งาน
ลองเปิด Build โดยไม่มีไบต์ด้วยการข้าม
--remote_download_minimal
ซึ่งจะช่วยให้งานสร้างของคุณเร็วขึ้นโดยหลีกเลี่ยงการดาวน์โหลดอาร์ติแฟกต์ระดับกลางที่ไม่จำเป็น
อีกตัวเลือกหนึ่งคือการกำหนดค่า แคชดิสก์เพื่อบันทึกไว้ แบนด์วิดท์การดาวน์โหลด