Thực thi động

Báo cáo vấn đề Xem nguồn Nightly · 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

Thực thi động là một tính năng trong Bazel, trong đó quá trình thực thi cục bộ và từ xa của cùng một thao tác được bắt đầu song song, sử dụng đầu ra từ nhánh đầu tiên đã hoàn tất, huỷ bỏ nhánh còn lại. Công cụ này kết hợp sức mạnh thực thi và/hoặc bộ nhớ đệm dùng chung lớn của hệ thống xây dựng từ xa với độ trễ thấp của quá trình thực thi cục bộ, mang lại hiệu quả tốt nhất cho cả bản dựng sạch và bản dựng tăng dần.

Trang này mô tả cách bật, điều chỉnh và gỡ lỗi thực thi linh động. Nếu bạn đã thiết lập cả quá trình thực thi cục bộ lẫn từ xa, đồng thời đang cố gắng điều chỉnh Bazel để có hiệu suất tốt hơn, trang này là dành cho bạn. Nếu bạn chưa có thiết lập thực thi từ xa, hãy chuyển đến Bazel Remote Execution Tổng quan trước tiên.

Bật tính năng thực thi động?

Mô-đun thực thi động là một phần của Bazel, nhưng để sử dụng mô-đun động , bạn phải có khả năng biên dịch cả trên máy và từ xa cùng một cách thiết lập Bazel.

Để bật mô-đun thực thi động, hãy truyền cờ --internal_spawn_scheduler vào Bazel. Thao tác này sẽ thêm một chiến lược thực thi mới có tên là dynamic. Bạn có thể làm điều này ngay bây giờ hãy dùng chiến lược này làm chiến lược giúp ghi nhớ mà bạn muốn chạy linh hoạt, chẳng hạn như --strategy=Javac=dynamic. Xem phần tiếp theo để biết cách chọn những bộ nhớ để bật tính năng thực thi động.

Đối với bất kỳ ghi nhớ nào sử dụng chiến lược động, chiến lược thực thi từ xa được lấy từ cờ --dynamic_remote_strategy và các chiến lược cục bộ từ Cờ --dynamic_local_strategy. Cầu thủ chuyền bóng --dynamic_local_strategy=worker,sandboxed đặt làm chế độ mặc định cho nhánh thực thi động để thử với trình thực thi hoặc thực thi hộp cát trong đó đơn đặt hàng. Việc truyền --dynamic_local_strategy=Javac=worker sẽ ghi đè giá trị mặc định chỉ dành cho ký hiệu Javac. Phiên bản từ xa cũng hoạt động theo cách tương tự. Cả hai cờ đều có thể được chỉ định nhiều lần. Nếu không thể thực thi một thao tác trên máy, thì thao tác đó sẽ thực thi từ xa như bình thường và ngược lại.

Nếu hệ thống từ xa có bộ nhớ đệm, cờ --dynamic_local_execution_delay thêm độ trễ tính bằng mili giây vào quá trình thực thi cục bộ sau khi hệ thống từ xa biểu thị một kết quả tìm kiếm trong bộ nhớ đệm. Điều này giúp tránh chạy phương thức thực thi cục bộ khi có thêm số lượt truy cập vào bộ nhớ đệm rất có thể. Giá trị mặc định là 1000 mili giây, nhưng bạn nên điều chỉnh để chỉ lâu hơn một chút so với thời gian truy cập vào bộ nhớ đệm thông thường. Thời gian thực tế phụ thuộc vào cả điều khiển từ xa và thời gian của một chuyến đi khứ hồi. Thông thường, giá trị này sẽ giống nhau cho tất cả người dùng của một hệ thống từ xa nhất định, trừ phi một số người dùng ở quá xa để tăng độ trễ trọn vòng. Bạn có thể sử dụng tính năng lập hồ sơ Bazel để xem thông tin về thời lượng truy cập bộ nhớ đệm.

Bạn có thể sử dụng tính năng thực thi động với chiến lược hộp cát cục bộ cũng như với worker ổn định. Worker ổn định sẽ tự động chạy trong hộp cát khi được sử dụng với phương thức thực thi động và không thể sử dụng worker đa kênh. Trên các hệ thống Darwin và Windows, hộp cát chiến lược có thể chậm; bạn có thể chuyển --reuse_sandbox_directories để giảm mức hao tổn tạo hộp cát trên các hệ thống này.

Quá trình thực thi động cũng có thể chạy với chiến lược standalone, mặc dù chiến lược standalone phải lấy khoá đầu ra khi bắt đầu thực thi, nhưng chiến lược này sẽ chặn hiệu quả chiến lược từ xa hoàn tất trước. Cờ --experimental_local_lockfree_output cho phép giải quyết vấn đề này bằng cách cho phép quá trình thực thi cục bộ ghi trực tiếp vào đầu ra, nhưng bị quá trình thực thi từ xa huỷ nếu quá trình thực thi cục bộ kết thúc trước.

Nếu một trong các nhánh của quá trình thực thi động kết thúc trước nhưng không thành công, thì sẽ không thể thực hiện toàn bộ thao tác. Đây là một lựa chọn có chủ ý để ngăn chặn sự khác biệt giữa việc thực thi cục bộ và từ xa.

Để biết thêm thông tin cơ bản về cách hoạt động của tính năng thực thi động và tính năng khoá, hãy xem các bài đăng trên blog tuyệt vời của Julio Merino

Khi nào nên sử dụng tính năng thực thi động?

Quá trình thực thi động yêu cầu một số hình thức hệ thống thực thi từ xa. Hiện tại, bạn không thể sử dụng hệ thống từ xa chỉ có bộ nhớ đệm, vì việc thiếu bộ nhớ đệm sẽ được coi là một thao tác không thành công.

Không phải loại thao tác nào cũng phù hợp để thực thi từ xa. Tốt nhất ứng viên là những đề xuất vốn đã nhanh hơn cục bộ, chẳng hạn như thông qua việc sử dụng nhân viên liên tục hoặc những nhân viên chạy nhanh đủ để mức hao tổn thực thi từ xa ảnh hưởng đến thời gian thực thi. Từ mỗi hành động được thực thi cục bộ sẽ khoá một số tài nguyên CPU và bộ nhớ, các hành động đang chạy không thuộc các danh mục đó chỉ trì hoãn việc thực thi cho những người có hiệu suất đó.

Kể từ bản phát hành 5.0.0-pre.20210708.4, phân tích hiệu suất chứa dữ liệu về quá trình thực thi worker, bao gồm cả thời gian hoàn tất yêu cầu công việc sau khi mất một cuộc đua thực thi động. Nếu thấy các luồng thực thi động tốn nhiều thời gian để thu nạp tài nguyên hoặc tốn nhiều thời gian trong async-worker-finish, thì có thể một số thao tác cục bộ bị chậm sẽ làm chậm các luồng worker.

Dữ liệu phân tích tài nguyên có hiệu suất thực thi động kém

Trong hồ sơ sử dụng 8 worker Java, chúng ta thấy có nhiều worker Java đã thua cuộc đua và hoàn thành công việc của mình ở async-worker-finish luồng. Nguyên nhân là do một câu thần chú không phải worker chiếm đủ tài nguyên để làm chậm worker.

Dữ liệu phân tích tài nguyên có hiệu suất thực thi động tốt hơn

Khi chỉ chạy Javac bằng phương thức thực thi động, chỉ khoảng một nửa số worker đã bắt đầu mới kết thúc cuộc đua sau khi bắt đầu công việc.

Cờ --experimental_spawn_scheduler được đề xuất trước đây không còn được dùng nữa. Thao tác này sẽ bật tính năng thực thi linh động và đặt dynamic làm chiến lược mặc định cho tất cả người dùng ghi nhớ, vốn thường dẫn đến các loại vấn đề này.

Hiệu suất

Phương pháp thực thi linh động giả định rằng có đủ tài nguyên trên thiết bị và từ xa rằng bạn nên đầu tư thêm một số tài nguyên để cải thiện hiệu suất tổng thể. Tuy nhiên, việc sử dụng tài nguyên quá mức có thể làm chậm chính Bazel hoặc máy tính đó chạy hay tạo áp lực không mong muốn lên một hệ thống từ xa. Có một số tuỳ chọn để thay đổi hành vi của quá trình thực thi động:

--dynamic_local_execution_delay trì hoãn việc bắt đầu một nhánh cục bộ trong một số mili giây sau khi nhánh từ xa bắt đầu, nhưng chỉ khi có lượt truy cập vào bộ nhớ đệm từ xa trong bản dựng hiện tại. Điều này giúp các bản dựng được hưởng lợi từ tính năng lưu vào bộ nhớ đệm từ xa không lãng phí tài nguyên cục bộ khi có thể tìm thấy hầu hết đầu ra trong bộ nhớ đệm. Tuỳ thuộc vào chất lượng của bộ nhớ đệm, nhưng việc giảm tốc độ này có thể cải thiện tốc độ xây dựng, nhưng đổi lại bạn sẽ phải dùng nhiều của chúng tôi.

--experimental_dynamic_local_load_factor là một tuỳ chọn quản lý tài nguyên nâng cao thử nghiệm. Giá trị này có giá trị từ 0 đến 1, 0 là tắt tính năng này. Khi được đặt thành một giá trị lớn hơn 0, Bazel sẽ điều chỉnh số lượng hành động được lên lịch cục bộ khi có nhiều hành động đang chờ được lên lịch. Việc đặt giá trị này thành 1 cho phép lên lịch nhiều hành động nhất có thể khi có sẵn CPU (theo --local_cpu_resources). Các giá trị thấp hơn sẽ đặt số lượng hành động được lên lịch tương ứng ít hơn khi có nhiều hành động hơn có thể chạy. Điều này có vẻ như trái với trực giác, nhưng với một hệ thống từ xa tốt, việc thực thi cục bộ không giúp ích nhiều khi nhiều thao tác đang chạy và CPU cục bộ sẽ được sử dụng hiệu quả hơn để quản lý các thao tác từ xa.

--experimental_dynamic_slow_remote_time ưu tiên bắt đầu các nhánh cục bộ khi nhánh từ xa đã chạy ít nhất trong thời gian này. Thông thường hành động được lên lịch gần đây nhất sẽ được ưu tiên, vì nó có khả năng cao nhất giành chiến thắng trong cuộc đua, nhưng nếu hệ thống từ xa đôi khi bị treo hoặc mất nhiều thời gian hơn, để có được một bản dựng phù hợp. Chế độ này không được bật theo mặc định vì có thể ẩn các vấn đề với hệ thống từ xa mà bạn cần khắc phục. Hãy nhớ giám sát hiệu suất của hệ thống từ xa nếu bạn bật tuỳ chọn này.

Bạn có thể sử dụng --experimental_dynamic_ignore_local_signals để cho phép nhánh từ xa tiếp quản khi một quá trình tạo cục bộ thoát do một tín hiệu nhất định. Điều này chủ yếu hữu ích cùng với các giới hạn tài nguyên của worker (xem --experimental_worker_memory_limit_mb, --experimental_worker_sandbox_hardening--experimental_sandbox_memory_limit_mb), trong đó các quy trình worker có thể bị huỷ khi sử dụng quá nhiều tài nguyên.

Hồ sơ theo dõi JSON chứa một số đồ thị liên quan đến hiệu suất có thể giúp xác định các cách cải thiện hiệu suất và mức sử dụng tài nguyên.

Khắc phục sự cố

Các vấn đề liên quan đến tính năng thực thi linh động có thể rất khó phát hiện và khó gỡ lỗi vì có thể chỉ có thể thực thi theo một số tổ hợp cụ thể giữa quá trình thực thi cục bộ và thực thi từ xa. --debug_spawn_scheduler thêm kết quả bổ sung từ quá trình thực thi động có thể giúp gỡ lỗi các vấn đề này. Bạn cũng có thể điều chỉnh cờ --dynamic_local_execution_delay và số lượng công việc từ xa so với công việc cục bộ để dễ dàng tái hiện các sự cố hơn.

Nếu bạn gặp sự cố khi thực thi động bằng chiến lược standalone, hãy thử chạy mà không cần --experimental_local_lockfree_output hoặc chạy các hành động cục bộ trong hộp cát. Điều này có thể làm chậm bản dựng của bạn một chút (xem ở trên nếu bạn đang dùng máy Mac hoặc Windows) nhưng sẽ xoá một số nguyên nhân có thể gây ra lỗi.