Zadig 构建效率提升 40% 背后的实践思路

V1.10.0 版本中我们重新分析了 Zadig 原子构建链路上还有哪些提升空间,重点优化了单个任务构建过程,将构建效率再次提升 40%。

KodeRover
KodeRover  
“构建”是软件工程师日常开发中的高频操作,也是生成可靠交付物的关键步骤。当前 Zadig 工作流在设计层面对微服务架构有良好的支持,支持并行的构建、部署、测试多个服务。在 V1.10.0 版本中我们重新分析了 Zadig 原子构建链路上还有哪些提升空间,重点优化了单个任务构建过程,将构建效率再次提升 40%。 接下来我们将逐步分析 Zadig 构建全链路流程,找出影响构建的瓶颈并做改善,同时思考后续的优化方向。

# 构建一般过程分析

云原生交付过程,构建通常包含 2 个阶段:

  • 将源代码构建为 Artifact
  • 将 Artifact 构建为镜像

源代码构建为 Artifact 过程,通常会有这样的过程:准备构建环境 (如准备构建工具) -> 拉取代码 -> 执行构建

准备构建环境的耗时相对固定,常和基础设施环境的配置关联紧密。

拉取代码强依赖于网络环境的性能,生产环境中建议使用内网环境的代码仓库,保障拉取代码的效率。

执行构建过程中,会涉及到拉取依赖库、生成构建中间产物等,这些通常可以基于对应编程语言的构建工具形成缓存,下次构建时可以基于缓存减少重复操作,极大提升构建效率,这也常是提升构建效率的重要优化环节,也是业界常见的 CI 工具,如 Codefresh、TravisCI、CircleCI 等推荐的构建配置项。

Artifact 构建为镜像的过程,会涉及到基础镜像、镜像 layers 的缓存共享,通过共享缓存减少重复数据拉取或镜像 layer 构建,可以提升镜像生成的效率。

在 Zadig 中,当前镜像构建是使用常驻的 Dind 服务,已经进行了镜像维度的缓存,而从源代码到 Artifact 的构建是通过 K8s Job 进行,每次构建时均是全新的环境。

故从源代码构建为镜像的端到端角度来看,重点需要解决 源代码构建为 Artifact 的效率。

# Zadig Artifact 构建过程

Zadig 当前的构建步骤如下:

  1. 任务排队

  2. 创建运行实例 (K8s Job)

  3. 运行

  • a.(optional) 拉取缓存 -- 仅在用户开启对象存储缓存时才会发生
  • b.准备编译环境
  • c.拉取代码
  • d.执行构建脚本
  • e.(optional) 上传缓存 -- 仅在用户开启对象存储缓存时才会发生
  1. 运行结束 (成功/失败)

由于本次主要关注单任务构建效率,故仅关注 3) 环节的效率。

没有测量就没有优化,此次效率提升会通过构造实验环境场景进行实测,找出影响构建效率的瓶颈,然后针对瓶颈进行优化。

# 测试环境&方法

下述测试将会基于如下环境进行:

  • 测试项目:https://github.com/sqsh

    • Commit:6bb2cf9ddbca980b664d3edbb6ff775d75369278
  • 测试环境 (Zadig)

    • 构建系统:Ubuntu-20.04
    • Zadig 版本:v1.10.0
    • Java:1.12.01
    • Maven: 3.3.9(使用阿里云的 maven 源)

测试环境构建脚本:

# 构建现状

Zadig 在 v1.9.0 及其以下版本中,支持使用对象存储作为构建缓存介质。执行上述测试过程,测试结果如下: 结论:

  • 使用构建缓存时会极大提升构建效率,提升 4 倍
  • Zadig 中构建耗时占比低,处理缓存占比极高

通过分析可知,Zadig 优化构建效率的重点在 缩短处理缓存 的耗时,有如下几种方案可以考虑:

1.构建服务变更形态,从 Job 改为常驻服务

  • a.使用 rootfs 管理构建缓存

  • b.挂接远程储存管理构建缓存

    2.构建服务采用当前的 Job 形态,挂接远程存储管理构建缓存

由于构建任务属于 run-to-complete 类型,且非 7x24 持续运行,故让考虑构建服务采用 Job 形态,同时采用远程存储 (PVC) 的方案来管理构建缓存,消除 拉取/解压、压缩/上传 缓存的过程。

# 构建效率优化

在刚推出的 Zadig v1.10.0 版本中,可将构建的缓存持久化到 PV 上,同时基于 PVC,可在多个项目中共享同一份缓存。

测试方法同上,测试结果如下: 结论:

  • 使用构建缓存时会极大提升构建效率
  • Zadig 对象缓存场景提升 4 倍,Zadig PVC 缓存场景提升 6 倍

Zadig PVC 场景比 Zadig 对象缓存场景提升 43.03%

# 如何配置缓存

以下步骤主要介绍管理员如何进行缓存资源配置,以及工程师如何开启构建缓存

1、配置集群缓存资源

在 集群管理 中,可以进行集群缓存资源的配置: 点开 高级配置,可以查看到 缓存资源配置 详情,点击 帮助,可以查看到具体的使用说明。

若不希望使用持久化存储作为缓存介质,可以继续使用 Zadig 的 对象存储 能力作为缓存介质。若想使用 PVC 能力,可以选择 集群存储 作为存储介质。
集群存储 可以根据 StorageClass 动态生成 PVC,也可以使用集群中已有的 PVC:

2、构建开启缓存

配置构建服务时,显式开启缓存,并配置缓存目录:

# 后续优化

从上述测试效果可以看出,Artifact 的构建由于 Job+PVC 的模式,缓存数据仍需通过网络获取,这部分构建效率仍存在优化空间。后续 Zadig 会从产品层面考虑支持 常驻构建服务+构建环境睡眠+PVC 的模式,进一步提升构建缓存获取的效率,同时减少不必要的常驻服务运行时长。

在 Artifact 构建效率 提升后,Artifact 到镜像构建效率 的影响度将会在整个构建过程中提升,我们也会继续评估考虑是否使用性能和安全性更好的 BuildKit、Kaniko 等替换 Dind ,来进一步提升镜像的构建效率。

通过细致梳理从源码到镜像的端到端构建过程,分析影响效率的主要因素,按照影响程度依次解决,运行在 Zadig 上的项目的构建效率将会持续提高,不断提升开发工程师的开发效率和幸福度。

Zadig,让工程师更专注创造。

欢迎加入开源吐槽群 🔥 交流。

# 关于 Zadig

Zadig 是基于 Kubernetes 设计、研发的开源分布式持续交付 (Continuous Delivery) 产品,为开发者提供云原生运行环境,支持开发者本地联调、微服务并行构建和部署、集成测试等。Zadig 内置了面向 Kubernetes、Helm、云主机、大体量微服务等复杂业务场景的最佳实践,为工程师一键生成自动化工作流 。

# 欢迎参与开源

github.com/koderover/zadig | 源码 (opens new window) gitee.com/koderover/zadig | 源码 (opens new window) koderover.com | 官网 (opens new window) space.bilibili.com/502473428 | Bilibili (opens new window) my.oschina.net/koderover | 开源中国 博客 (opens new window) blog.csdn.net/koderover | CSDN 博客 (opens new window) zhihu.com/org/koderover | 知乎 (opens new window)

欢迎大家 Star、Fork、 Watch!和众多开发者一起探讨、交流,共建开源社区!

KodeRover 公众号

© 2022 筑栈(上海)信息技术有限公司 沪 ICP 备 19000177 号 - 1