前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >编译耗时:46分钟→1分钟,这款CI神器有点强!

编译耗时:46分钟→1分钟,这款CI神器有点强!

作者头像
腾讯云开发者
发布2024-10-18 12:59:45
120
发布2024-10-18 12:59:45
举报
文章被收录于专栏:【腾讯云开发者】

最近云原生构建团队针对一个占用磁盘 124.44GB,超过 1400 仓库的项目进行开发。这样的代码规模背后面临拉取耗时长、存储空间占用大、效率低、并发构建受限等问题。面对这些持续存在的挑战,团队意识到需要从根本上解决代码 clone 的速度问题,这不仅关系到开发效率,还直接影响 CI/CD 流程和资源利用。

于是,我们关注到了这款最新发布的 CI 神器。本篇文章是编译部分的技术详解。

关注腾讯云开发者,一手技术干货提前解锁👇

在上一篇文章《125G 代码,10秒内准备完成:这款 CI 神器有点强!》中,我们分享了如何通过 CNB 的 git-clone-yyds 插件,把一个 125 GB 代码库的克隆时间从 20 分钟降至 10 秒内。显著缩减了我们团队的流水线运行时间,大大提高了构建效率。

然而,在实际针对 AOSP 进行定制开发时,我们遇到了一个更加棘手问题:

即便成功加速了代码库的克隆过程,全量编译如此庞大的代码库依然是个非常耗时的过程,需时约 46 分钟。

常规的解决策略,就是对编译产物的缓存,避免后续构建的全量重新编译,加快编译过程。这也就是为什么前文团队会专门采购一台编译构建机用来做编译的原因。

虽然这个方案可行,但是显然也是一个比较挫的方法:

  1. 单机编译缓存限制了并行编译的可能性。
  2. 增加了对编译产物管理的复杂度和成本。

既然 CNB 已经帮我们解决了 clone 代码的速度问题,是否 CNB 也提供了编译缓存的方案呢?

有的,而且还非常先进!

01、CNB 使用 volumes 挂载缓存

基于 Docker 生态构建的 CNB,在处理缓存的方式也是非常的云原生、异常先进。

底层原理是通过在母机上存放需要被缓存的产物,然后在编译环境的 Docker 容器起来时,通过 volume 参数挂载上去,在编译环境容器中即可使用缓存。

Docker 玩家对 volumes 都很熟悉,常见的有 rw/ro 两种模式(读写和只读模式)。

CNB 在此之上,还提供了 Copy-on-Write 模式,挂载到容器上的缓存目录,是基于 Copy-on-Write的机制实现的。Copy-on-Write (CoW 写时复制)允许系统在需要修改数据之前共享相同的数据副本,从而实现高效的缓存复制。在并发环境中,这种方法避免了缓存的读写冲突,因为只有在实际需要修改数据时,才会创建数据的私有副本。

这种 volumes + Copy-on-Write的机制显著提高了并发性能。

按照官方文档的配置,修改一下流水线的配置,团队在编译 AOSP 的时候,通过 Copy-on-Write 的方式缓存 ./out 目录,配置的方法很简单,修改 docker.volumes 字段即可:

代码语言:javascript
复制
build_config: &aosp_build_config
  runner:
    cpus: 64
  docker:
    build: .ide/Dockerfile
    # 在这里挂载 volume 缓存,声明为 copy-on-write
    volumes:
      - out:copy-on-write
  stages:
    - name: build
      env:
        BUILD_HOSTNAME: cnb-build
        shell: |
          source build/envsetup.sh
          lunch aosp_arm-eng
          make -j64
      script: bash -e -c "${shell}"

# 测试并发 6 流水线测试
master:
  push:
    - *aosp_build_config
    - *aosp_build_config
    - *aosp_build_config
    - *aosp_build_config
    - *aosp_build_config
    - *aosp_build_config

按照官方 quick start 的测试用例,修改了 SurfaceFlinger.cpp 的系统默认颜色配置,并且触发 6 条流水线同时编译出多个包。

从上面截图可以看到,第一次编译后,通过 CNB 配置 volume 挂载缓存的方式,6 条并行的流水线已经可以利用上缓存。

因为我们声明了是 Copy-on-Write 的方式来使用缓存,在 6 条流水线中编译都实现了 100% 的增量编译,

编译用时是从 46 分 40 秒降低到 1 分 30 秒。

02、CNB volumes 缓存的原理

Docker Volume 是一种持久化和共享数据的机制,允许将数据存储在容器外部(如母机上),确保数据不随容器销毁而丢失,并支持不同容器之间的数据共享。

CNB 使用 Docker Volume 来实现缓存,支持多种缓存的策略,如 :

  • read-write: 读写,并发写冲突需自行处理,适用于串行构建场景
  • read-only: 只读,写操作抛出异常
  • copy-on-write: 读写,变更在构建成功后被合并,适用于并发构建场景
  • copy-on-write-read-only: 只读,变更在构建结束后丢弃
  • data : 创建一个临时数据卷,该数据卷在流水线结束时会自动清理

这里我们以 Copy-on-Write 缓存方式,介绍一下 CNB 是如何结合 CoW 和 Docker Volume 实现高效的缓存策略的。

如前文提到 Copy-on-Write 是在数据需要被修改时,才会创建数据的私有副本,而读操作是可以安全并发运行的。

我们从文件系统挂载的角度看,当流水线起来时,CNB 检测到配置文件中有配置 volumes 字段,从而会在 /data/cache 下面创建一个缓存的文件夹,用户缓存编译产物。

当我们声明了 volume 缓存使用 Copy-on-Write 的数据卷类型来做缓存的时候,CNB 还会在母机的 /data/copy-on-write 下建立 3 个文件夹,upper dir、 work dir、 merged dir。

最终通过 mount -t overlay 挂载成 CoW,其中 lower dir ,就是 volume 缓存所在的文件夹, 这个缓存最终会在编译容器启动的时候(docker run)通过 -v (volumes) 的方式挂载到容器的对应目录下,从而让在流水线运行时,可以直接在容器中使用编译缓存。

下图可以看到,在编译容器中,/workspace/out 目录下,已经挂载了缓存目录。

当有多条流水线并发使用缓存的时候,情况也是类似,我们并发多条流水线,CNB 会通过建立多套 CoW 文件夹(lower dir 都是 /data/cache/ 下的目录),多个构建容器并发使用缓存,互不冲突,换言之需要同时运行多个编译任务的时候,CNB 可以并发命中并使用编译缓存,从而加速编译的过程。

03、更多玩法——远程开发

基于 Docker 生态构建的 CNB,除了 git-clone-yyds 加速 clone 代码的速度、volume 缓存加速编译速度之外,还有更炸裂的功能——远程开发。CNB 的远程开发结合了上面的优点:

  1. 秒级启动远程工作区,借助 git-clone-yyds 实现代码的秒级克隆,大幅缩短初始化时间,同时支持 web IDE 和本地 VSCode Remote 连接,提升效率。
  2. 实现快速的增量编译,通过有效利用 volumes 编译缓存,使得即便是庞大的项目如 AOSP,代码的修改与编译也能迅速完成,让开发者享受到即改即见的便捷。
  3. 支持并发使用工作区远程开发。通常开发者自建 code server 的远程开发,虽然也带缓存,但是往往只能单人使用,无法支持多人并发使用工作区。在实际开发中,多人同时开发一个项目的情况非是事实存在的。CNB 远程开发支持多人并发使用工作区远程开发,共用缓存,但互不干扰,同时享受秒级启动、快速编译。

后面我们将探讨远程开发背后的更多细节,尤其是 CNB 是如何解决并发性问题,从而提供一个流畅、高效的远程开发体验。

-End-

原创作者|黎志航

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-10-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 腾讯云开发者 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 01、CNB 使用 volumes 挂载缓存
  • 02、CNB volumes 缓存的原理
  • 03、更多玩法——远程开发
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档