3. 数据平台单仓库与多仓库结构选型验证

数据平台单仓库与多仓库结构选型验证 学习卡片

为什么需要先做结构选型验证

数据平台仓库结构一旦确定,后续的权限模型、CI 触发范围、依赖解析方式都会围绕它展开。单仓库(monorepo)把 ETL、调度、模型定义放在同一仓库,多仓库(polyrepo)则按资产类型拆分。两者没有绝对优劣,关键看团队规模、发布节奏和权限隔离要求。本节用最小原型把两种结构各搭一遍,用同一组资产做对照实验,得出可落地的选型结论。

两种原型的最小目录结构

为了让对比公平,两种结构放入完全相同的三类资产:ETL 作业(Python)、调度配置(YAML)、模型定义(SQL)。单仓库用目录隔离,多仓库用仓库隔离。

# 单仓库原型 monorepo/
monorepo/
├── etl/
│   └── orders_daily.py
├── schedule/
│   └── orders_daily.yaml
├── models/
│   └── dwd_orders.sql
└── ci/
    └── pipeline.yaml

# 多仓库原型 polyrepo/
polyrepo-etl/        orders_daily.py
polyrepo-schedule/   orders_daily.yaml
polyrepo-models/     dwd_orders.sql
polyrepo-ci/         pipeline.yaml

两类资产之间存在真实依赖:调度配置引用 ETL 作业名,模型定义依赖 ETL 产出的表。这个依赖关系是后续对比依赖管理的关键。

对照实验:权限、构建速度、依赖管理

用同一台机器、同一份资产内容,分别对两种结构执行一次完整 CI(安装依赖、静态检查、构建产物)。下表为教学示例的预期观察结果,用于说明差异方向,不代表真实实测数据。

对比维度单仓库多仓库
权限粒度目录级 CODEOWNERS,ETL/调度/模型共用一套权限仓库级权限,可给模型组只读 ETL 仓库
CI 触发范围需路径过滤,否则任一改动触发全量构建天然按仓库触发,改动范围即构建范围
构建速度全量构建慢,加路径过滤后接近多仓库单仓库构建快,但跨仓库变更需多次触发
依赖管理依赖在同一提交内可见,跨资产引用易追踪跨仓库依赖需版本号或子模块,易出现版本漂移
原子变更一次提交可同时改 ETL+调度+模型需协调多个仓库的提交顺序

结构选型验证关系图

下图把两种结构的资产分布、CI 触发路径和依赖追踪方式放在同一视图中,便于直接对比差异点。

单仓库 vs 多仓库结构选型验证 单仓库 monorepo etl/orders_daily.py Python ETL 作业 schedule/orders_daily.yaml 调度配置,引用 ETL 作业名 models/dwd_orders.sql 模型定义,依赖 ETL 产出表 CI:路径过滤触发 改动 etl/ 只构建 ETL 子集 依赖追踪:同提交内可见 ETL→调度→模型 引用链清晰 多仓库 polyrepo polyrepo-etl orders_daily.py polyrepo-schedule orders_daily.yaml polyrepo-models dwd_orders.sql CI:按仓库独立触发 改动哪个仓库就构建哪个 依赖追踪:跨仓库版本引用 需版本号/子模块,易漂移 对比

选型判断与结论

根据上述对照,选型可按以下条件判断:

  • 选单仓库:团队小于 15 人、ETL/调度/模型变更经常需要原子提交、希望一次 CI 覆盖全链路依赖。必须配置路径过滤,否则构建时间会随资产增长线性上升。
  • 选多仓库:模型组与 ETL 组权限需要严格隔离、各资产发布节奏差异大、单仓库 CI 已明显变慢。必须为跨仓库依赖引入版本号或子模块锁定,避免版本漂移。
  • 折中方案:单仓库 + 目录级 CODEOWNERS + 路径过滤 CI,可在多数中小数据平台中兼顾原子变更与构建速度。
验证时重点观察两个指标:一次跨资产变更需要触发几次 CI、依赖引用是否需要人工同步版本号。前者决定构建速度,后者决定依赖管理成本。