Bazel Remote Cache
前面讲了Bazel的基本本地使用,但是我们知道,Bazel最重要的是支持缓存和分布式(远程执行),那么这一节主要就是讲如何让bazel使用缓存。
要能够缓存Bazel每个action的输出,我们就要一个server来实现remote cache,用于存储action的输出。这些输出实际上是一堆文件恶化对应的hash值。总体来说,我们需要满足三个前提:
- 设置一个server作为cache backend
- 配置Bazel build去使用cache
- Bazel版本要在0.10.0以上
Cache本身会存储两种数据:
- action cache,或者说实际上是一个acton->action result的map映射表
- 一个可寻址(addressable)的输出文件存储系统
https://docs.bazel.build/versions/master/remote-caching.html 中对Bazel Remote Cache的使用和工作有更详细的介绍,就不重复了。这里直接讲到底怎么设置一个Bazel Remote Cache Server. 在上面这个链接中提到了三种方式:
- NGINX的WebDAV模块
- 开源的bazel-remote
- Google Cloud Storage
这里我们直接选择第二种:开源的bazel-remote,以便可能的定制及更好理解内部实现。
这里我们不用去重新编译运行,直接下载对应的docker镜像并运行即可
1 | $docker pull buchgr/bazel-remote-cache |
bazel-remote支持grpc和http的接口调用,但注意docker内部应用的http接口应该是8080而不是9090(官方文档有误)。
创建一个目录cache, 然后启动docker容器如下
1 | $ docker run -u 0 \ |
1 | $ docker container update --restart=always 容器名字 |
We recommend deploying bazel-remote-cache with Docker Compose
1 | # https://stackoverflow.com/questions/64341356/pass-arguments-into-docker-container-from-docker-compose-yml |
Save as docker-compose.yaml, create config.yaml in the same directory, and run the below commands to get bazel-remote-cache up:
1 | $ docker-compose up -d |
You can view the logs with:
1 | $ docker-compose logs |
Stop bazel-remote-cache with:
1 | $ docker-compose stop && docker-compose rm -f |
使用具有mkdir权限的docker 用户, user 0 为root用户
1 | docker run --user 0 -v `pwd`/bazel_cache/:/data -p 8080:8080 buchgr/bazel-remote-cache --max_size=20 |
我们可以看到一堆输出:
1 | 2020/10/13 16:12:20 bazel-remote built with go1.14.5 from git commit cc9030667416ab63d89b9fbf543f0243292009b4. |
然后可以通过其/status接口来查看是否正常启动
1 | $curl http://10.11.11.107:7070/status |
另外我们也可以查看cache目录下是否生成了对应文件:

这时就可以在运行bazel build的时候指定remote cache server的地址:
使用Bazel Remote Cache
在Bazel工程的工程目录下,创建.bazelrc文件,并进行如下配置:
1 | 指定Bazel Remote Cache的Http IP地址和端口,低版本bazel支持 |
或者直接build target后加上–remote_cache参数
1 | $bazel build //src/main:app --remote_cache=http://172.24.136.52:7070 |
在docker一侧,我们可以看到输出

可以看到cache主要是通过http put/get,并使用hash作为key来进行对应结果的查找。
我们重复几次bazel build后可以看到耗时很短,只有不到0.3秒:
1 | INFO: Analyzed target //src/main:app (0 packages loaded, 0 targets configured). |
这显然是cache的作用,我们也可以在BUILD文件中禁止cache。这实际上是对rule的tags设置(我们在以后再讲如何定义rule),我们在这里可以尝试对java_library这个rule添加tag,禁止cache。修改src/main/java/com/example/bazel/util/BUILD中的java_library属性如下:

这样bazel就不会对该BUILD的结果进行缓存,读者可以自行尝试对比,这里就不过多展示实验结果。
实际上,remote caching只是最基本的一个结果缓存机制,部署和使用都很简单,这里也只是对此进行快捷说明。小团队完全可以用这种方式来部分提升效率。而远程执行(Remote Execution)往往集成了缓存功能,因此在实际大型团队部署中一般不会专门对Remote Cache创建server。我们在下一节来介绍Remote Execution.
–noremote_accept_cached: disable remote cache accept, but upload.
Bazel remote Execution
https://bazelbuild.github.io/bazel-buildfarm/docs/quick_start/
References: