4. 数据湖仓迁移策略
把传统数据湖或数仓迁移到 Delta Lake,本质上不是“把文件换个目录”,而是把数据组织方式从“文件集合”升级为“带事务日志的表”。传统 Hive 表或 Parquet 目录只记录文件位置,读时靠目录扫描推断分区;Delta Lake 在表目录下维护 _delta_log/,用 JSON 提交记录每次写入的 add/remove 文件、schema、统计信息和事务版本。因此迁移策略必须同时回答三件事:分层怎么落、增量怎么同步、出错怎么回滚。
一、Bronze/Silver/Gold 分层的迁移映射
迁移时不要按原系统表名平铺到新环境,而应先按“数据加工深度”重新归位。Bronze 层承接原始接入,保留源系统字段、原始类型和接入时间,允许存在重复与脏数据;Silver 层做清洗、去重、类型规范、维度补全和一致性校验,是可信明细层;Gold 层面向主题域和消费场景,做聚合、宽表或指标计算。传统数仓的 ODS 通常映射到 Bronze,DWD/DWB 映射到 Silver,DWS/ADS 映射到 Gold;传统数据湖的原始日志区映射 Bronze,清洗后 Parquet 映射 Silver,报表集市映射 Gold。
分层落位后,每层表的 Delta 属性要区别设置。Bronze 表通常启用 delta.appendOnly=true,避免误更新原始数据;Silver 表启用 schema 演进与 mergeSchema,并建立主键去重逻辑;Gold 表按查询模式选择分区列和 Z-Order 列。下面这张图给出迁移时的分层映射与数据流关系,重点看“源系统 → 分层落位 → Delta 表属性”的对应关系。
二、增量同步:水位、MERGE 与幂等
全量搬迁只适合首次初始化,日常必须走增量。增量同步的核心是“水位 + 主键 + 幂等”。水位记录上次同步到的位置,可以是时间戳、数据库 LSN 或 Kafka offset;主键决定 MERGE 的匹配条件;幂等保证同一批数据重复执行不会产生重复行。
以订单表为例,源库有 order_id、updated_at、status 等字段。首次全量导入 Bronze 后,后续每次从水位表读取 last_sync_ts,抽取 updated_at > last_sync_ts 的记录写入 Bronze 临时区,再 MERGE 到 Silver:
MERGE INTO silver.orders AS t
USING bronze.orders_inc AS s
ON t.order_id = s.order_id
WHEN MATCHED AND s.updated_at > t.updated_at THEN UPDATE SET *
WHEN NOT MATCHED THEN INSERT *;
-- 成功后更新水位
UPDATE ctl.sync_watermark
SET last_sync_ts = (SELECT MAX(updated_at) FROM bronze.orders_inc),
last_version = (SELECT MAX(version) FROM (DESCRIBE HISTORY silver.orders))
WHERE table_name = 'silver.orders';
这里有两个容易踩的坑。第一,水位更新必须放在 MERGE 成功之后,否则中途失败会导致数据丢失;第二,MERGE 的匹配条件要包含 updated_at 比较,避免旧版本覆盖新版本。如果源系统存在物理删除,还需要额外用 WHEN NOT MATCHED BY SOURCE THEN DELETE 或软删除标记处理,不能只靠 upsert。
三、回滚方案:时间旅行 + 校验 + 保留窗口
Delta Lake 的 _delta_log 天然支持时间旅行,这是迁移过程中最重要的安全网。每次写入都会生成新版本,回滚只需 RESTORE TABLE silver.orders TO VERSION AS OF 12 或 TO TIMESTAMP AS OF '2025-01-15 10:00:00'。但回滚不是无条件的:必须先确认目标版本的数据质量,再执行恢复,最后验证下游读取是否正常。
建议的回滚判断依据包括三项:目标版本行数与预期偏差是否在阈值内、主键是否唯一、关键指标(如订单总金额)与回滚前是否一致。若偏差超过阈值,说明目标版本本身也有问题,应继续向前回滚或从 Bronze 重放。同时要注意 VACUUM 会物理删除旧文件,默认保留 7 天,迁移期间建议把保留窗口设为 14 天,确保故障发现周期内都能回滚。
四、迁移执行顺序与验收
推荐按“先 Bronze、再 Silver、后 Gold”的顺序迁移,每层完成后再进入下一层。Bronze 迁移重点是接入完整性和分区对齐;Silver 迁移重点是主键去重和 schema 兼容;Gold 迁移重点是聚合口径与查询性能。每层迁移后都要做一次对账:源表与目标表的行数、主键数、关键字段空值率、金额汇总值四项对比,偏差超过 0.1% 就要暂停并排查。
验收通过后,再切换下游任务读取新表,并保留旧表一个周期作为兜底。整个迁移过程中,水位表、版本历史和回滚脚本要作为标准交付物一并维护,确保任何一次同步失败都能在分钟级定位并恢复到已知良好版本。