• bazel远程构建(Remote Execution) -- Buildfarm介绍和部署测试


    Buildfarm是什么?

    Buildfarm是一个基于 Python 的分布式编译系统,支持多种语言,包括 C、C++、Java、Python、Ruby 等。BuildFarm 的设计比较灵活,可以根据实际需求进行定制和扩展。它使用一个中心控制节点来管理多个编译服务器,中心控制节点会将编译任务分发给空闲的服务器。BuildFarm 还提供了 Web 界面来方便用户管理编译任务。

    目标

    通过buildfarm实现bazel远程缓存和远程执行。

    要求

    buildfarm需要一个backplane 来存储集群成员之间共享的信息。可以使用 redis 服务器来满足此要求。下载/安装 redis-server 实例并在本地主机上运行它。默认的 redis 端口 6379 将由默认的Buildfarm配置使用。redis安装方式参考bazel远程构建(Remote Execution) --- linux安装Redis-CSDN博客。需提前安装和运行redis,否则buildfarm运行时会报找不到可用的redis。

    bazel示例工程

    从当个文件编译为可执行文件方式,搭建bazel构建工程

    创建新目录作为工作区,并添加以下文件:

    文件main.cc及内容

    1. #include
    2. int main( int argc, char *argv[] )
    3. {
    4. std::cout << "Hello, World!" << std::endl;
    5. }

    文件BUILD及内容

    1. cc_binary(
    2. name = "main",
    3. srcs = ["main.cc"],
    4. )

    一个空的WORKSPACE文件,标识当前目录为bazel工作区

    构建bazel的HelloWorld示例,运行如下命令:

    bazel run :main

    运行构建产物可执行二进制观察输出是否为预期的Hello, World

    ./bazel-bin/main

    上述正常确保机器已正确安装bazel和C++编译器, 这个也是后续测试远程缓存和远程执行的一个工作目标。

    Buildfarm下载部署

    创建一个目录,然后在下面clone Bazel Buildfarm项目:

    1. mkdir buildfarm
    2. cd buildfarm
    3. git clone https://github.com/bazelbuild/bazel-buildfarm.git
    4. cd bazel-buildfarm

    这时候进入了对应的bazel buildfarm目录。 需修改buildfarm项目的.bazelversion文件,将其默认版本号改为当前机器安装的bazel版本号(运行bazel --version即可查看,但需退出buildfarm项目目录再执行查看)。

    远程缓存

    Buildfarm 群集可以严格用作 ActionCache (AC) 和 ContentAddressableStorage (CAS),以提高构建性能。如下是运行 bazel 客户端的示例

    切换到目录bazel-buildfarm,然后执行如下命令:

    bazel run src/main/java/build/buildfarm:buildfarm-server $PWD/examples/config.minimal.yml

    若是正常,则将在服务器运行时等待,指示它已准备好接收请求。

    服务器本身不存储操作结果的内容。它充当提供存储的任意数量的工作线程的端点,因此我们还必须启动单个工作线程。

    重新打开一个交互界面,然后执行如下命令:

    bazel run src/main/java/build/buildfarm:buildfarm-shard-worker -- --prometheus_port=9091 $PWD/examples/config.minimal.yml

    -- option是 bazel 约定,将所有后续参数视为正在运行的应用程序的参数,例如上述的----prometheus_port,而不是使用run。该选项--prometheus_port=9091允许该工作线程与我们的服务器一起运行,该服务器将启动并记录它已在端口9090上启动服务。您还可以为服务器或辅助角色关闭此选项--prometheus_option=0。这也将在工作线程运行时等待,指示它将可用于存储缓存内容。

    重新打开一个交互界面,切换到bazel示例工作区目录

    1. bazel clean
    2. bazel run :main --remote_cache=grpc://localhost:8980

    执行clean操作是为了清除历史执行的本地工作区缓存,由于我们正在验证重新执行和缓存,因此这可确保我们将执行步骤中的任何操作并与远程缓存进行交互。我们应该尝试检索缓存的结果,然后当我们没有命中时,因为是首次启动了这个内存驻留服务器。 bazel 将上传执行结果供以后使用。如果一切正常,此 bazel 运行的输出不会有任何变化,因为 bazel 不会在每次上传结果时提供输出。

    为了证明远端缓存已存储了构建结果,我们需要再次执行以下操作:

    1. bazel clean
    2. bazel run :main --remote_cache=grpc://localhost:8980

    现在,这应该在行上打印统计信息,指示您已从缓存中检索操作的结果:

    1. bazel clean
    2. bazel run :main --remote_cache=grpc://localhost:8980

    现在,这应该在行上打印统计信息,指示您已从缓存中检索操作的结果:

    INFO: 2 processes: 2 remote cache hit.

    或者可以换个执行机器,将localhost替换部署远端缓存的上述机器IP即可

    远程执行(和缓存)

    下面示例中,在本机上只搭建一个worker,使用最少量的配置,保证其在工作区上调用bazel能单次执行一个进程即可

    首先,要清除先前缓存操作的结果,请刷新本地 redis 数据库:

    redis-cli flushdb

    接下来,重新启动 buildfarm 服务器,并删除 worker 的 cas 存储,以确保能执行远程构建(这也可通过在客户端强制指定参数--noremote_accept_cached达到同样效果)。buildfarm server窗口和目录执行如下操作:

    • 中断buildfarm-server运行(即按键 Ctrl+C)
    • 重新启动buildfarm-server
    • bazel run src/main/java/build/buildfarm:buildfarm-server $PWD/examples/config.minimal.yml

    您可以从远程缓存步骤让工作线程运行,它不需要重新启动

    在其它窗口,客户端工作区中执行如下命令:

    1. bazel clean
    2. bazel run :main --remote_executor=grpc://localhost:8980

    运行后窗口打印应该包含如下信息

    INFO: 2 processes: 2 remote.

    其中的“2 remote”表明您的编译和链接是远程运行的。恭喜,您刚刚通过远程执行构建了一些东西!

    容器快速启动

    上述方式启动buildfarm较为复杂,需要手动启动redis、buildfarm-server、buildfarm-worker三个服务。可通过如下命令最小化快速启动buildfarm集群:

    ./examples/bf-run start

    备注:examples/bf-run是个shell文件,查看其内容发现,其是封装了buildfarm-redis、buildfarm-server、buildfarm-worker三个docker container的部署、启动和停止等操作。

    上述命令将在最新版本上启动所有必要的容器。容器启动后,可以使用如下命令进行构建。

    1. bazel clean
    2. bazel run :main --remote_executor=grpc://localhost:8980

     备注:按容器方式启动后,执行bazel构建报错,提示没有可用的workers, 具体原因不明,后续空闲再定位其原因。

    要停止容器,请运行如下命令:

    ./examples/bf-run stop

    下一步工作

    我们已经在单台机器上启动了worker 、server和构建bazel,但这些服务可以分布在不同的机器上,以实现“远程”。一般采用大量的workers和少量的servers (在实践中使用了 10:1 和 100:1 的比率),充分整合workers上的大型存储和强大的多核 CPU/GPU能力,使其更高效且专业的为bazel构建执行服务(或其他服务的客户端),并且有专门servers具有大量的网络连接来汇集内容流量。一个全套的buildfarm 部署可以为数百或数千名开发人员或 CI 构建提供服务,使他们能够从 AC/CAS 中彼此的共享其它人构建结构,以及在大量的workers执行并交付构建结果。

    在多个机器上部署分别worker时,需使其连接到同一个redis集群(更改examples/config.minimal.yml 中的redisUri),从而实现一个含多worker的buildfarm设置。

    备注:redis默认有保护,不允许其它机器连接,可采用如下方法设置:将配置redis.conf中的protected-mode从默认的yes改为no,并且将bin 127.0.0.1这一行注释,否则就只能本机访问,指定配置文件重启redis服务, 如./redis-server ../redis.conf

    Buildfarm 管理器

    现在,您可以使用开源的 Buildfarm Manager 在本地或在 AWS 中轻松启动新的 Buildfarm 集群。

    1. wget https://github.com/80degreeswest/bfmgr/releases/download/1.0.7/bfmgr-1.0.7.jar
    2. java -jar bfmgr-1.0.7.jar

    打开http://localhost,观察。

    备注:过程中有以下需注意之处

    1、可能出现java版本不匹配的问题,本文采用免安装方式,直接下载JDK解压后设置临时环境变量使用

    https://url.zeruns.tech/Tuna_JDK出处下载最新JDK版本

    解压tar -zxvf OpenJDKxxx -C 临时目录

    export JAVA_HOME=/临时目录/jdk-xxx
    export JRE_HOME=${JAVA_HOME}/jre
    export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
    export PATH=${JAVA_HOME}/bin:$PATH

    Linux——安装JDK和OpenJDK【多种方法】_linux安装openjdk_Pan_peter的博客-CSDN博客

    2、必须使用root账号或者有root权限账号执行java -jar bfmgr-1.0.7.jar

    部署中的问题

    bazel远程构建(Remote Execution) -- Buildfarm部署中的问题-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/m0_74043383/article/details/134555259

    参考文件:

    Home | Buildfarm (bazelbuild.github.io)

    Can I run multi worker on different machine? · Issue #1257 · bazelbuild/bazel-buildfarm · GitHub

    Redis 拒绝连接 Could not connect to Redis at 127.0.0.1:6379: Connection refused的几种情况_redis connection refused-CSDN博客

  • 相关阅读:
    Spring基础篇:Spring简介
    java中有哪些条件选择方法呢?
    详解诊断数据库ODX-F
    C++ list 模拟实现
    Linux操作系统使用及C高级编程-D9D10Linux 服务搭建与使用
    [LeetCode周赛复盘] 第 318 场周赛20221107
    【读书】《北京印象》
    让BI自动生成零售数据分析报表?用模板
    钉钉企业内部应用获取登录用户信息
    高质量代码计算降水季节指数Seasonality index
  • 原文地址:https://blog.csdn.net/m0_74043383/article/details/133948939