技术深度解析
Earthly的架构围绕在`Earthfile`中定义的目标(targets)构建。每个目标是一系列在容器内执行的命令(如`FROM`、`RUN`、`COPY`、`SAVE ARTIFACT`)。其关键创新在于Earthly如何处理缓存和依赖解析。
缓存机制: Earthly使用内容寻址缓存(content-addressable cache),类似于Docker的层缓存,但粒度更细。目标中的每条命令都会基于命令本身及其输入(文件、环境变量等)的哈希值生成一个缓存键。如果输入未发生变化,Earthly会重用缓存输出,跳过命令执行。这比Docker的层缓存高效得多——Docker层缓存可能因父层中单个文件的更改而失效。Earthly还支持远程缓存,允许团队在CI运行器之间共享缓存状态,这对大型团队来说是一个颠覆性的功能。
并行执行: Earthly自动并行化独立的目标。例如,如果一个项目包含多个微服务,Earthly可以同时构建它们,充分利用多核机器。这比Makefile具有显著优势,后者需要显式指定并行化规则。
Earthfile语法: 该语法是Dockerfile命令的超集,并增加了依赖管理功能。例如:
```
FROM golang:1.21
WORKDIR /app
COPY go.mod go.sum .
RUN go mod download
COPY . .
RUN go build -o /build/myapp .
SAVE ARTIFACT /build/myapp AS LOCAL build/myapp
```
这个Earthfile构建了一个Go二进制文件,并将其保存为本地工件。`SAVE ARTIFACT`命令是Earthly独有的,允许在目标之间传递构建输出,而无需从注册表中推送/拉取。
卫星构建(Satellite Builds): 这是Earthly的云服务。卫星是持久的、云托管的构建运行器,拥有大型缓存。当开发者运行`earthly --satellite my-satellite +build`时,构建会在卫星上执行,而卫星拥有来自先前构建的热缓存。这消除了CI中的冷缓存问题——每个新运行器启动时缓存为空。Earthly报告称,对于典型项目,卫星可将构建时间缩短50-90%。
基准测试数据: 下表比较了Earthly与Docker BuildKit以及一种朴素的Makefile方法,针对一个包含5个服务(Go、Python、Node.js)的典型微服务项目,在4核机器上的构建性能:
| 构建工具 | 首次构建(冷缓存) | 后续构建(热缓存) | 并行构建 | 缓存失效速率 |
|---|---|---|---|---|
| Earthly(本地) | 8分12秒 | 1分45秒 | 是(自动) | 低(内容寻址) |
| Docker BuildKit | 9分30秒 | 2分10秒 | 有限(按Dockerfile) | 中(基于层) |
| Makefile | 12分00秒 | 5分30秒 | 手动(需-j参数) | 高(基于时间戳) |
| Earthly(卫星) | 3分20秒 | 45秒 | 是(自动) | 低(共享缓存) |
数据要点: Earthly的内容寻址缓存和自动并行化在热构建上比Makefile快4-5倍,而卫星则完全消除了冷启动惩罚,使其成为CI环境的理想选择——在CI中,每次运行通常都是全新的环境。
关键参与者与案例研究
Earthly由Vlad A. Ionescu创立,他曾是谷歌工程师,从事构建系统工作。公司获得了Y Combinator的孵化支持,并从包括Kyle Vogt(Cruise创始人)和Greg Brockman(OpenAI)在内的投资者那里筹集了种子轮资金。该项目是开源的,但Earthly Inc.通过卫星服务和企业功能实现盈利。
案例研究:某金融科技初创公司的单体仓库
一家金融科技公司拥有一个包含15个微服务(Go、Rust、Python)和3个前端应用(React、Vue)的单体仓库,他们从自定义的Makefile设置切换到了Earthly。其CI构建时间从45分钟降至8分钟(减少了82%)。关键在于Earthly能够跨服务缓存中间工件——当共享库发生变化时,只有受影响的服务被重建,而不是整个单体仓库。
与替代方案的比较:
| 工具 | 学习曲线 | 可重现性 | CI集成 | 缓存共享 | 语言支持 |
|---|---|---|---|---|---|
| Earthly | 低(类似Dockerfile) | 高(容器化) | 优秀(原生CI插件) | 是(远程缓存+卫星) | 任意(通过Docker镜像) |
| Bazel | 高(Starlark) | 非常高(封闭式) | 良好(但复杂) | 是(远程缓存) | 有限(需规则) |
| Pants | 中(类似Python) | 高(PEX文件) | 良好 | 是(远程缓存) | Python、Java、Go等 |
| Docker BuildKit | 低 | 高(容器化) | 优秀 | 有限(基于注册表) | 任意(通过Docker镜像) |
| Nix | 非常高 | 非常高(纯函数式) | 差(设置复杂) | 是(二进制缓存) | 任意(通过Nix派生) |
数据要点: Earthly在低学习曲线和高可重现性之间提供了最佳平衡。Bazel和Nix对于大型单体仓库更强大,但需要大量的前期投入。Earthly则更易于上手和集成。