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

Báo cáo sự cố Xem nguồn

Trang này mô tả trình thực thi multiplex, cách viết quy tắc tương thích với multiplex và cách giải quyết một số giới hạn nhất định.

Trình thực thi Multiplex cho phép Bazel xử lý nhiều yêu cầu bằng một quy trình trình thực thi duy nhất. Đối với các trình thực thi đa luồng, Bazel có thể sử dụng ít tài nguyên hơn để đạt được hiệu suất tương đương hoặc tốt hơn. Ví dụ: thay vì có một quy trình cho mỗi trình thực thi, Bazel có thể có 4 trình thực thi ghép kênh trò chuyện với cùng một quy trình của trình thực thi, sau đó có thể xử lý song song các yêu cầu. Đối với các ngôn ngữ như Java và Scala, cách này giúp tiết kiệm thời gian khởi động JVM và thời gian biên dịch JIT, nói chung là cho phép sử dụng một bộ nhớ đệm dùng chung giữa tất cả cá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ố lệnh ghi nhớ có thể chạy song song các quy trình, 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 trình thực thi theo tuần tự cùng với request_id, quy trình này sẽ xử lý yêu cầu và gửi phản hồi cho 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 các phản hồi này trở lại đúng WorkerProxy. Cũng giống như với worker không được ghép kênh, mọi hoạt động giao tiếp đều được thực hiện qua quy trình nhập/xuất 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ị cho 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, gốc thực thi và bộ nhớ ghi nhớ) để xác định cần sử dụng WorkerMultiplexer nào. Các 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à gốc thực thi là giống nhau trong một lệnh gọi Bazel, thì mỗi ký tự ghi nhớ duy nhất chỉ có thể có một WorkerMultiplexer và một quy trình trình thực thi. Tổng số trình thực thi (bao gồm cả trình thực thi thông thường và WorkerProxy) vẫn bị giới hạn trong --worker_max_instances.

Viết quy tắc tương thích với multiplex

Quy trình trình thực thi của quy tắc phải đa luồng để tận dụng các trình thực thi Multiplex. Protobuf cho phép một bộ quy tắc phân tích cú pháp một yêu cầu ngay cả khi có thể có nhiều yêu cầu chồng chéo trong luồng. Bất cứ khi nào quy trình worker phân tích cú pháp yêu cầu từ luồng, nó 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 thực thi cần đảm bảo các phản hồi được viết tỉ mỉ (các thông báo không chồng chéo nhau). 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 multiplex

Trình thực thi Multiplex cần cẩn thận hơn khi xử lý đầu ra so với trình thực thi Multiplex. 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 cùng loại, được xen kẽ ngẫu nhiên giữa các yêu cầu đồng thời. Bạn nên chuyển hướng stdout vào stderr, nhưng đừng thu thập kết quả đó vào trường output của WorkResponse, vì điều này có thể cho thấy các phần đầu ra bị hỏng. Nếu công cụ của bạn chỉ gửi đầu ra dành cho người dùng đến stdout hoặc stderr, bạn cần thay đổi hành vi đó trước khi có thể bật multiplex worker.

Bật multiplex worker

Trình thực thi Multiplex không được bật theo mặc định. Một bộ quy tắc có thể bật trình thực thi multiplex bằng cách sử dụng thẻ supports-multiplex-workers trong execution_requirements của một hành động (tương tự như thẻ supports-workers cho phép các trình thực thi thông thường). Tương tự như khi sử dụng trình thực thi thông thường, bạn cần chỉ định chiến lược trình thực thi ở cấp bộ 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). Không cần gắn cờ bổ sung 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 multiplex worker trên toàn cầu bằng cách truyền --noworker_multiplex.

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

Hộp cát Multiplex

Trình thực thi Multiplex có thể được tạo hộp cát bằng cách thêm tuỳ chọn hỗ trợ rõ ràng cho lớp đó trong quá trình triển khai trình thực thi. Mặc dù bạn có thể thực hiện hộp cát của trình thực thi singleplex bằng cách chạy từng quy trình của trình thực thi trong hộp cát riêng, nhưng các trình thực thi multiplex lại chia sẻ thư mục đang làm việc 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, worker phải hỗ trợ đọc 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 của nó.

Để hỗ trợ hộp cát multiplex, worker phải sử dụng trường sandbox_dir từ WorkRequest và dùng trường đó làm tiền tố cho tất cả lượt đọc và ghi tệp. Mặc dù các trường argumentsinputs vẫn 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ế sẽ có liên quan đến sandbox_dir. Trình thực thi 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ả kết quả đầu ra liên quan đến sandbox_dir. Điều này bao gồm các đường dẫn như ".", cũng như các đường dẫn tìm thấy trong các tệp được chỉ định trong đối số (chẳng hạn như các đối số "argfile").

Sau khi một trình thực thi hỗ trợ hộp cát multiplex, tập hợp 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 Multiplex nếu cờ --experimental_worker_multiplex_sandboxing được truyền hoặc nếu worker này được dùng với chế độ thực thi động.

Tệp trình chạy của một trình thực thi multiplex có hộp cát vẫn tương ứng với thư mục làm việc của quy trình trình thực thi này. Do đó, nếu một tệp được dùng cho cả hai mục đích chạy trình thực thi và 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ố tệp cờ cũng như trong tools, executable hoặc runfiles.