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

Báo cáo vấn đề Xem nguồn Nightly/3}

Trang này mô tả trình thực thi Multiplex, cách viết các quy tắc tương thích với Multiplex và giải pháp cho một số hạn chế 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 worker duy nhất. Đối với các worker đa 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 cho mỗi worker, Bazel có thể có 4 worker đa kênh trao đổi với cùng một quy trình worker, 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, phương pháp này giúp tiết kiệm thời gian khởi động JVM và thời gian biên dịch JIT. Nhìn chung, công cụ này 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ó 2 lớp giữa máy chủ Bazel và quy trình worker. Đối với một số bộ 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 worker theo tuần tự cùng với request_id, quy trình worker này sẽ 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 rồi chuyển tiếp các phản hồi đó trở lại WorkerProxy chính xác. Tương tự như với các worker không đa kênh, mọi hoạt động giao tiếp đều được thực hiện qua phương thức vào/ra tiêu chuẩn, nhưng công cụ này không thể chỉ sử dụng stderr cho đầu ra mà người dùng có thể nhìn thấy (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à trình ghi nhớ) để xác định WorkerMultiplexer cần dùng. WorkerProxy sẽ giao tiếp với cùng một WorkerMultiplexer nếu 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 lệnh ghi nhớ duy nhất chỉ có thể có một WorkerMultiplexer và một quy trình thực thi. 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 Multiplex

Quy trình trình thực thi của quy tắc phải là đa luồng để tận dụng nhiều trình thực thi. Protobuf cho phép bộ quy tắc phân tích cú pháp một yêu cầu mặc dù 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 một yêu cầu trong luồng, quy trình đó sẽ xử lý yêu cầu trong một luồng mới. Vì các luồng khác nhau có thể hoàn thành 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 ghi 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à phản hồi đang xử lý.

Xử lý đầu ra Multiplex

Multiplex worker cần xử lý đầu ra cẩn thận hơn so với singleplex worker. Mọi thứ được gửi đến stderr sẽ được chuyển vào một tệp nhật ký duy nhất được chia sẻ giữa tất cả các WorkerProxy cùng 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 đến stderr, nhưng đừng thu thập dữ liệu đầu ra đó vào trường output của WorkResponse, vì điều đó có thể khiến người dùng bị hỏng các phần đầu ra. Nếu công cụ của bạn chỉ gửi đầu ra do người dùng hướng đến stdout hoặc stderr, thì bạn cần thay đổi hành vi đó trước khi có thể bật worker ghép nối.

Bật trình thực thi Multiplex

Theo mặc định, Multiplex worker không được bật. Một bộ quy tắc có thể bật trình thực thi ghép nối bằng cách sử dụng thẻ supports-multiplex-workers trong execution_requirements của một hành động (giống như thẻ supports-workers bật 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, chiến lược trình thực thi cần được chỉ định ở 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 thêm cờ nào và supports-multiplex-workers sẽ được ưu tiên hơn supports-workers nếu cả hai được đặt. Bạn có thể tắt trình thực thi Multiplex trên toàn cầu bằng cách truyền --noworker_multiplex.

Bạn nên sử dụng một bộ quy tắc nếu có thể để giảm áp lực bộ nhớ và cải thiện hiệu suất. Tuy nhiên, trình thực thi multiplex hiện không tương thích với tính năng thực thi động trừ phi chúng 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 với tính năng thực thi động sẽ ngầm sử dụng các trình thực thi singleplex trong hộp cát.

Hộp cát Multiplex

Bạn có thể tạo hộp cát cho Multiplex worker bằng cách thêm tuỳ chọn hỗ trợ rõ ràng cho worker đó trong quá trình triển khai worker. Mặc dù hộp cát của trình thực thi singleplex có thể được thực hiện bằng cách chạy từng quy trình trình thực thi trong hộp cát riêng của trình thực thi đó, nhưng trình thực thi đa năng sẽ chia sẻ thư mục quy trình đang làm việc giữa nhiều yêu cầu song song. Để cho phép tạo hộp cát cho các worker ghép nối, worker phải hỗ trợ đọc và ghi vào 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 worker đó.

Để hỗ trợ hộp cát multiplex, 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 lượt đọc và ghi tệp. Mặc dù các trường argumentsinputs vẫn không thay đổi so với một yêu cầu không có hộp cát, nhưng dữ liệu đầu vào thực tế 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ả kết quả tương ứng với sandbox_dir. Các đường dẫn 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 các đối số (chẳng hạn như đối số "argfile").

Sau khi một trình thực thi hỗ trợ tính năng hộp cát multiplex, bộ 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 thao tác. 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 trình thực thi này được dùng với tính năng thực thi động.

Các tệp worker của worker trong hộp cát vẫn liên quan đến thư mục làm việc của quy trình worker. Do đó, nếu một tệp được dùng cho cả mục đích chạy worker và đầu vào, thì tệp đó phải được chỉ định cả làm dữ liệu đầu vào trong đối số tệp gắn cờ cũng như trong tools, executable hoặc runfiles.