1. 远程缓存原理
Bazel 的远程缓存是其性能核心特性,通过存储构建产物(编译输出、测试结果)并复用它们来大幅加速构建。
1.1 缓存的基本概念

1.2 缓存存储的产物类型
1.3 缓存策略
缓存策略:1. 按内容哈希存储 → 同一内容只存储一次2. 只存储中间产物 → 源代码不缓存3. 缓存分层 → 本地磁盘 → 远程缓存 → 重新构建4. 原子性操作 → 避免部分构建
2. 远程缓存配置
2.1 基本配置
# 配置远程缓存(gRPC)bazel build //... --remote_cache=grpc://cache.example.com:9092# 配置远程缓存(HTTP)bazel build //... --remote_cache=http://cache.example.com:8080# 配置本地磁盘缓存bazel build //... --disk_cache=~/.cache/bazel
2.2 .bazelrc 配置
# .bazelrc# 默认启用远程缓存build --remote_cache=grpc://cache.example.com:9092build --remote_timeout=60 # 超时时间(秒)# 本地缓存配置build --disk_cache=/tmp/bazel_cachebuild --remote_upload_local_results=true # 本地结果上传到远程# 缓存大小限制build --max_idle_secs=3600 # 缓存保留时间build --remote_default_exec_properties=platform=x86_64
2.3 企业级配置
# .bazelrc# 远程执行配置build --remote_executor=grpc://executor.example.com:9091build --remote_instance_name=instance1build --remote_default_platform_properties=platform=x86_64,os=linux# 缓存配置build --remote_cache=grpc://cache.example.com:9092build --remote_timeout=300build --remote_retries=3# 证书配置build --remote_cafile=/path/to/ca.crtbuild --remote_cacert_pin="sha256=..."
3. 本地磁盘缓存
3.1 磁盘缓存结构
~/.cache/bazel/├── execroot/ # 执行根目录├── cache/ # 缓存数据│ ├── action_cache/ # Action 输出缓存│ ├── content_cache/ # 文件内容缓存│ └── test_logs/ # 测试日志└── tmp/ # 临时文件
3.2 配置磁盘缓存
# .bazelrc# 设置缓存大小限制build --remote_max_connections=20 # 最大并发连接build --remote_timeout=60 # 连接超时# 缓存清理策略build --max_idle_secs=86400 # 24小时不访问则清理build --experimental_remote_downloader_cache_size=100 # 100GB# Windows 特定配置build --experimental_windows_symlink_in_runfiles=false
3.3 管理磁盘缓存
# 查看缓存大小du -sh ~/.cache/bazel/# 清理缓存bazel clean --expunge # 完全清理rm -rf ~/.cache/bazel/cache # 手动清理缓存# 设置缓存清理任务# 在 .bashrc 或 crontab 中添加# 每周清理一次*/5 * * * * find ~/.cache/bazel/cache -type f -mtime +7 -delete
4. 远程执行
远程执行与远程缓存协同工作,将计算任务分发到远程执行器。
4.1 远程执行配置
# 启用远程执行bazel build //... --remote_executor=grpc://executor.example.com:9091# 同时使用缓存和执行bazel build //... \--remote_cache=grpc://cache.example.com:9092 \--remote_executor=grpc://executor.example.com:9091# 指定执行平台bazel build //... --platform_target=@platforms//os:linux
4.2 工作区配置
# WORKSPACE 或 MODULE.bazelload("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")# 注册远程执行器http_archive(name = "my_remote_tools",urls = ["https://example.com/tools.tar.gz"],patch_cmds = ["echo 'my_executable' > remote_executor","chmod +x remote_executor",],)# BUILD 文件中使用toolchain(name = "remote_toolchain",toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",toolchain = ":remote_toolchain_impl",)
4.3 安全配置
# .bazelrc# 启用认证build --remote_timeout=60build --remote_downloader_cafile=/path/to/ca.crtbuild --remote_downloader_cacert_pin="sha256=..."build --remote_executor_cafile=/path/to/ca.crt# 令牌认证build --remote_downloader_header="Authorization: Bearer token"build --remote_executor_header="Authorization: Bearer token"
5. 缓存优化策略
5.1 缓存命中率优化
# 查看缓存命中率bazel build //... --remote_verbose# 分析构建缓存效果bazel analyze-profile --build \--output_html=cache_analysis.html# 使用 bazel analyze-action-inputsbazel analyze-action-inputs //... > action_inputs.log
5.2 Action 合并
# 合并相似的 Actioncc_library(name = "optimized_lib",srcs = ["a.cc", "b.cc", "c.cc"],copts = ["-O2"], # 相同编译选项)# 而不是分开编译# cc_library(name = "a", srcs = ["a.cc"], copts = ["-O2"])# cc_library(name = "b", srcs = ["b.cc"], copts = ["-O2"])
5.3 内容感知的缓存
# 使用文件的哈希值而不是文件名cc_library(name = "versioned_lib",srcs = ["lib.cc"],copts = ["-DVERSION_SHA=@"EOF
6.3 监控与报警
# 监控脚本(Python)import requestsimport timedef monitor_cache_health():# 检查缓存服务器状态try:response = requests.get("https://cache.example.com/health", timeout=5)if response.status_code != 200:alert("Cache server unhealthy")else:stats = response.json()if stats["cache_hit_ratio"] < 0.8:alert("Low cache hit ratio")except Exception as e:alert(f"Cache server error: {e}")# 定期执行while True:monitor_cache_health()time.sleep(60)
7. 故障排查
7.1 常见问题
7.2 调试命令
# 启用详细日志bazel build //... --remote_verbose# 测试缓存连接bazel build //:hello --remote_cache=grpc://cache.example.com:9092# 查看缓存的 Actionbazel query "buildfiles(//...)" --output=graph# 分析构建缓存bazel analyze-profile --build --output_html=analysis.html
7.3 缓存统计
# 缓存使用统计bazel info --disk_cache_usagebazel info --remote_cache_usage# 查看缓存中的 Actionbazel cquery "kind(cc_compile, //...)" --output=label | wc -l
8. 性能基准测试
8.1 本地 vs 远程构建对比
#!/bin/bash# build_benchmark.sh# 确保构建目录干净bazel clean --expunge# 构建时间测试echo "=== 本地构建 ==="time bazel build //...echo "=== 本地缓存构建 ==="time bazel build //...echo "=== 远程缓存构建 ==="time bazel build //... --remote_cache=grpc://cache.example.com:9092echo "=== 远程执行构建 ==="time bazel build //... --remote_executor=grpc://executor.example.com:9091
8.2 缓存命中测试
# 测试不同场景的缓存命中率import subprocessimport jsondef test_cache_hit_ratio():# 记录初始状态result = subprocess.run(["bazel", "info", "disk_cache_usage"], capture_output=True)initial_cache = int(result.stdout.decode().strip())# 构建并测量subprocess.run(["bazel", "build", "//..."], check=True)result = subprocess.run(["bazel", "info", "disk_cache_usage"], capture_output=True)final_cache = int(result.stdout.decode().strip())cache_growth = final_cache - initial_cachereturn cache_growth# 测试不同配置print("Action-level cache size:", test_cache_hit_ratio())
9. 成本优化
9.1 缓存压缩
# .bazelrc# 启用压缩build --remote_compression=truebuild --remote_timeout=60# 压缩级别build --remote_compression_level=6
9.2 智能缓存策略
# 自动清理旧缓存import osimport timedef cleanup_old_cache():cache_dir = os.path.expanduser("~/.cache/bazel/cache")max_age = 30 * 24 * 60 * 60 # 30天for root, dirs, files in os.walk(cache_dir):for file in files:file_path = os.path.join(root, file)if time.time() - os.path.getmtime(file_path) > max_age:os.remove(file_path)print(f"Removed: {file_path}")
9.3 冷热数据分离
存储策略:1. 热数据(最近7天)→ 存在高速存储2. 温数据(30天)→ 存在标准存储3. 冷数据(30天以上)→ 存在低成本存储或删除// .bazelrc 配置build --remote_cache_cleanup_age=2592000 # 30天build --remote_cache_retention_multiplier=1.5
10. 小结
本篇详细介绍了 Bazel 的远程缓存与分布式构建:
✅ 远程缓存原理与基本概念 ✅ 本地磁盘缓存配置与管理 ✅ 远程执行与缓存协同工作 ✅ 缓存优化策略与技巧 ✅ 企业级部署方案 ✅ 故障排查与监控 ✅ 性能基准测试 ✅ 成本优化策略
夜雨聆风