Lưu từ xa vào bộ nhớ đệm

Sử dụng bộ sưu tập để sắp xếp ngăn nắp các trang Lưu và phân loại nội dung dựa trên lựa chọn ưu tiên của bạn.
Báo cáo sự cố Xem nguồn

Trang này trình bày cách lưu vào bộ nhớ đệm từ xa, thiết lập một máy chủ để lưu trữ bộ nhớ đệm và chạy các bản dựng bằng bộ nhớ đệm từ xa.

Một nhóm nhà phát triển và/hoặc hệ thống tích hợp liên tục (CI) sử dụng bộ nhớ đệm từ xa để chia sẻ kết quả của bản dựng. Nếu bản dựng của bạn có thể tái tạo, kết quả từ một máy có thể được tái sử dụng một cách an toàn trên máy khác, điều này có thể giúp bản dựng nhanh hơn đáng kể.

Tổng quan

Bazel chia một bản dựng thành các bước riêng biệt, được gọi là hành động. Mỗi hành động có các dữ liệu đầu vào, tên đầu ra, dòng lệnh và biến môi trường. Các đầu vào và đầu ra dự kiến bắt buộc được khai báo rõ ràng cho mỗi hành động.

Bạn có thể thiết lập máy chủ làm bộ nhớ đệm từ xa cho dữ liệu đầu ra của bản dựng, chính là các đầu ra của hành động này. Các kết quả này bao gồm danh sách tên tệp đầu ra và hàm băm của nội dung. Với bộ nhớ đệm từ xa, bạn có thể sử dụng lại kết quả của bản dựng từ bản dựng của người dùng khác thay vì xây dựng từng kết quả mới một cách cục bộ.

Cách sử dụng tính năng lưu vào bộ nhớ đệm từ xa:

  • Thiết lập một máy chủ làm phần phụ trợ của bộ nhớ đệm
  • Định cấu hình bản dựng Bazel để sử dụng bộ nhớ đệm từ xa
  • Sử dụng Bazel phiên bản 0.10.0 trở lên

Bộ nhớ đệm từ xa lưu trữ hai loại dữ liệu:

  • Bộ nhớ đệm hành động, một bản đồ của các hàm băm hành động để siêu dữ liệu kết quả hành động.
  • Một kho lưu trữ địa chỉ nội dung (CAS) của tệp đầu ra.

Lưu ý rằng bộ nhớ đệm từ xa cũng lưu trữ stdout và stderr cho mỗi thao tác. Do đó, việc kiểm tra stdout/stderr của Bazel không phải là một tín hiệu tốt để ước tính lượt truy cập bộ nhớ đệm.

Cách bản dựng sử dụng bộ nhớ đệm từ xa

Sau khi máy chủ được thiết lập làm bộ nhớ đệm từ xa, bạn sẽ sử dụng bộ nhớ đệm theo nhiều cách:

  • Đọc và ghi vào bộ nhớ đệm từ xa
  • Đọc và/hoặc ghi vào bộ nhớ đệm từ xa, ngoại trừ các mục tiêu cụ thể
  • Chỉ đọc từ bộ nhớ đệm từ xa
  • Không sử dụng bộ nhớ đệm từ xa

Khi bạn chạy một bản dựng Bazel có thể đọc và ghi vào bộ nhớ đệm từ xa, bản dựng đó sẽ tuân theo các bước sau:

  1. Bazel tạo biểu đồ các mục tiêu cần xây dựng, sau đó tạo danh sách các hành động bắt buộc. Mỗi hành động trong số này đều đã khai báo tên đầu vào và tên tệp đầu ra.
  2. Bazel kiểm tra máy cục bộ của bạn để tìm các kết quả bản dựng hiện có và sử dụng lại bất kỳ kết quả nào mà công cụ này tìm thấy.
  3. Bazel kiểm tra bộ nhớ đệm để xem các kết quả bản dựng hiện có. Nếu tìm thấy kết quả, Bazel sẽ truy xuất kết quả đó. Đây là một lượt truy cập bộ nhớ đệm.
  4. Đối với các hành động bắt buộc mà không tìm thấy kết quả, Bazel sẽ thực thi các thao tác trên máy và tạo các kết quả bản dựng cần thiết.
  5. Các kết quả mới về bản dựng được tải lên bộ nhớ đệm từ xa.

Thiết lập máy chủ làm phần phụ trợ của bộ nhớ đệm

Bạn cần thiết lập một máy chủ để hoạt động như phần phụ trợ của bộ nhớ đệm. Máy chủ HTTP/1.1 có thể coi dữ liệu của Bazel là các byte mờ và nhiều máy chủ hiện có có thể được dùng làm phần phụ trợ lưu vào bộ nhớ đệm từ xa. Giao thức lưu vào bộ nhớ đệm HTTP của Bazel là tính năng hỗ trợ lưu vào bộ nhớ đệm từ xa.

Bạn chịu trách nhiệm chọn, thiết lập và duy trì máy chủ phụ trợ sẽ lưu trữ các kết quả đã lưu vào bộ nhớ đệm. Khi chọn máy chủ, hãy cân nhắc:

  • Tốc độ mạng. Ví dụ: nếu nhóm của bạn ở cùng một văn phòng, bạn có thể muốn chạy máy chủ cục bộ của riêng mình.
  • Bảo mật. Bộ nhớ đệm từ xa sẽ có các tệp nhị phân nên cần được bảo mật.
  • Dễ quản lý. Ví dụ: Google Cloud Storage là một dịch vụ được quản lý toàn diện.

Có nhiều phần phụ trợ có thể dùng cho bộ nhớ đệm từ xa. Một số tuỳ chọn bao gồm:

nginx

nginx là một máy chủ web nguồn mở. Với [mô-đun WebDAV], bạn có thể dùng mô-đun này làm bộ nhớ đệm từ xa cho Bazel. Trên Debian và Ubuntu, bạn có thể cài đặt gói nginx-extras. Trên macOS nginx có sẵn qua Homebrew:

brew tap denji/nginx
brew install nginx-full --with-webdav

Dưới đây là cấu hình mẫu cho nginx. Xin lưu ý rằng bạn sẽ cần thay đổi /path/to/cache/dir thành một thư mục hợp lệ, trong đó nginx có quyền ghi và đọc. Bạn có thể cần thay đổi tùy chọn client_max_body_size thành giá trị lớn hơn nếu có các tệp đầu ra lớn hơn. Máy chủ sẽ yêu cầu cấu hình khác, chẳng hạn như xác thực.

Cấu hình mẫu cho phần server trong nginx.conf:

location /cache/ {
  # The path to the directory where nginx should store the cache contents.
  root /path/to/cache/dir;
  # Allow PUT
  dav_methods PUT;
  # Allow nginx to create the /ac and /cas subdirectories.
  create_full_put_path on;
  # The maximum size of a single file.
  client_max_body_size 1G;
  allow all;
}

điều khiển từ xa bazel

bazel-remote là một bộ nhớ đệm bản dựng từ xa nguồn mở mà bạn có thể sử dụng trên cơ sở hạ tầng của mình. Kỹ thuật này đã được sử dụng thành công trong môi trường thực tế tại một số công ty kể từ đầu năm 2018. Lưu ý rằng dự án Bazel không hỗ trợ kỹ thuật cho điều khiển từ xa bazel.

Bộ nhớ đệm này lưu trữ nội dung trên ổ đĩa, đồng thời cung cấp bộ nhớ thu gom rác để thực thi giới hạn bộ nhớ trên và dọn sạch các cấu phần phần mềm không sử dụng. Bộ nhớ đệm có sẵn dưới dạng [hình ảnh Docker] và mã có sẵn trên GitHub. Cả API bộ nhớ đệm từ xa REST và gRPC đều được hỗ trợ.

Hãy tham khảo trang GitHub để biết hướng dẫn về cách sử dụng trang đó.

Google Cloud Storage

[Google Cloud Storage] là một kho đối tượng được quản lý toàn diện, cung cấp API HTTP tương thích với giao thức lưu vào bộ nhớ đệm từ xa của Bazel. Phương thức này yêu cầu bạn phải có tài khoản Google Cloud và đã bật tính năng thanh toán.

Cách sử dụng Cloud Storage làm bộ nhớ đệm:

  1. Tạo bộ chứa. Đảm bảo rằng bạn chọn vị trí gần nhất với bạn, vì băng thông mạng rất quan trọng đối với bộ nhớ đệm từ xa.

  2. Tạo một tài khoản dịch vụ cho Bazel để xác thực với Cloud Storage. Hãy xem bài viết Tạo tài khoản dịch vụ.

  3. Tạo một khoá JSON bí mật, sau đó truyền khoá đó đến Bazel để xác thực. Lưu trữ khoá một cách an toàn, vì bất kỳ ai có khoá này đều có thể đọc và ghi dữ liệu tuỳ ý vào/từ bộ chứa GCS của bạn.

  4. Kết nối với Cloud Storage bằng cách thêm các cờ sau vào lệnh Bazel:

    • Chuyển URL sau đến Bazel bằng cách sử dụng cờ: --remote_cache=https://storage.googleapis.com/bucket-name trong đó bucket-name là tên của bộ chứa lưu trữ.
    • Truyền khoá xác thực bằng cách sử dụng cờ: --google_credentials=/path/to/your/secret-key.json hoặc --google_default_credentials để sử dụng tính năng Xác thực ứng dụng.
  5. Bạn có thể định cấu hình Cloud Storage để tự động xoá các tệp cũ. Để làm điều đó, hãy xem phần Quản lý vòng đời đối tượng.

Máy chủ khác

Bạn có thể thiết lập bất kỳ máy chủ HTTP/1.1 nào hỗ trợ PUT và GET làm phần phụ trợ của bộ nhớ đệm. Người dùng đã báo cáo thành công với các phần phụ trợ lưu vào bộ nhớ đệm như Hazelcast, Apache httpdAWS S3.

Xác thực

Kể từ phiên bản 0.11.0, tính năng Xác thực HTTP cơ bản đã được thêm vào Bazel. Bạn có thể chuyển tên người dùng và mật khẩu đến Bazel qua URL bộ nhớ đệm từ xa. Cú pháp là https://username:password@hostname.com:port/path. Lưu ý: Xác thực cơ bản HTTP truyền tên người dùng và mật khẩu dưới dạng văn bản thuần tuý qua mạng và do đó điều quan trọng là phải luôn sử dụng tên miền này với HTTPS.

Giao thức lưu vào bộ nhớ đệm của HTTP

Bazel hỗ trợ lưu vào bộ nhớ đệm từ xa qua HTTP/1.1. Giao thức này rất đơn giản về mặt lý thuyết: Dữ liệu nhị phân (rời) được tải lên qua yêu cầu PUT và tải xuống qua yêu cầu GET. Siêu dữ liệu về kết quả hành động được lưu trữ trong đường dẫn /ac/ và các tệp đầu ra được lưu trữ trong đường dẫn /cas/.

Ví dụ: hãy xem xét bộ nhớ đệm từ xa chạy trong http://localhost:8080/cache. Yêu cầu Bazel tải siêu dữ liệu kết quả hành động xuống cho một hành động có hàm băm SHA256 01ba4719... sẽ có dạng như sau:

GET /cache/ac/01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b HTTP/1.1
Host: localhost:8080
Accept: */*
Connection: Keep-Alive

Yêu cầu Bazel tải tệp đầu ra có hàm băm SHA256 15e2b0d3... lên CAS sẽ như sau:

PUT /cache/cas/15e2b0d3c33891ebb0f1ef609ec419420c20e320ce94c65fbc8c3312448eb225 HTTP/1.1
Host: localhost:8080
Accept: */*
Content-Length: 9
Connection: Keep-Alive

0x310x320x330x340x350x360x370x380x39

Chạy Bazel bằng bộ nhớ đệm từ xa

Sau khi máy chủ được thiết lập làm bộ nhớ đệm từ xa, để sử dụng bộ nhớ đệm từ xa, bạn cần thêm cờ vào lệnh Bazel. Hãy xem danh sách các cấu hình và các cờ của chúng ở bên dưới.

Bạn cũng có thể cần xác thực cấu hình dành riêng cho máy chủ bạn đã chọn.

Bạn nên thêm các cờ này vào tệp .bazelrc để không cần chỉ định chúng mỗi khi chạy Bazel. Tuỳ thuộc vào động lực của dự án và nhóm, bạn có thể thêm cờ vào tệp .bazelrc:

  • Trên máy cục bộ
  • Trong không gian làm việc của dự án, hãy chia sẻ với nhóm
  • Trên hệ thống CI

Đọc và ghi vào bộ nhớ đệm từ xa

Chú ý đến những người có khả năng ghi vào bộ nhớ đệm từ xa. Bạn có thể chỉ muốn hệ thống CI của mình có thể ghi vào bộ nhớ đệm từ xa.

Sử dụng cờ sau để đọc và ghi vào bộ nhớ đệm từ xa:

build --remote_cache=http://your.host:port

Ngoài HTTP, các giao thức sau cũng được hỗ trợ: HTTPS, grpc, grpcs.

Ngoài cờ trên, hãy sử dụng cờ sau đây để chỉ đọc từ bộ nhớ đệm từ xa:

build --remote_upload_local_results=false

Loại trừ các mục tiêu cụ thể khỏi việc sử dụng bộ nhớ đệm từ xa

Để loại trừ mục tiêu cụ thể bằng cách sử dụng bộ nhớ đệm từ xa, hãy gắn thẻ mục tiêu bằng no-remote-cache. Ví dụ:

java_library(
    name = "target",
    tags = ["no-remote-cache"],
)

Xoá nội dung khỏi bộ nhớ đệm từ xa

Việc xoá nội dung khỏi bộ nhớ đệm từ xa sẽ góp phần quản lý máy chủ của bạn. Cách xoá nội dung khỏi bộ nhớ đệm từ xa phụ thuộc vào máy chủ mà bạn đã thiết lập làm bộ nhớ đệm. Khi xoá kết quả, hãy xoá toàn bộ bộ nhớ đệm hoặc xoá các kết quả cũ.

Kết quả đã lưu vào bộ nhớ đệm được lưu trữ dưới dạng tập hợp tên và hàm băm. Khi xoá nội dung, không có cách nào để phân biệt đầu ra nào thuộc về một bản dựng cụ thể.

Bạn nên xoá nội dung khỏi bộ nhớ đệm để:

  • Tạo bộ nhớ đệm sạch sau khi bộ nhớ đệm bị nhiễm độc
  • Giảm lượng bộ nhớ đã dùng bằng cách xoá dữ liệu đầu ra cũ

Ổ cắm Unix

Bộ nhớ đệm HTTP từ xa hỗ trợ kết nối qua các ổ cắm miền Unix. Hành vi này tương tự như cờ --unix-socket của curl. Sử dụng các mục sau để định cấu hình ổ cắm miền Unix:

   build --remote_cache=http://your.host:port
   build --remote_cache_proxy=unix:/path/to/socket

Tính năng này không được hỗ trợ trên Windows.

Bộ nhớ đệm của ổ đĩa

Bazel có thể sử dụng một thư mục trên hệ thống tệp làm bộ nhớ đệm từ xa. Điều này rất hữu ích khi chia sẻ cấu phần phần mềm của bản dựng khi chuyển đổi các nhánh và/hoặc làm việc trên nhiều không gian làm việc của cùng một dự án, chẳng hạn như nhiều quy trình thanh toán. Vì Bazel không thu thập rác trong thư mục, nên bạn có thể muốn tự động hoá việc dọn dẹp thư mục này theo định kỳ. Kích hoạt bộ nhớ đệm của ổ đĩa như sau:

build --disk_cache=path/to/build/cache

Bạn có thể chuyển một đường dẫn dành riêng cho người dùng đến cờ --disk_cache bằng cách sử dụng bí danh ~ (Bazel sẽ thay thế thư mục gốc của người dùng hiện tại). Điều này rất hữu ích khi bật bộ nhớ đệm của ổ đĩa cho tất cả nhà phát triển của dự án thông qua tệp .bazelrc đã kiểm tra của dự án.

Vấn đề đã biết

Sửa đổi tệp đầu vào trong quá trình xây dựng

Khi tệp đầu vào được sửa đổi trong quá trình tạo bản dựng, Bazel có thể tải các kết quả không hợp lệ lên bộ nhớ đệm từ xa. Bạn có thể bật tính năng phát hiện thay đổi bằng cờ --experimental_guard_against_concurrent_changes. Không có vấn đề nào đã biết và tính năng này sẽ được bật theo mặc định trong bản phát hành sau này. Hãy xem [vấn đề #3360] để biết thông tin cập nhật. Nhìn chung, hãy tránh sửa đổi các tệp nguồn trong quá trình tạo bản dựng.

Các biến môi trường bị rò rỉ trong một hành động

Định nghĩa hành động chứa các biến môi trường. Đây có thể là vấn đề khi chia sẻ bộ nhớ đệm từ xa trên các máy. Ví dụ: các môi trường có các biến $PATH khác nhau sẽ không chia sẻ lượt truy cập bộ nhớ đệm. Chỉ có các biến môi trường được đưa vào danh sách cho phép một cách rõ ràng qua --action_env mới được đưa vào định nghĩa hành động. Gói Debian/Ubuntu của Bazel từng dùng để cài đặt /etc/bazel.bazelrc có danh sách cho phép gồm các biến môi trường, bao gồm $PATH. Nếu bạn nhận được ít lượt truy cập bộ nhớ đệm hơn dự kiến, hãy kiểm tra để đảm bảo rằng môi trường của bạn không có tệp /etc/bazel.bazelrc cũ.

Bazel không theo dõi các công cụ bên ngoài một không gian làm việc

Bazel hiện không theo dõi các công cụ bên ngoài không gian làm việc. Đây có thể là vấn đề nếu chẳng hạn như một hành động sử dụng trình biên dịch trong /usr/bin/. Sau đó, hai người dùng đã cài đặt trình biên dịch khác nhau sẽ chia sẻ không chính xác lượt truy cập bộ nhớ đệm vì kết quả sẽ khác nhau nhưng họ có cùng một hàm băm hành động. Hãy xem vấn đề #4558 để biết thông tin cập nhật.

Trạng thái trong bộ nhớ gia tăng sẽ bị mất khi chạy bản dựng bên trong vùng chứa docker Bazel sử dụng kiến trúc máy chủ/ứng dụng ngay cả khi chạy trong vùng chứa docker đơn. Ở phía máy chủ, Bazel duy trì trạng thái trong bộ nhớ giúp tăng tốc các bản dựng. Khi chạy các bản dựng bên trong vùng chứa docker, chẳng hạn như trong CI, trạng thái trong bộ nhớ sẽ bị mất và Bazel phải tạo lại nó trước khi sử dụng bộ nhớ đệm từ xa.