Bazel rất phức tạp và thực hiện nhiều việc khác nhau trong quá trình tạo bản dựng, một số việc có thể ảnh hưởng đến hiệu suất bản dựng. Trang này cố gắng liên kết một số khái niệm Bazel với tác động của chúng đối với hiệu suất bản dựng. Mặc dù không toàn diện, nhưng chúng tôi đã đưa ra một số ví dụ về cách phát hiện vấn đề về hiệu suất bản dựng thông qua việc trích xuất các chỉ số và những việc bạn có thể làm để khắc phục vấn đề đó. Với thông tin này, chúng tôi hy vọng bạn có thể áp dụng các khái niệm này khi điều tra các trường hợp hiệu suất bản dựng bị giảm.
Bản dựng sạch so với bản dựng gia tăng
Bản dựng sạch là bản dựng tạo mọi thứ từ đầu, trong khi bản dựng gia tăng sử dụng lại một số công việc đã hoàn thành.
Bạn nên xem xét bản dựng sạch và bản dựng gia tăng riêng biệt, đặc biệt là khi bạn đang thu thập / tổng hợp các chỉ số phụ thuộc vào trạng thái của bộ nhớ đệm Bazel (ví dụ: chỉ số kích thước yêu cầu bản dựng ). Chúng cũng đại diện cho 2 trải nghiệm người dùng khác nhau. So với việc bắt đầu một bản dựng sạch từ đầu (mất nhiều thời gian hơn do bộ nhớ đệm lạnh), bản dựng gia tăng xảy ra thường xuyên hơn nhiều khi nhà phát triển lặp lại mã (thường nhanh hơn vì bộ nhớ đệm thường đã được làm nóng).
Bạn có thể sử dụng trường CumulativeMetrics.num_analyses trong BEP để phân loại
bản dựng. Nếu num_analyses <= 1, thì đó là bản dựng sạch; nếu không, chúng ta có thể phân loại rộng rãi
là bản dựng gia tăng – người dùng có thể đã chuyển sang
các cờ hoặc mục tiêu khác nhau, dẫn đến một bản dựng sạch hiệu quả. Bất kỳ
định nghĩa nghiêm ngặt nào khác về tính gia tăng có thể sẽ phải ở dạng
một phương pháp phỏng đoán, ví dụ: xem xét số lượng gói đã tải
(PackageMetrics.packages_loaded).
Chỉ số bản dựng xác định làm đại diện cho hiệu suất bản dựng
Việc đo lường hiệu suất bản dựng có thể khó khăn do tính chất không xác định của một số chỉ số (ví dụ: thời gian CPU của Bazel hoặc thời gian xếp hàng trên một cụm từ xa ). Do đó, bạn có thể hữu ích khi sử dụng các chỉ số xác định làm đại diện cho lượng công việc mà Bazel thực hiện, từ đó ảnh hưởng đến hiệu suất của Bazel.
Kích thước của yêu cầu bản dựng có thể có tác động đáng kể đến hiệu suất bản dựng. Bản dựng lớn hơn có thể đại diện cho nhiều công việc hơn trong việc phân tích và tạo biểu đồ bản dựng. Sự tăng trưởng tự nhiên của bản dựng diễn ra một cách tự nhiên cùng với quá trình phát triển, khi có thêm/tạo thêm nhiều phần phụ thuộc, do đó, độ phức tạp tăng lên và chi phí tạo bản dựng cũng tăng lên.
Chúng ta có thể chia vấn đề này thành nhiều giai đoạn tạo bản dựng và sử dụng các chỉ số sau làm chỉ số đại diện cho công việc được thực hiện ở mỗi giai đoạn:
PackageMetrics.packages_loaded: số lượng gói đã tải thành công. Trường hợp hiệu suất giảm ở đây đại diện cho nhiều công việc hơn cần thực hiện để đọc và phân tích cú pháp từng tệp BUILD bổ sung trong giai đoạn tải.TargetMetrics.targets_configured: đại diện cho số lượng mục tiêu và khía cạnh được định cấu hình trong bản dựng. Trường hợp hiệu suất giảm đại diện cho nhiều công việc hơn trong việc tạo và duyệt qua biểu đồ mục tiêu được cấu hình.- Điều này thường là do việc thêm các phần phụ thuộc và phải tạo biểu đồ bao đóng bắc cầu của chúng.
- Sử dụng cquery để tìm vị trí có thể đã thêm các phần phụ thuộc mới.
ActionSummary.actions_created: đại diện cho các hành động được tạo trong bản dựng, và trường hợp hiệu suất giảm đại diện cho nhiều công việc hơn trong việc tạo biểu đồ hành động. Xin lưu ý rằng điều này cũng bao gồm các hành động không dùng đến có thể chưa được thực thi.- Sử dụng aquery để gỡ lỗi các trường hợp hiệu suất giảm;
bạn nên bắt đầu bằng
--output=summarytrước khi đi sâu hơn bằng--skyframe_state.
- Sử dụng aquery để gỡ lỗi các trường hợp hiệu suất giảm;
bạn nên bắt đầu bằng
ActionSummary.actions_executed: số lượng hành động được thực thi, trường hợp hiệu suất giảm trực tiếp đại diện cho nhiều công việc hơn trong việc thực thi các hành động này.- BEP ghi ra số liệu thống kê về hành động
ActionDatacho biết các loại hành động được thực thi nhiều nhất. Theo mặc định, BEP thu thập 20 loại hành động hàng đầu, nhưng bạn có thể truyền--experimental_record_metrics_for_all_mnemonicsđể thu thập dữ liệu này cho tất cả các loại hành động đã được thực thi. - Điều này sẽ giúp bạn tìm ra loại hành động nào đã được thực thi (ngoài ra).
- BEP ghi ra số liệu thống kê về hành động
BuildGraphSummary.outputArtifactCount: số lượng cấu phần phần mềm do các hành động được thực thi tạo ra.- Nếu số lượng hành động được thực thi không tăng, thì có khả năng là quá trình triển khai quy tắc đã bị thay đổi.
Các chỉ số này đều bị ảnh hưởng bởi trạng thái của bộ nhớ đệm cục bộ, do đó, bạn cần đảm bảo rằng các bản dựng mà bạn trích xuất các chỉ số này là bản dựng sạch.
Chúng tôi nhận thấy rằng trường hợp hiệu suất giảm ở bất kỳ chỉ số nào trong số này đều có thể đi kèm với trường hợp hiệu suất giảm về thời gian thực, thời gian CPU và mức sử dụng bộ nhớ.
Mức sử dụng tài nguyên cục bộ
Bazel sử dụng nhiều tài nguyên trên máy cục bộ của bạn (cả để phân tích biểu đồ bản dựng và thúc đẩy quá trình thực thi, cũng như để chạy các hành động cục bộ). Điều này có thể ảnh hưởng đến hiệu suất / khả năng sử dụng của máy trong việc thực hiện bản dựng và các tác vụ khác.
Thời gian đã đi
Có lẽ các chỉ số dễ bị nhiễu nhất (và có thể thay đổi đáng kể từ bản dựng
sang bản dựng) là thời gian; đặc biệt là thời gian thực, thời gian CPU và thời gian hệ thống. Bạn có thể
sử dụng bazel-bench để lấy
điểm chuẩn cho các chỉ số này và với số lượng --runs đủ, bạn có thể
tăng ý nghĩa thống kê của phép đo.
Thời gian thực là thời gian thực đã trôi qua.
- Nếu chỉ thời gian thực giảm, bạn nên thu thập hồ sơ dấu vết JSON và tìm sự khác biệt. Nếu không, có lẽ sẽ hiệu quả hơn khi điều tra các chỉ số giảm khác vì chúng có thể đã ảnh hưởng đến thời gian thực.
Thời gian CPU là thời gian CPU dành để thực thi mã người dùng.
- Nếu thời gian CPU giảm trên 2 lần xác nhận dự án, bạn nên thu thập
hồ sơ CPU Starlark. Bạn cũng nên sử dụng
--nobuildđể giới hạn bản dựng ở giai đoạn phân tích vì đó là nơi thực hiện hầu hết công việc nặng về CPU.
- Nếu thời gian CPU giảm trên 2 lần xác nhận dự án, bạn nên thu thập
hồ sơ CPU Starlark. Bạn cũng nên sử dụng
Thời gian hệ thống là thời gian CPU dành cho kernel.
- Nếu thời gian hệ thống giảm, thì thời gian này chủ yếu tương quan với I/O khi Bazel đọc tệp từ hệ thống tệp của bạn.
Lập hồ sơ tải trên toàn hệ thống
Khi sử dụng cờ
--experimental_collect_load_average_in_profiler
được giới thiệu trong Bazel 6.0, trình lập hồ sơ dấu vết JSON sẽ thu thập
mức tải trung bình của hệ thống trong quá trình gọi.

Hình 1. Hồ sơ bao gồm mức tải trung bình của hệ thống.
Mức tải cao trong quá trình gọi Bazel có thể là dấu hiệu cho thấy Bazel lên lịch
quá nhiều hành động cục bộ song song cho máy của bạn. Bạn có thể muốn xem xét việc điều chỉnh
--local_cpu_resources
và --local_ram_resources,
đặc biệt là trong môi trường vùng chứa (ít nhất là cho đến khi
#16512 được hợp nhất).
Giám sát mức sử dụng bộ nhớ của Bazel
Có 2 nguồn chính để lấy mức sử dụng bộ nhớ của Bazel, Bazel info và
BEP.
bazel info used-heap-size-after-gc: Lượng bộ nhớ đã sử dụng tính bằng byte sau khi gọiSystem.gc().- Bazel bench cũng cung cấp điểm chuẩn cho chỉ số này.
- Ngoài ra, còn có
peak-heap-size,max-heap-size,used-heap-sizevàcommitted-heap-size(xem tài liệu), nhưng ít liên quan hơn.
BEP’s
MemoryMetrics.peak_post_gc_heap_sizecủa BEP: Kích thước của kích thước vùng nhớ heap JVM cao nhất tính bằng byte sau GC (yêu cầu đặt--memory_profileđể cố gắng buộc thực hiện GC đầy đủ).
Trường hợp hiệu suất giảm về mức sử dụng bộ nhớ thường là kết quả của trường hợp hiệu suất giảm về các chỉ số kích thước yêu cầu bản dựng, thường là do việc thêm các phần phụ thuộc hoặc thay đổi trong quá trình triển khai quy tắc.
Để phân tích mức sử dụng bộ nhớ của Bazel ở mức chi tiết hơn, bạn nên sử dụng trình lập hồ sơ bộ nhớ tích hợp cho các quy tắc.
Lập hồ sơ bộ nhớ của trình thực thi liên tục
Mặc dù trình thực thi liên tục có thể giúp tăng tốc đáng kể quá trình tạo bản dựng (đặc biệt là đối với các ngôn ngữ được diễn giải), nhưng mức sử dụng bộ nhớ của chúng có thể
gây ra vấn đề. Bazel thu thập các chỉ số về trình thực thi của mình, đặc biệt là trường
WorkerMetrics.WorkerStats.worker_memory_in_kb cho biết lượng bộ nhớ mà
trình thực thi sử dụng (theo mnemonic).
Trình lập hồ sơ dấu vết JSON cũng
thu thập mức sử dụng bộ nhớ của trình thực thi liên tục trong quá trình gọi bằng cách truyền cờ
--experimental_collect_system_network_usage (mới trong Bazel 6.0).

Hình 2. Hồ sơ bao gồm mức sử dụng bộ nhớ của trình thực thi.
Việc giảm giá trị của
--worker_max_instances
(mặc định là 4) có thể giúp giảm
lượng bộ nhớ mà trình thực thi liên tục sử dụng. Chúng tôi đang tích cực làm việc để giúp trình quản lý tài nguyên và trình lên lịch của Bazel thông minh hơn, để bạn ít phải tinh chỉnh như vậy hơn trong tương lai.
Giám sát lưu lượng truy cập mạng cho bản dựng từ xa
Trong quá trình thực thi từ xa, Bazel tải xuống các cấu phần phần mềm được tạo do thực thi các hành động. Do đó, băng thông mạng có thể ảnh hưởng đến hiệu suất của bản dựng.
Nếu đang sử dụng tính năng thực thi từ xa cho bản dựng, bạn có thể cân nhắc
giám sát lưu lượng truy cập mạng trong quá trình gọi bằng cách sử dụng
NetworkMetrics.SystemNetworkStats proto từ BEP
(yêu cầu truyền --experimental_collect_system_network_usage).
Hơn nữa, hồ sơ dấu vết JSON
cho phép bạn xem mức sử dụng mạng trên toàn hệ thống trong suốt quá trình tạo bản dựng
bằng cách truyền cờ --experimental_collect_system_network_usage (mới trong Bazel
6.0).

Hình 3. Hồ sơ bao gồm mức sử dụng mạng trên toàn hệ thống.
Mức sử dụng mạng cao nhưng khá ổn định khi sử dụng tính năng thực thi từ xa có thể cho biết
rằng mạng là nút thắt cổ chai trong bản dựng của bạn; nếu chưa sử dụng,
hãy cân nhắc bật tính năng Tạo bản dựng mà không cần byte bằng cách truyền
--remote_download_minimal.
Điều này sẽ giúp tăng tốc bản dựng bằng cách tránh tải xuống các cấu phần phần mềm trung gian không cần thiết.
Một lựa chọn khác là định cấu hình bộ nhớ đệm trên đĩa cục bộ để tiết kiệm băng thông tải xuống.