Phân tích hiệu suất bản dựng

Báo cáo vấn đề Xem nguồn Hằng đêm · 7.3 · 7.2 · 7.1 · 7 · 6,5

Bazel rất phức tạp và thực hiện rất nhiều việc trong suốt một quá trình xây dựng, một số tính năng có thể ảnh hưởng đến hiệu suất của bản dựng. Trang này cố gắng liên kết một số khái niệm Bazel này liên quan đến tác động của chúng đối với hiệu suất bản dựng. Trong khi Tuy nhiên, chúng tôi đã đưa vào một số ví dụ về cách phát hiện hiệu suất bản dựng thông qua trích xuất chỉ số và những gì bạn có thể làm để khắc phục chúng. Bằng cách 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 nghiên cứu hồi quy hiệu suất bản dựng.

Bản dựng sạch so với Bản dựng tăng dần

Bản dựng sạch là bản dựng có thể xây dựng mọi thứ từ đầu, trong khi bản dựng tăng dần sẽ sử dụng lại một số công việc đã hoàn thành.

Bạn nên xem xét riêng các bản dựng sạch và tăng dần, đặc biệt 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 của Bazel (ví dụ: chỉ số về kích thước của yêu cầu bản dựng ). Chúng cũng đại diện cho hai trải nghiệm người dùng khác nhau. So với khi 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 nguội), tăng dần các bản dựng xảy ra thường xuyên hơn nhiều khi nhà phát triển lặp lại trên mã (thường nhanh hơn vì bộ nhớ đệm thường đã 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 là num_analyses <= 1, thì đó là một bản dựng sạch; nếu không, chúng tôi có thể mở rộng phân loại nó thành một bản dựng tăng dần – người dùng có thể đã chuyển đổi cho các cờ khác nhau hoặc các mục tiêu khác nhau, nhờ đó tạo ra bản dựng sạch một cách hiệu quả. Bất kỳ hạng nào bạn có thể sẽ phải đưa ra định nghĩa nghiêm ngặt hơn về mức độ gia tăng của phương pháp phỏng đoán, ví dụ: xem xét số lượng gói được tải (PackageMetrics.packages_loaded).

Chỉ số bản dựng mang tính quyết định dùng làm proxy cho hiệu suất của bản dựng

Việc đo lường hiệu suất của 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ố nhất định (ví dụ: thời gian CPU của Bazel hoặc thời gian xếp hàng trên một chiếc điều khiển từ xa cụm). Do đó, bạn nên sử dụng chỉ số xác định làm proxy cho khối lượng công việc mà Bazel thực hiện, do đó cũng ảnh hưởng đến hiệu suất của công cụ.

Kích thước của yêu cầu bản dựng có thể ảnh hưởng đáng kể đến bản dựng hiệu suất. Bản dựng lớn hơn có thể giúp bạn phân tích và phân tích nhiều hơn để tạo biểu đồ bản dựng. Số lượng công trình tăng lên tự nhiên quá trình phát triển, vì ngày càng nhiều phần phụ thuộc được thêm vào/tạo ra, do đó ngày càng phức tạp và trở nên tốn kém hơn khi xây dựng.

Chúng ta có thể chia vấn đề này thành nhiều giai đoạn xây dựng và sử dụng làm chỉ số đại diện cho công việc được hoàn thành ở mỗi giai đoạn:

  1. PackageMetrics.packages_loaded: số lượng gói đã tải thành công. Sự hồi quy ở đây cho thấy cần phải làm nhiều việc hơn để đọc và phân tích cú pháp mỗi tệp BUILD bổ sung trong giai đoạn tải.

    • Điều này thường là do việc thêm các phần phụ thuộc và phải tải các phần phụ thuộc đóng bắc cầu.
    • Sử dụng query / cquery để tìm có thể đã thêm các phần phụ thuộc mới.
  2. TargetMetrics.targets_configured: đại diện cho số lượng mục tiêu và các khía cạnh được định cấu hình trong bản dựng. Sự hồi quy cho thấy bạn cần làm nhiều việc hơn tạo và truyền tải biểu đồ mục tiêu đã định 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 xây dựng đồ thị đóng cửa bắc cầu của chúng.
    • Sử dụng cquery để tìm vị trí mới có thể đã được thêm vào.
  3. ActionSummary.actions_created: đại diện cho các thao tác được tạo trong bản dựng, và hồi quy cho thấy bạn phải tốn nhiều công sức hơn trong việc xây dựng biểu đồ hành động. Ghi chú bao gồm cả những hành động không được sử dụng nhưng có thể chưa được thực thi.

  4. ActionSummary.actions_executed: số lượng thao tác được thực thi, một hồi quy trực tiếp thể hiện trực tiếp nhiều công việc hơn trong việc thực thi các hành động này.

    • BEP viết số liệu thống kê hành động ActionData cho thấy những loại thao tác được thực thi nhiều nhất. Theo mặc định, thu thập 20 loại hành động hàng đầu, nhưng bạn có thể chuyển vào --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 xác định những loại hành động đã được thực thi (bổ sung).
  5. BuildGraphSummary.outputArtifactCount: số lượng cấu phần phần mềm được tạo bởi các hành động đã được thực thi.

    • Nếu số lượng hành động được thực thi không tăng thì có khả năng đã thay đổi triển khai quy tắc.

Tất cả các chỉ số này đều chịu ảnh hưởng của trạng thái của bộ nhớ đệm cục bộ, do đó bạn sẽ muố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 bản dựng sạch.

Chúng tôi nhận thấy rằng sự hồi quy của bất kỳ chỉ số nào trong số này có thể đi kèm với hồi quy theo thời gian thực, thời gian CPU và mức sử dụng bộ nhớ.

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ả hai đều dành cho việc phân tích biểu đồ bản dựng và thúc đẩy hoạt động thực thi cũng như để chạy các hành động liên quan đến địa điểm thực tế), có thể ảnh hưởng đến hiệu suất / khả năng sử dụng của máy tính trong việc thực hiện tạo bản dựng và các nhiệm vụ khác.

Thời gian trên đường mòn

Có lẽ các chỉ số dễ bị ảnh hưởng nhất bởi nhiễu (và có thể thay đổi đáng kể so với bản dựng để xây dựng) là thời gian; cụ thể – thời gian chờ, thời gian CPU và thời gian hệ thống. Bạn có thể sử dụng bazel-bench để có đ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 kết quả đo lường.

  • Giờ tường là thời gian thực đã trôi qua.

    • Nếu chỉ thời gian thực tế giảm, bạn nên thu thập Hồ sơ theo dõi JSON và tìm kiếm cho sự khác biệt. Nếu không, có thể sẽ hiệu quả hơn nếu điều tra các chỉ số hồi quy khác vì chúng có thể ảnh hưởng đến tường bất cứ lúc nào.
  • Thời gian của CPU là thời gian để CPU thực thi mã người dùng.

    • Nếu thời gian CPU hồi quy qua 2 lần cam kết dự án, bạn nên thu thập hồ sơ CPU Starlark. Bạn cũng nên dùng --nobuild để nên hạn chế việc tạo bản dựng ở giai đoạn phân tích, vì đó là giai đoạn mà hầu hết Đã xử lý xong công việc nặng nhọc về CPU.
  • Thời gian hệ thống là thời gian mà CPU sử dụng trong nhân.

    • Nếu thời gian hệ thống hồi quy, nó chủ yếu tương quan với I/O khi Bazel đọc khỏi hệ thống tệp của bạn.

Lập hồ sơ tải trên toàn hệ thống

Sử dụng --experimental_collect_load_average_in_profiler cờ được giới thiệu trong Bazel 6.0, Trình phân tích dấu vết JSON thu thập hệ thống trung bình tải trong khi gọi.

Hồ sơ bao gồm mức trung bình tải của hệ thống

Hình 1. Hồ sơ bao gồm mức trung bình tải của hệ thống.

Mức tải cao trong lệnh gọi Bazel có thể là một chỉ báo rằng Bazel lên lịch có quá nhiều hành động cục bộ song song cho máy của bạn. Bạn nên xem xét đang điều chỉnh --local_cpu_resources--local_ram_resources, đặc biệt là trong môi trường vùng chứa (ít nhất là cho đến #16512 được hợp nhất).

Giám sát mức sử dụng bộ nhớ Bazel

Có hai nguồn chính để sử dụng bộ nhớ của Bazel, đó là Bazel infoBEP.

  • bazel info used-heap-size-after-gc: Dung lượng bộ nhớ đã sử dụng tính bằng byte sau khi một lệnh gọi đến System.gc().

    • Ghế băng bazel 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-sizecommitted-heap-size (xem tài liệu), nhưng ít liên quan hơn.
  • BEP MemoryMetrics.peak_post_gc_heap_size: Kích thước của kích thước vùng nhớ khối xếp JVM cao nhất trong byte sau GC (yêu cầu cài đặt --memory_profile cố gắng buộc GC đầy đủ).

Sự hồi quy về mức sử dụng bộ nhớ thường là kết quả của sự hồi quy theo chỉ số về 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 quy tắc trong quá trình triển khai.

Để 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 phân tích bộ nhớ tích hợp sẵn cho các quy tắc.

Phân tích bộ nhớ của worker liên tục

Mặc dù trình thực thi liên tục có thể giúp tăng tốc các bản dựng đáng kể (đặc biệt là đối với các ngôn ngữ thông dịch) mức sử dụng bộ nhớ của các em có thể có vấn đề. Bazel thu thập các chỉ số về nhân viên của mình, cụ thể là Trường WorkerMetrics.WorkerStats.worker_memory_in_kb cho biết dung lượng bộ nhớ mà nhân viên sử dụng (theo ghi nhớ).

Trình phân tích dấu vết JSON cũng thu thập mức sử dụng bộ nhớ của worker liên tục trong khi gọi bằng cách truyền giá trị --experimental_collect_system_network_usage cờ (mới trong Bazel 6.0).

Hồ sơ bao gồm mức sử dụng bộ nhớ của worker

Hình 2. Hồ sơ bao gồm mức sử dụng bộ nhớ của worker.

Giảm giá trị của --worker_max_instances (mặc định là 4) có thể giúp giảm mức bộ nhớ mà worker liên tục sử dụng. Chúng tôi đang tích cực nghiên cứu giúp trình quản lý tài nguyên và trình lập lịch biểu của Bazel trở nên thông minh hơn để có thể tinh chỉnh sẽ được yêu cầu ít thường xuyên hơn trong tương lai.

Giám sát lưu lượng truy cập mạng cho các 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 xây dựng nhờ 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 các 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 Proto NetworkMetrics.SystemNetworkStats từ BEP (yêu cầu truyền --experimental_collect_system_network_usage).

Ngoài ra, hồ sơ theo dõi 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 (tính năng mới trong Bazel 6.0).

Cấu hình bao gồm việc sử dụng mạng trên toàn hệ thống

Hình 3. Cấu hình bao gồm hoạt động 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 dùng tính năng thực thi từ xa có thể cho biết mạng đó chính là điểm tắc nghẽn trong bản dựng của bạn; nếu bạn chưa sử dụng, hãy xem xét bật Build không có Byte bằng cách chuyển --remote_download_minimal. Việc này sẽ tăng tốc các bản dựng bằng cách tránh tải các cấu phần phần mềm trung gian không cần thiết xuống.

Một cách khác là định cấu hình bộ nhớ đệm của ổ đĩa để lưu vào băng thông tải xuống.