跳转到内容
use-cases / push-one-build-to-thirty-ci-workers / hero
PIPE · CI 扇出

把一次构建推送到三十个 CI worker

矩阵 CI 扇出到三十个测试 runner,每个都需要同样的 800 MB 镜像。把 tarball 流式送入一个带 ?n=30 的管道路径,三十个 worker 一起 curl 同一个 URL。字节只走一次,服务器什么都不存,镜像仓库凭据也不必轮换。

阅读 Pipe 文档
use-cases / push-one-build-to-thirty-ci-workers / mechanism

三十条 curl 怎么变成一条流

管道是一个无磁盘的扇出路由器。发送端对 /api/v1/pipe/[path]?n=30 的 POST 会阻塞,直到三十个接收端用相同 n 连到同一 URL。然后字节从构建容器一直流到每个 runner,同时进行,以最慢接收端的速度为准。

三步。无镜像仓库,无 S3,无 cache action。PIPE · ?n=30
01

构建只流一次

tar c | curl -T - https://pipe/.../build?n=30

构建容器把 tarball 直接管道送入 curl。不写文件,不推镜像仓库。

02

管道等待集群

POST /api/v1/pipe/[path]?n=30

服务器让发送端阻塞,直到三十个接收端全部连接。n 不匹配返回 400。提前连接的接收端没问题。

03

三十个全拉同一 URL

curl https://pipe/.../build?n=30 | tar x

每个 runner 拿到完全相同的字节。反压来自最慢的接收端,而不是发送端的带宽。

什么都不持久,什么都不缓存。管道撮合连接后就让到一边。最慢的 runner 完成,传输就完成——URL 也随之消失。

use-cases / push-one-build-to-thirty-ci-workers / numbers

对矩阵 CI 来说意味着什么

朴素做法:同一个 800 MB tarball 拉三十次镜像仓库,三十个冷缓存,三十次网络往返。Pipe:一次出站、一次传输,最慢接收端定节奏。

WALL TIME

12s

一次出站,以线速传输。最慢接收端定节奏,但没人需要重新下载。

EGRESS

1× / build

字节从构建机离开一次,在管道扇出。无 S3 GET 费用、无 Docker Hub 拉取。

STORAGE

0 bytes

管道在磁盘上什么都不存。无镜像仓库要清理,无缓存键要失效。

wall-time 数字假设三十路矩阵与构建容器在同一区域网络;跨区域传输瓶颈在区域间带宽,不在管道。

use-cases / push-one-build-to-thirty-ci-workers / powers

扇出解锁了什么

一旦构建变成一个 URL 加三十条 curl,一整堆 CI 脚手架就消失了。无产物存储要老化、无镜像仓库凭据要轮换、无 cache action 要调试。

最慢接收端定节奏

反压内建在管道里。快的 worker 不用为慢的多走一次镜像仓库往返——大家都在管道处等,然后以同一速率喝水。没人重新下载。

无镜像仓库凭据要轮换

什么都没推到镜像仓库,所以也不必对其鉴权。URL 本身就是凭据——短生命周期、限定一次传输、构建结束就被驱逐。

无 S3 账单,无出站惊喜

字节从构建机离开一次,管道做广播。每次构建只付一次出站,而不是每次矩阵跑三十次镜像仓库拉取。

无 cache 键要失效

管道按构建,不按键。没有 GitHub Actions cache 漏命中、没有 buildx 层迷案、也没有从上周 main 残留下来的旧 tarball。

适用于任何 tarball,不只是镜像

同一模式适用于 node_modules、.pnpm-store、target/、wheel cache、数据集分片。能流的就能扇出。

use-cases / push-one-build-to-thirty-ci-workers / punchline

一个发送端。三十个接收端。零 S3 账单。

原本要九十秒、消耗一次 S3 命中的 30 路推送,现在只要十二秒、一次出站。没人重新下载。镜像仓库凭据不用轮换。矩阵跑完,URL 自动消失。

  • 1 EGRESS
  • 30 RECEIVERS
  • 0 STORAGE
  • 0 CREDENTIALS
打开 Pipe API
use-cases / push-one-build-to-thirty-ci-workers / replaces

它替代了什么

矩阵 CI 流程平时要拼起来的零件——镜像仓库、cache action、镜像源、自定义上传步骤。管道把它们折进一个 URL。

  • AWS S3(镜像仓库存储 + 出站)每次构建 30× GET 费用、淘汰策略、IAM 角色
  • GitHub Actions cache10 GB 上限、键冲突、按分支隔离
  • Docker Hub 拉取限速,需付费镜像源避免限流
  • npm / pnpm 镜像源为了避开公共 registry 自托管 Verdaccio
  • 自定义 CI cache actionBash 胶水、S3 SDK、过期逻辑、坏掉时要值班
  • Buildx 层缓存导出层格式怪癖、跨 runner 缓存未命中
use-cases / push-one-build-to-thirty-ci-workers / cta

别再把同一 tarball 推三十次。推一次。让三十条 curl 共享这条流。

阅读 Pipe API
use-cases / push-one-build-to-thirty-ci-workers / related

阅读其他内容