最近在做同步数仓数据的工作,从设计到实现整个过程其实是挺有意思的。这里记录和分享一下我们的实施方案,也能给有类似需求的同学提供一些参考价值。
需求
在调研了阿里云的 AnalyticDB MySQL 后,我们决定把业务系统使用 Presto 查询 Hive 数据的过程替换成业直接查询 ADB(文中 ADB 都指的是 AnalyticDB MySQL)。具体原因这里就不做展开,简单说三点就是第一解耦我们目前业务直接依赖 EMR, 第二是性能上有很好的提升, 第三点用钱买服务省心。
所以简单来说我们需要把数仓 DWS 层的数据同步到 ADB。
目标
在明确了需求后,数仓数据同步的任务需要达到以下目标
- 扩展性高
新建的表或者删除表都不需要改动同步逻辑,或者其他代码 - 延时低
数仓的数据生产完毕或者更新完毕,相关的表就能开始同步 - 容错率高
不会出现漏同步,或者重复同步
方案设计
为了达到上述的目标,数据同步的主要流程如下
首先我们的同步任务最终执行的形式是 Airflow 中的一个 task,各个不同表的同步任务组成了 Airflow 中的一个 dag。
扩展性
为了达到扩展性的要求,我们把需要同步的 table 和他的依赖 task 以及一些别的信息存入 mysql 表中(表名 sync_task)。上面提到的 dag 就是根据 sync_task 的有效记录动态生成的。所以无论新建同步任务或者删除同步任务,只需要更新 sync_task, 那么 dag 也会动态调整。
dag 示例代码如下
# 读取同步记录sync_tasks = get_mysql_dataset( mysql_conn_id="mysql_metadata", schema="metadata", sql=f"select * from sync_task where status = 1", )# 生成 dag 里的同步 taskfo