Multiplex Worker (Tính năng thử nghiệm)

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

Trang này mô tả các worker đa năng, cách viết quy tắc tương thích với nhiều luồng và giải pháp cho một số hạn chế nhất định.

Trình chạy nhiều luồng cho phép Bazel xử lý nhiều yêu cầu bằng một quy trình trình chạy duy nhất. Đối với các worker nhiều luồng, Bazel có thể sử dụng ít tài nguyên hơn để đạt được hiệu suất tương tự hoặc tốt hơn. Ví dụ: thay vì có một quy trình worker cho mỗi worker, Bazel có thể có 4 worker được đa kênh hoá giao tiếp với cùng một quy trình worker, sau đó có thể xử lý các yêu cầu song song. Đối với các ngôn ngữ như Java và Scala, việc này giúp tiết kiệm thời gian khởi động JVM và thời gian biên dịch JIT, đồng thời nói chung cho phép sử dụng một bộ nhớ đệm dùng chung giữa tất cả worker cùng loại.

Tổng quan

Có hai lớp giữa máy chủ Bazel và quy trình worker. Đối với một số ký hiệu mnemonics nhất định có thể chạy các quy trình song song, Bazel sẽ nhận được WorkerProxy từ nhóm worker. WorkerProxy chuyển tiếp các yêu cầu đến quy trình worker theo tuần tự cùng với request_id, quy trình worker xử lý yêu cầu và gửi phản hồi đến WorkerMultiplexer. Khi nhận được phản hồi, WorkerMultiplexer sẽ phân tích cú pháp request_id, sau đó chuyển tiếp phản hồi trở lại WorkerProxy chính xác. Giống như với các worker không đa kênh, tất cả hoạt động giao tiếp đều được thực hiện qua phương thức truyền/nhận tiêu chuẩn, nhưng công cụ này không thể chỉ sử dụng stderr cho đầu ra hiển thị với người dùng (xem bên dưới).

Mỗi worker có một khoá. Bazel sử dụng mã băm của khoá (bao gồm các biến môi trường, thư mục gốc thực thi và câu thần chú) để xác định WorkerMultiplexer nào sẽ sử dụng. WorkerProxy giao tiếp với cùng một WorkerMultiplexer nếu chúng có cùng một mã băm. Do đó, giả sử các biến môi trường và thư mục gốc thực thi giống nhau trong một lệnh gọi Bazel, thì mỗi câu thần chú duy nhất chỉ có thể có một WorkerMultiplexer và một quy trình worker. Tổng số worker, bao gồm cả worker thông thường và WorkerProxy, vẫn bị giới hạn bởi --worker_max_instances.

Viết quy tắc tương thích với nhiều kênh

Quy trình worker của quy tắc phải có nhiều luồng để tận dụng các worker đa kênh. Protobuf cho phép một quy tắc phân tích cú pháp một yêu cầu duy nhất, mặc dù có thể có nhiều yêu cầu đang xếp chồng trong luồng. Bất cứ khi nào quy trình worker phân tích cú pháp một yêu cầu từ luồng, quy trình đó sẽ xử lý yêu cầu trong một luồng mới. Vì nhiều luồng có thể hoàn tất và ghi vào luồng cùng một lúc, nên quy trình worker cần đảm bảo các phản hồi được ghi một cách nguyên tử (các thông báo không chồng chéo). Phản hồi phải chứa request_id của yêu cầu mà chúng đang xử lý.

Xử lý đầu ra đa kênh

Worker đa kênh cần cẩn thận hơn trong việc xử lý đầu ra so với worker đơn kênh. Mọi nội dung được gửi đến stderr sẽ chuyển vào một tệp nhật ký duy nhất được chia sẻ giữa tất cả WorkerProxy thuộc cùng một loại, được xen kẽ ngẫu nhiên giữa các yêu cầu đồng thời. Mặc dù bạn nên chuyển hướng stdout vào stderr, nhưng đừng thu thập đầu ra đó vào trường output của WorkResponse, vì điều đó có thể cho người dùng thấy các phần đầu ra bị xáo trộn. Nếu công cụ của bạn chỉ gửi đầu ra hướng người dùng đến stdout hoặc stderr, thì bạn sẽ cần thay đổi hành vi đó trước khi có thể bật trình chạy đa kênh.

Bật worker đa kênh

Theo mặc định, worker Multiplex không được bật. Một bộ quy tắc có thể bật worker đa kênh bằng cách sử dụng thẻ supports-multiplex-workers trong execution_requirements của một thao tác (giống như thẻ supports-workers bật worker thông thường). Giống như trường hợp sử dụng worker thông thường, bạn cần chỉ định một chiến lược worker, ở cấp quy tắc (ví dụ: --strategy=[some_mnemonic]=worker) hoặc thường ở cấp chiến lược (ví dụ: --dynamic_local_strategy=worker,standalone). Bạn không cần thêm cờ nào và supports-multiplex-workers sẽ được ưu tiên hơn supports-workers nếu bạn đặt cả hai. Bạn có thể tắt trình chạy đa năng trên toàn cục bằng cách truyền --noexperimental_worker_multiplex.

Bạn nên sử dụng quy tắc để sử dụng trình chạy đa kênh nếu có thể, nhằm giảm áp lực bộ nhớ và cải thiện hiệu suất. Tuy nhiên, các worker đa kênh hiện không tương thích với tính năng thực thi động, trừ phi các worker này triển khai tính năng hộp cát đa kênh. Việc cố gắng chạy worker đa kênh không có hộp cát bằng phương thức thực thi động sẽ âm thầm sử dụng worker đơn kênh có hộp cát.

Chạy trong môi trường hộp cát Multiplex

Bạn có thể đưa worker Multiplex vào hộp cát bằng cách thêm tính năng hỗ trợ tường minh cho worker đó trong quá trình triển khai worker. Mặc dù bạn có thể tạo hộp cát cho worker đơn bằng cách chạy từng quy trình worker trong hộp cát riêng, nhưng worker đa kênh sẽ chia sẻ thư mục hoạt động của quy trình giữa nhiều yêu cầu song song. Để cho phép hộp cát của các worker đa kênh, worker phải hỗ trợ việc đọc từ và ghi vào một thư mục con được chỉ định trong mỗi yêu cầu, thay vì trực tiếp trong thư mục đang hoạt động.

Để hỗ trợ hộp cát đa năng, worker phải sử dụng trường sandbox_dir từ WorkRequest và sử dụng trường đó làm tiền tố cho tất cả các hoạt động đọc và ghi tệp. Mặc dù các trường argumentsinputs không thay đổi so với yêu cầu không có hộp cát, nhưng dữ liệu đầu vào thực tế lại liên quan đến sandbox_dir. Worker phải dịch các đường dẫn tệp có trong argumentsinputs để đọc từ đường dẫn đã sửa đổi này, đồng thời phải ghi tất cả đầu ra tương ứng với sandbox_dir. Điều này bao gồm các đường dẫn như ".", cũng như các đường dẫn có trong các tệp được chỉ định trong đối số (chẳng hạn như đối số "argfile").

Sau khi một worker hỗ trợ tính năng hộp cát đa kênh, quy tắc có thể khai báo tính năng hỗ trợ này bằng cách thêm supports-multiplex-sandboxing vào execution_requirements của một hành động. Sau đó, Bazel sẽ sử dụng hộp cát đa kênh nếu cờ --experimental_worker_multiplex_sandboxing được truyền hoặc nếu worker được sử dụng với phương thức thực thi động.

Các tệp worker của worker đa kênh trong hộp cát vẫn tương ứng với thư mục đang hoạt động của quy trình worker. Do đó, nếu một tệp được dùng cả để chạy worker và làm dữ liệu đầu vào, thì bạn phải chỉ định tệp đó làm dữ liệu đầu vào trong đối số flagfile cũng như trong tools, executable hoặc runfiles.