Lakebase 分支功能用于 CI/CD:100 个 PR 数据库的实践经验
Lakebase branching for CI/CD: lessons from 100 PR databases
Databricks 的 serverless Postgres 数据库 Lakebase 通过 copy-on-write 分支支持 CI/CD,Snorkel AI 借此为每个 PR 创建独立数据库分支,创建时间从 Aurora 全量恢复的约 20 分钟降至 60 秒以内(p95)。
问题:针对生产数据进行测试不应耗时超过 30 分钟
Snorkel AI 为 AI 团队构建数据开发工具,其用户包括专业数据标注员和前沿模型提供商。在这个具体用例中,Snorkel 通过基于 Kubernetes 构建的 CI 流水线交付代码。每个打开的拉取请求以及临时提交都会获得自己的临时 Kubernetes 命名空间(“PR 命名空间”)。开发者将分支部署到该命名空间,并在合并前运行完整的测试套件。
这些测试在针对真实数据运行时最为有用。Snorkel 的生产数据库是一个 Amazon Aurora PostgreSQL 集群。为每个 PR 命名空间提供该数据库的独立副本才是难点所在。恢复一个副本每个环境大约需要 20 分钟,当开发者全天不断打开 PR、且合并队列每次运行都需要全新环境时,这太慢了。替代方案(共享预发布数据库、裁剪过的测试夹具或合成数据)会重新带来类生产测试本应解决的问题:测试相互干扰、模式过期,以及只有在真实数据形态下才会出现的缺陷。
成功标准
如果 Lakebase 满足以下标准,Snorkel 将认为它在 CI/CD 场景中是成功的:
- 快速配置: 新的 PR 分支在 60 秒内(p95)准备就绪。
- 规模: 峰值时约有 100 个并发 PR 分支,每个分支都有独立的读写。
- 兼容性: 现有应用和 CI 套件通过标准 Postgres 在 Lakebase 上运行,性能与 Aurora 相当,并支持大型 JSONB/LOB 列。
- 新鲜数据: 通过持续的 DMS 复制,主分支与生产 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. 在主分支上保留一份生产环境的最新副本。 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 分支。智能体可以读取真实数据、写入数据,甚至更改 schema,而不会影响生产环境或任何其他智能体的工作。无论数据库多大,创建分支都只需几秒钟,因此为每个任务创建一个分支是切实可行的。
多个智能体并行运行。存储只随每个分支更改的页面而增长,并且每个分支的计算资源在空闲时会缩容到零。同时运行数十个智能体的成本大约等于它们所做的更改量,而不是数十份数据库副本。
审查更改,或将其丢弃。团队可以在将任何内容应用到生产环境之前,检查智能体在其分支上所做的更改。如果结果不正确,他们可以删除该分支,无需回滚任何内容。
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 流水线中设置分支过期。
来源:Databricks Blog · databricks.com