Tính năng thực thi linh độ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 và huỷ nhánh còn lại. Tính năng 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 những lợi ích 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 tính năng thực thi linh động. Nếu bạn đã thiết lập cả quá trình thực thi cục bộ và từ xa, đồng thời đang cố gắng điều chỉnh các chế độ cài đặt Bazel để có hiệu suất tốt hơn, thì trang này là dành cho bạn. Nếu bạn chưa thiết lập quá trình thực thi từ xa, hãy chuyển đến phần Tổng quan về tính năng thực thi từ xa của Bazel trước.
Bật tính năng thực thi linh động?
Mô-đun thực thi linh động là một phần của Bazel, nhưng để sử dụng tính năng thực thi linh động, bạn phải có khả năng biên dịch cả cục bộ và từ xa từ cùng một thiết lập Bazel.
Để bật mô-đun thực thi linh động, hãy truyền --internal_spawn_scheduler
cờ đến 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. Giờ đây, bạn có thể
sử dụng chiến lược này cho các từ viết tắt mà bạn muốn chạy một cách linh động, chẳng hạn như
--strategy=Javac=dynamic. Hãy xem phần tiếp theo để biết cách chọn từ viết tắt
để bật tính năng thực thi linh động.
Đối với bất kỳ từ viết tắt nào sử dụng chiến lược linh động, các chiến lược thực thi từ xa sẽ được
lấy từ cờ --dynamic_remote_strategy và các chiến lược cục bộ từ cờ
--dynamic_local_strategy. Việc truyền
--dynamic_local_strategy=worker,sandboxed sẽ đặt giá trị mặc định cho nhánh cục bộ
của quá trình thực thi linh động để thử với các worker hoặc quá trình thực thi trong hộp cát theo thứ tự đó. Việc truyền --dynamic_local_strategy=Javac=worker chỉ ghi đè giá trị mặc định cho
từ viết tắt Javac. Phiên bản từ xa hoạt động theo cách tương tự. Bạn có thể chỉ định cả hai cờ
nhiều lần. Nếu một thao tác không thể thực thi cục bộ, thì thao tác đó sẽ được
thực thi từ xa như bình thường và ngược lại.
Nếu hệ thống từ xa của bạn có bộ nhớ đệm, thì cờ --dynamic_local_execution_delay sẽ thêm một độ 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 đã cho biết có một lượt truy cập bộ nhớ đệm. Điều này giúp tránh chạy quá trình thực thi cục bộ khi có nhiều lượt truy cập bộ nhớ đệm. Giá trị mặc định là 1000 mili giây, nhưng nên điều chỉnh để chỉ dài hơn một chút
so với thời gian truy cập bộ nhớ đệm. Thời gian thực tế phụ thuộc vào cả hệ thống từ xa
và thời gian khứ hồi. Thông thường, giá trị sẽ giống nhau
đối với 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 ở đủ xa
để thêm độ trễ khứ hồi. Bạn có thể sử dụng các tính năng lập hồ sơ Bazel để xem thời gian truy cập bộ nhớ đệm thông thường.
Bạn có thể sử dụng tính năng thực thi linh động với chiến lược hộp cát cục bộ cũng như với
các worker liên tục. Các worker liên tục sẽ tự động
chạy với tính năng hộp cát khi được sử dụng với tính năng thực thi linh động và không thể sử dụng các worker đa hợp. Trên hệ thống Darwin và Windows, chiến lược hộp cát
có thể chậm; bạn có thể truyền --reuse_sandbox_directories để giảm
chi phí tạo hộp cát trên các hệ thống này.
Tính năng thực thi linh độ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 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ỷ bỏ nếu quá trình đó hoàn tất trước.
Nếu một trong các nhánh của quá trình thực thi linh động hoàn tất trước nhưng bị lỗi, thì toàn bộ thao tác sẽ bị lỗi. Đây là một lựa chọn có chủ ý để ngăn chặn sự khác biệt giữa quá trình thực thi cục bộ và từ xa mà không bị bỏ qua.
Để 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 linh động và tính năng khoá của tính năng này, hãy xem các bài đăng xuất sắc trên blog của Julio Merino
Khi nào nên sử dụng tính năng thực thi linh động?
Tính năng thực thi linh động yêu cầu một số dạng 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ì lỗi bộ nhớ đệm sẽ được coi là một thao tác không thành công.
Không phải tất cả các loại thao tác đều phù hợp với quá trình thực thi từ xa. Các ứng cử viên tốt nhất là những ứng cử viên vốn nhanh hơn cục bộ, chẳng hạn như thông qua việc sử dụng các worker liên tục, hoặc những ứng cử viên chạy đủ nhanh để chi phí thực thi từ xa chiếm ưu thế về thời gian thực thi. Vì mỗi thao tác được thực thi cục bộ sẽ khoá một lượng tài nguyên CPU và bộ nhớ, nên việc chạy các thao tác không thuộc các danh mục đó chỉ làm chậm quá trình thực thi đối với những thao tác thuộc các danh mục đó.
Kể từ bản phát hành
5.0.0-pre.20210708.4,
tính năng lập hồ sơ 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
thua cuộc đua thực thi linh động. Nếu bạn thấy các luồng worker thực thi linh động
dành nhiều thời gian để thu thập tài nguyên hoặc nhiều thời gian trong
async-worker-finish, thì có thể bạn có một số thao tác cục bộ chậm làm chậm các luồng worker.
Trong hồ sơ ở trên, sử dụng 8 worker Javac, chúng ta thấy nhiều worker Javac
đã thua cuộc đua và hoàn tất công việc của họ trên các async-worker-finish
luồng. Điều này là do một từ viết tắt không phải worker chiếm đủ tài nguyên để
làm chậm các worker.
Khi chỉ chạy Javac với tính năng thực thi linh động, chỉ có khoảng một nửa số worker đã bắt đầu bị thua cuộc đua sau khi bắt đầu công việc.
Cờ --experimental_spawn_scheduler được đề xuất trước đó không còn được dùng nữa.
Cờ này 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ả các
từ viết tắt, điều này 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 có sẵn cục bộ và từ xa để đáng để chi thêm một số tài nguyên nhằm cải thiện hiệu suất tổng thể. Tuy nhiên, việc sử dụng quá nhiều tài nguyên có thể làm chậm chính Bazel hoặc máy chạy Bazel, hoặc gây áp lực không mong muốn lên hệ thống từ xa. Có một số cách để thay đổi hành vi của tính năng thực thi linh động:
--dynamic_local_execution_delay trì hoãn việc bắt đầu một nhánh cục bộ theo một số
mili giây sau khi nhánh từ xa đã bắt đầu, nhưng chỉ khi có
một lượt truy cập 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 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ó khả năng tìm thấy hầu hết các
đầu ra trong bộ nhớ đệm. Tuỳ thuộc vào chất lượng của bộ nhớ đệm,
việc giảm giá trị này có thể cải thiện tốc độ xây dựng, nhưng phải trả giá bằng việc sử dụng nhiều tài nguyên cục bộ
hơn.
--experimental_dynamic_local_load_factor là một lựa chọn nâng cao thử nghiệm về quản lý tài nguyên. Giá trị này có thể từ 0 đến 1, 0 tắt tính năng này.
Khi được đặt thành một giá trị trên 0, Bazel sẽ điều chỉnh số lượng
thao tác được lên lịch cục bộ khi có nhiều thao tác đ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 thao tác như có
CPU (theo --local_cpu_resources). Các giá trị thấp hơn đặt số lượng
thao tác được lên lịch tương ứng ít hơn khi có nhiều thao tác hơn để
chạy. Điều này có thể nghe có vẻ phản trực giác, nhưng với một hệ thống từ xa tốt
, quá trình thực thi cục bộ không giúp ích nhiều khi nhiều thao tác đang được chạy và
CPU cục bộ được sử dụng tốt 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, thao tác được lên lịch gần đây nhất sẽ được ưu tiên, vì thao tác này có cơ hội chiến thắng cuộc đua cao nhất, nhưng nếu hệ thống từ xa đôi khi bị treo hoặc mất nhiều thời gian hơn, thì thao tác này có thể giúp bản dựng di chuyển. Tính năng này không được bật theo mặc định, vì tính năng này
có thể ẩn các vấn đề với hệ thống từ xa mà đáng lẽ phải được khắc phục. Hãy nhớ
theo dõi hiệu suất hệ thống từ xa nếu bạn bật lựa 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 khi kết hợp với giới hạn tài nguyên worker (xem
--experimental_worker_memory_limit_mb,
--experimental_worker_sandbox_hardening,
và
--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ố biểu đồ liên quan đến hiệu suất có thể giúp xác định cách cải thiện sự đánh đổi giữa hiệu suất và mức sử dụng tài nguyên.
Khắc phục sự cố
Các vấn đề với tính năng thực thi linh động có thể khó phát hiện và gỡ lỗi, vì chúng có thể
chỉ xuất hiện trong một số tổ hợp cụ thể của quá trình thực thi cục bộ và từ xa.
The --debug_spawn_scheduler thêm đầu ra bổ sung từ hệ thống thực thi linh độ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 tạo các vấn đề.
Nếu bạn gặp vấn đề với tính năng thực thi linh động bằng chiến lược standalone
, hãy thử chạy mà không có --experimental_local_lockfree_output hoặc chạy
các thao tác 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 sử dụng Mac hoặc Windows), nhưng sẽ loại bỏ một số nguyên nhân có thể gây ra lỗi.