- Snorkel AI 的 CI/CD 流水线为每个开放的拉取请求提供独立的 Lakebase Postgres 分支,这是生产数据的完整读写副本,可在不到一分钟内就绪,而此前需要 30 分钟以上甚至更久,因此他们一直无法为每个 PR 启用副本。
- Lakebase 分支采用写时复制,因此在约 2.5 TB 的生产数据集上,100 个并发 PR 数据库只会为每个分支所改动的数据增加存储。分支过期(TTL)会在 PR 完成后自动清理每个分支,因此存储量始终接近生产数据大小加上活跃 PR 的改动量。
- 私有连接和 Okta SSO 支持提供受治理且安全的环境
问题:基于生产数据进行测试不应耗时超过 30 分钟
Snorkel AI 为 AI 团队构建数据开发工具,其用户包括专家数据标注员和前沿模型提供商。在这个具体用例中,Snorkel 通过基于 Kubernetes 构建的 CI 流水线交付代码。每个开放的拉取请求以及临时提交都会获得自己的临时 Kubernetes 命名空间(“PR 命名空间”)。开发者将分支部署到该命名空间,并在合并前运行完整测试套件。
这些测试在针对真实数据运行时最为有用。Snorkel 的生产数据库是一个 Amazon Aurora PostgreSQL 集群。为每个 PR 命名空间提供该数据库的独立副本才是难点所在。恢复一个副本每个环境大约需要 20 分钟,当开发者全天不断提交 PR、合并队列每次运行都需要全新环境时,这太慢了。其他替代方案(共享预发布数据库、裁剪后的测试夹具或合成数据)会重新带来类生产测试本应解决的问题:测试相互干扰、模式过期,以及只有在真实数据形态下才会出现的缺陷。
成功标准
如果满足以下标准,Snorkel 就会认为 Lakebase 在 CI/CD 场景中是成功的:
- 快速配置: 新的 PR 分支在 60 秒内就绪(p95)。
- 规模: 峰值时约 100 个并发 PR 分支,每个分支都有独立的读写能力。
- 兼容性: 现有应用和 CI 套件通过标准 Postgres 在 Lakebase 上运行,性能与 Aurora 相当,并支持大型 JSONB/LOB 列。
- 数据新鲜度: 通过持续的 DMS 复制,main 分支与生产 Aurora 的差距保持在约 2 分钟以内。
- 安全性: 生产数据始终位于私有网络中,绝不经过公共互联网;开发者使用 Okta SSO 登录,CI 流水线以服务主体身份进行身份验证。
为什么数据库分支适合 CI/CD
Lakebase 是 Databricks 的无服务器 Postgres 数据库。其存储与计算分离,并支持分支:你可以像创建 Git 分支一样,从任意时间点创建数据库的一个新的、隔离的、可写分支。
分支采用写时复制。创建分支是元数据操作,因此创建分支时不会复制任何数据。新分支与其父分支共享存储页,只有该分支修改的页才会作为新存储写入。对于 CI 而言,这意味着:
- 创建分支只需几秒,而不是几分钟。 它不依赖于数据库的大小。
- 存储量随每个分支所做的改动增长,而不是随数据库大小增长。 Snorkel 的每个 PR 分支在约 1 TB 的基础数据之上写入约 5 至 10 GB 的改动。
- 计算资源按分支分配并可缩减至零。 每个分支都有自己的自动扩缩计算资源,在 CI 运行间隙可缩减至零。即使配置了 100 个分支,Snorkel 预计也只有约 20 至 30 个分支会同时处理流量,每个分支峰值时约每秒 5 次查询。
架构

1. 在 main 分支上保留一份最新的生产数据副本。 Lakebase 是标准 Postgres,因此无需自定义工具即可作为 AWS DMS 的目标。Snorkel 将一个 DMS 任务指向其生产 Aurora 数据库,并将其复制到 Lakebase 项目的 main 分支:先进行全量加载,然后进行持续的变更数据捕获,使 main 与生产数据的差距保持在约 2 分钟以内。完整 LOB 模式会传输 10 至 20 MB 的 JSONB 值。该团队已经在运行 DMS,因此无需构建或维护新的复制流水线。main 分支是每个 PR 分支的起点,即“黄金副本”。
2. 在 PR 打开时创建分支。 当开发者打开 PR 时,CI 流水线会调用 Lakebase API 从 main 创建分支,为其设置过期时间,并将该分支的连接详细信息传递给 PR 命名空间。分支在不到一分钟内就绪。
3. 针对真实数据运行测试。 PR 命名空间中的应用通过标准 Postgres 连接到其分支。测试可以运行迁移、写入数据并更改模式,而不会影响生产环境、main 或任何其他 PR。
4. 在 PR 关闭或测试通过时删除分支,并以 TTL 作为兜底。 当 PR 被合并或关闭时,流水线会删除该分支。如果该清理步骤未运行,分支会在其 TTL 到期时自行过期。
安全性:私有网络以及面向人员和流水线的身份
两项安全要求排除了其他选项,因此值得单独用一节来说明。
私有连接。 生产数据通过私有网络而非公共互联网从 Aurora 传输到 Lakebase,再从 Lakebase 传输到 CI 集群。
身份。 Snorkel 有两类数据库用户:交互式连接以调试 PR 环境的开发者,以及无需人工参与即可运行的 CI 流水线。Okta SSO 围绕交互式浏览器登录构建,因此我们按用户类型拆分设计:
- 开发者: Okta 与 Databricks 账户联合,用户通过 SCIM 进行配置。开发者使用其常用的 Okta 身份登录。
- CI 流水线: 每个 PR 命名空间以 Databricks 服务主体(按团队或按仓库限定范围)运行,同样通过 SCIM 进行配置。PR Pod 使用服务主体的凭据,通过 Databricks SDK 获取短期的 Lakebase OAuth 令牌,并在长时间测试运行期间刷新这些令牌。CI 中不存在长期有效的数据库密码。
- 审计: Postgres 审计日志会记录每个查询的服务主体身份,因此每个查询都可以追溯到运行它的流水线。
为什么写时复制和分支过期能让 CI 保持快速且低成本
Lakebase 的两项功能使这一模式能够大规模运行:写时复制分支和分支过期(TTL)。

写时复制让分支瞬间创建。 新分支不复制任何数据。它指向父分支已有的存储页,只有该分支修改过的页才会作为新存储写入。从约 1 TB 的生产副本创建分支所需的时间,与从 1 GB 数据库创建分支差不多:只需几秒,而不是完整恢复所需的约 20 分钟。每个 PR 命名空间都能立即获得自己独立的、可写的生产副本。
写时复制让分支成本低廉。 每个分支与 main 共享大部分数据,因此存储增长取决于每个分支所做的更改,而不是数据库的大小。对 Snorkel 来说,每个 PR 分支在共享基础之上大约增加 5 到 10 GB。计算资源按分支分配,并在空闲时缩容到零,因此只有正在运行测试的分支才会使用计算资源。
分支过期让长期成本保持低廉。 当分支生命周期较短时,写时复制的节省效果最大。分支会保留其创建时存在的数据版本。随着 DMS 持续用生产变更更新 main,长期存在的分支会一直持有那些较旧的页,因此其使用的存储会随时间增长。为每个 CI 分支设置 TTL,意味着每个分支在其 PR 完成后会自动删除。这使存储量接近生产基础数据的大小加上活跃 PR 的更改量。
同样的模式也适用于 AI 代理
PR 命名空间并不是唯一需要生产数据一次性副本的工作负载。编写 SQL、运行迁移或更改数据的 AI 代理也需要一个安全的试验场所,而写时复制分支正好提供了这样的场所。
每个代理任务一个分支。 每次代理运行都会获得 main 的一个独立分支。代理可以读取真实数据、写入数据,甚至更改模式,而不会影响生产环境或任何其他代理的工作。无论数据库多大,创建分支都只需几秒,因此为每个任务创建一个分支是切实可行的。
多个代理并行运行。 存储只会随每个分支更改的页而增长,并且每个分支的计算资源在空闲时会缩容到零。并行运行数十个代理的成本大约相当于它们所做的更改量,而不是数据库的数十个副本。
审查更改,或将其丢弃。 团队可以在将任何内容应用到生产环境之前,检查代理在其分支上所做的更改。如果结果不正确,他们可以删除该分支,无需回滚任何内容。
TTL 会清理代理留下的分支。 代理可能会创建大量短生命周期分支。为每个分支设置过期时间会自动删除被遗弃的分支,就像 TTL 清理 CI 分支一样。
为代理提供限定范围的身份。 与 CI 流水线一样,代理可以以服务主体身份运行,并使用短期 OAuth 令牌,因此代理运行的每个查询都可以在审计日志中追溯。
结果
- 配置时间: 之前超过 30 分钟,使用 Lakebase 后不到 60 秒 [VERIFY p95 measured]
- 规模: 设计目标是在约 2.5 TB 的生产数据集上支持约 100 个并发 PR 分支
- 兼容性: CI 套件在 Lakebase 上运行,与 Aurora 相比“没有重大兼容性问题”/性能相当
- 采用情况: 推广到各团队的 60 到 70 名开发者
- 开发者评价: “以前我们必须物理复制数据,这些复制任务要花费数小时,并且经常在各种 CI 平台(github actions、circle ci 等)上遇到网络和其他瓶颈。我们在寻找一种解决方案,在数据离开我们的 VPC 时也能满足我们的安全和合规要求”
在 CI/CD 中使用 Lakebase 分支的最佳实践
- 每个 PR 一个分支,从持续同步的 main 分支创建。
- 始终设置 TTL。 将过期视为必需项,而非可选项。使其与 PR 或测试运行通常持续的时间相匹配。
- 创建新分支,而不是保留旧分支。 如果 PR 需要更新的数据,请从 main 创建新分支。这只需几秒钟。
- 让计算资源缩容到零。 大多数已配置的分支在任何给定时刻都处于空闲状态。
- 为流水线使用服务主体和短期 OAuth 令牌, 人员则使用 SSO。
- 监控每个分支的存储使用情况 以便及早发现长期存在的分支。
准备好为每个拉取请求提供其专属的类生产数据库了吗? 开始使用 Lakebase 并阅读分支文档,在 CI 流水线中设置分支过期。
相关标签:在收件箱中获取最新文章
订阅我们的博客,最新文章将直接发送到您的收件箱。