En esta página, se abordan el almacenamiento en caché remoto, la configuración de un servidor para alojar la caché y ejecutando compilaciones con la caché remota.
Un equipo de desarrolladores o una integración continua usan una caché remota (CI) para compartir resultados de compilación. Si tu compilación es reproducible, el las salidas de una máquina pueden reutilizarse en otra máquina, lo que puede y agilizar las compilaciones.
Descripción general
Bazel divide una compilación en pasos discretos llamados acciones. Cada acción tiene entradas, nombres de salida, una línea de comandos y variables de entorno. Obligatorias Las entradas y las salidas esperadas se declaran explícitamente para cada acción.
Puedes configurar un servidor para que sea una caché remota para los resultados de compilación: resultados de acciones. Estos resultados consisten en una lista de nombres de archivos de salida y el hash de su contenido. Con una caché remota, puedes volver a usar los resultados de compilación a partir de la compilación de otro usuario, en lugar de compilar cada resultado nuevo a nivel local.
Para usar el almacenamiento en caché remoto, haz lo siguiente:
- Configura un servidor como backend de la caché
- Configura la compilación de Bazel para usar la caché remota
- Usa Bazel 0.10.0 o una versión posterior
La caché remota almacena dos tipos de datos:
- La caché de acciones, que es un mapa de hashes de acciones para metadatos de resultados de acciones.
- Un almacén de contenido direccionable (CAS) de archivos de salida.
Ten en cuenta que la caché remota además almacena stdout y stderr para cada acción. Inspeccionar las stdout/stderr de Bazel no es una buena señal para estimar los aciertos de caché.
Cómo una compilación usa el almacenamiento en caché remoto
Una vez que un servidor se configura como la caché remota, se usa la caché en varios maneras:
- Leer y escribir en la caché remota
- Leer o escribir en la caché remota, excepto en destinos específicos
- Solo leer desde la caché remota
- No usar la caché remota en absoluto
Cuando ejecutas una compilación de Bazel que puede leer y escribir en la caché remota, la compilación sigue estos pasos:
- Bazel crea el gráfico de destinos que deben compilarse y, luego, crea una lista de acciones requeridas. Cada una de estas acciones tiene entradas declaradas y nombres de archivo de salida.
- Bazel verifica tu máquina local en busca de resultados de compilación existentes y reutiliza que encuentre.
- Bazel verifica la caché en busca de resultados de compilación existentes. Si se encuentra el resultado, Bazel recupera el resultado. Este es un acierto de caché.
- Para las acciones necesarias en las que no se encontraron los resultados, Bazel ejecuta a nivel local y crea los resultados de compilación requeridos.
- Los resultados de compilación nuevos se suben a la caché remota.
Configura un servidor como backend de la caché
Debes configurar un servidor para que actúe como backend de la caché. Una instancia de HTTP/1.1 puede tratar los datos de Bazel como bytes opacos, por lo que muchos servidores existentes se puede usar como backend de almacenamiento en caché remoto. Bazel El protocolo de almacenamiento en caché HTTP es lo que admite el almacenamiento en caché.
Eres responsable de elegir, configurar y mantener el backend de salida que almacenará las salidas en caché. Cuando elijas un servidor, considera lo siguiente:
- Velocidad de la creación de redes. Por ejemplo, si tu equipo está en la misma oficina, puedes cuando quieras ejecutar tu propio servidor local.
- Seguridad La caché remota tendrá tus objetos binarios, por lo que debe ser segura.
- Facilidad de administración. Por ejemplo, Google Cloud Storage es un servicio completamente administrado.
Hay muchos backends que se pueden usar para una caché remota. Estas son algunas opciones:
nginx
nginx es un servidor web de código abierto. Con su [módulo WebDAV], se puede
como caché remota para Bazel. En Debian y Ubuntu, puedes instalar
nginx-extras
. En macOS, nginx está disponible a través de Homebrew:
brew tap denji/nginx
brew install nginx-full --with-webdav
A continuación, se muestra un ejemplo de configuración para nginx. Ten en cuenta que deberás
cambia /path/to/cache/dir
por un directorio válido en el que nginx tenga permiso.
de escribir y leer. Es posible que debas cambiar la opción client_max_body_size
a una
o un valor mayor si tienes archivos de salida más grandes. El servidor necesitará otros
configuración, como la autenticación.
Configuración de ejemplo para la sección server
en 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;
}
control remoto de Bazel
bazel-remote es una caché de compilación remota de código abierto que puedes usar en tu infraestructura. Se usó con éxito en producción en varias empresas desde principios de 2018. Ten en cuenta que el proyecto de Bazel no no proporcionar asistencia técnica para bazel-remote
Esta caché almacena contenido en el disco y también proporciona la recolección de elementos no utilizados para aplicar un límite de almacenamiento superior y borrar artefactos sin usar. La caché es como [imagen de Docker] y su código está disponible en GitHub: Se admiten las APIs de caché remota de REST y gRPC.
Consulta GitHub para obtener instrucciones sobre cómo utilizarla.
Google Cloud Storage
[Google Cloud Storage] es un almacén de objetos completamente administrado que proporciona API de HTTP compatible con el protocolo de almacenamiento en caché remoto de Bazel. Requiere que tienes una cuenta de Google Cloud con facturación habilitada.
Para usar Cloud Storage como la caché, haz lo siguiente:
Crea un bucket de almacenamiento. Asegúrate de seleccionar la ubicación de bucket más cercana a ti como ancho de banda de red es importante para la caché remota.
Crea una cuenta de servicio para que Bazel se autentique en Cloud Storage. Consulta Crea una cuenta de servicio.
Genera una clave JSON secreta y, luego, pásala a Bazel para la autenticación. Tienda la clave de forma segura, ya que cualquier persona que la tenga podrá leer y escribir datos arbitrarios desde y hacia el bucket de GCS.
Para conectarte a Cloud Storage, agrega las siguientes marcas al comando de Bazel:
- Pasa la siguiente URL a Bazel con la marca:
--remote_cache=https://storage.googleapis.com/bucket-name
, en el quebucket-name
es el nombre del bucket de almacenamiento. - Pasa la clave de autenticación con la marca
--google_credentials=/path/to/your/secret-key.json
, o--google_default_credentials
para usar la autenticación de aplicaciones.
- Pasa la siguiente URL a Bazel con la marca:
Puedes configurar Cloud Storage para borrar automáticamente los archivos antiguos. Para ello, consulta Administra ciclos de vida de objetos.
Otros servidores
Puedes configurar cualquier servidor HTTP/1.1 que admita PUT y GET como backend. Los usuarios informaron que con éxito los backends de almacenamiento en caché, como Hazelcast, Apache httpd y AWS S3.
Autenticación
A partir de la versión 0.11.0, se agregó a Bazel la compatibilidad con la autenticación básica HTTP.
Puedes pasar un nombre de usuario y una contraseña a Bazel a través de la URL de caché remota. El
la sintaxis es https://username:password@hostname.com:port/path
. Ten en cuenta que
La autenticación básica HTTP transmite el nombre de usuario y la contraseña en texto simple a través del
por lo que es fundamental
utilizarla siempre con HTTPS.
Protocolo de almacenamiento en caché HTTP
Bazel admite el almacenamiento en caché remoto a través de HTTP/1.1. El protocolo es conceptualmente simple:
Los datos binarios (BLOB) se suben a través de solicitudes PUT y se descargan a través de solicitudes GET.
Los metadatos de los resultados de acciones se almacenan en la ruta de acceso /ac/
, y los archivos de salida se almacenan
en la ruta /cas/
.
Por ejemplo, imagina una caché remota que se ejecuta en http://localhost:8080/cache
.
Una solicitud de Bazel para descargar metadatos de resultados de acciones para una acción con el algoritmo SHA256
el hash 01ba4719...
se verá de la siguiente manera:
GET /cache/ac/01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b HTTP/1.1
Host: localhost:8080
Accept: */*
Connection: Keep-Alive
Una solicitud de Bazel para subir un archivo de salida con el hash SHA256 15e2b0d3...
a
el CAS se verá de la siguiente manera:
PUT /cache/cas/15e2b0d3c33891ebb0f1ef609ec419420c20e320ce94c65fbc8c3312448eb225 HTTP/1.1
Host: localhost:8080
Accept: */*
Content-Length: 9
Connection: Keep-Alive
0x310x320x330x340x350x360x370x380x39
Ejecuta Bazel con la caché remota
Una vez que el servidor esté configurado como caché remota, para usar la caché remota debes agregar marcas a tu comando de Bazel. Consulta la lista de configuraciones y sus banderas debajo.
Es posible que también debas configurar la autenticación, que es específica de tu servidor elegido.
Te recomendamos agregar estas marcas a un archivo .bazelrc
para evitar lo siguiente:
deberás especificarlos cada vez que ejecutes Bazel. Según tu proyecto y
dinámica de equipo, puedes agregar marcas a un archivo .bazelrc
con las siguientes características:
- En tu máquina local
- En el lugar de trabajo de tu proyecto, compartido con el equipo
- En el sistema de CI
Lee y escribe en la caché remota
Verifica quién tiene la capacidad de escribir en la caché remota. Es posible que quieras para que solo tu sistema de CI pueda escribir en la caché remota.
Usa la siguiente marca para leer y escribir en la caché remota:
build --remote_cache=http://your.host:port
Además de HTTP
, también se admiten los siguientes protocolos: HTTPS
, grpc
y grpcs
.
Usa la siguiente marca, además de la anterior, para leer solamente desde el Caché remota:
build --remote_upload_local_results=false
Excluir destinos específicos para que no usen la caché remota
Para excluir destinos específicos y evitar el uso de la caché remota, etiqueta el destino con
no-cache
Por ejemplo:
java_library(
name = "target",
tags = ["no-cache"],
)
Borra el contenido de la caché remota
Borrar contenido de la caché remota forma parte de la administración del servidor. La forma de borrar contenido de la caché remota depende del servidor que tengas configurar como caché. Cuando borres los resultados, borra toda la caché o borrar las salidas antiguas.
Los resultados almacenados en caché se almacenan como un conjunto de nombres y hashes. Al borrar contenido, no hay forma de distinguir qué salida pertenece a un compilar.
Es posible que quieras borrar el contenido de la caché para lo siguiente:
- Crear una caché limpia después de que se envenenó una caché
- Borra los resultados antiguos para reducir la cantidad de almacenamiento que se usa.
Sockets Unix
La caché HTTP remota admite la conexión a través de sockets de dominio Unix. El comportamiento
es similar a la marca --unix-socket
de curl. Usa el siguiente comando para configurar Unix
socket de dominio:
build --remote_cache=http://your.host:port
build --remote_cache_proxy=unix:/path/to/socket
Esta función no es compatible con Windows.
Caché de disco
Bazel puede usar un directorio en el sistema de archivos como caché remota. Este es útil para compartir artefactos de compilación cuando se cambian de rama o se trabaja en varios espacios de trabajo del mismo proyecto, como varias confirmaciones de compra. Desde Bazel no realiza la recolección de elementos no utilizados del directorio, por lo que tal vez quieras automatizar la limpieza periódica de este directorio. Habilita la caché de disco de la siguiente manera:
build --disk_cache=path/to/build/cache
Puedes pasar una ruta específica del usuario a la marca --disk_cache
con el alias ~
.
(Bazel reemplazará el directorio principal del usuario actual). Esto es muy útil
Cuando habilites la caché de disco para todos los desarrolladores de un proyecto a través del
registrado en el archivo .bazelrc
.
Problemas conocidos
Modificación del archivo de entrada durante una compilación
Cuando se modifica un archivo de entrada durante una compilación, es posible que Bazel suba una carga no válida.
los resultados a la caché remota. Puedes habilitar la detección de cambios con
la marca --experimental_guard_against_concurrent_changes
. Hay
no hay problemas conocidos y se habilitará de forma predeterminada en una versión futura.
Consulta el [problema #3360] para ver actualizaciones. Generalmente, evita modificar los archivos fuente durante un
compilar.
Variables de entorno que se filtran en una acción
Una definición de acción contiene variables de entorno. Esto puede ser un problema para
los aciertos de caché remota entre máquinas. Por ejemplo, los entornos con
las diferentes variables $PATH
no compartirán los aciertos de caché. Solo variables de entorno
se incluyen en una acción de forma explícita a través de --action_env
definición. El paquete Debian/Ubuntu de Bazel que se usa para instalar /etc/bazel.bazelrc
con una lista blanca de variables de entorno, incluida $PATH
. Si obtienes
aciertos de caché de lo esperado, comprueba que tu entorno no tenga un
/etc/bazel.bazelrc
.
Bazel no hace un seguimiento de las herramientas fuera de un espacio de trabajo
Por el momento, Bazel no realiza un seguimiento de las herramientas fuera de un espacio de trabajo. Puede ser un
si, por ejemplo, una acción usa un compilador de /usr/bin/
. Luego,
dos usuarios con diferentes compiladores instalados compartirán de manera incorrecta los aciertos de caché
porque las salidas son diferentes, pero tienen el mismo hash de acción. Consulta
error #4558 para las actualizaciones.
Se pierde el estado incremental en la memoria cuando se ejecutan compilaciones dentro de contenedores de Docker Bazel usa una arquitectura de servidor/cliente incluso cuando se ejecuta en un solo contenedor de Docker. En el lado del servidor, Bazel mantiene un estado en la memoria que acelera las compilaciones. Cuando se ejecutan compilaciones dentro de contenedores de Docker, como en CI, se pierde el estado en memoria. y Bazel debe volver a compilarla antes de usar la caché remota.
Vínculos externos
Tu compilación en un centro de datos: En el FOSDEM 2018, el equipo de Bazel dio una charla sobre la ejecución y el almacenamiento en caché remoto.
Compilaciones más rápidas de Bazel con almacenamiento en caché remoto: una comparativa: Nicolò Valigi escribió una entrada de blog en el que compara el almacenamiento en caché remoto en Bazel.