一、背景
相信很多公司都是基于Hive做的数仓,从而对外提供数据服务。这里只讨论离线数仓,做数仓必然离不开对大量数据的ETL处理工作。目前的ETL种类繁多,可选择的工具也有很多,比如使用Sqoop, DataX做离线的T+1数据同步, Spark或者Flink做T+0的实时数据同步等。
目前有很多公司业务是T+1的,每天需要同步昨天的业务库(MySQL、mongodb等)的数据到Hive数据仓库中,这里就涉及到大量数据同步的性能开销问题。我司由于历史原因,大量的MySQL表是全量同步的,而且由于某些原因居然还不带时间字段比如:created_at,updated_at等,不过好在后面和DBA进行沟通补全了。我们直到sqoop是支持全量和增量进行数据同步的 参考Sqoop抽数的模式
但是数仓更多的是基于分区来做的,虽然sqoop可以只同步修改的,但是我们需要按天或者小时为维度获得天级和小时级全量数据,鉴于历史原因,我们并没有做真正意义上的天级或者小时级分区而是使用每个分区全量的方式提供服务。
二、注意事项
- 关于MySQL建表:
必须有主键,必须有时间字段包含创建和修改,必须最小化使用字段类型,必须创建经常使用的字段索引,必须主从分离。 - 以下天级和小时级增量全量主要针对没有历史数据修改的情况。如果有历史修改,需要重新刷下全量数据,或者干脆就采用监听MySQL binglog日志做实时同步。
三、天级数据增量同步
思路: 每天将前天的全量数据和昨天的增量数据进行聚合(Union All)
这里需要依赖一个天级增量任务:ods_xxx_record_di,ods_xxx_record_df任务会将ods_xxx_record_di作为他的前置依赖,当ods_xxx_record_di任务运行完成后就开始使用hive或者sparksql计算ods_xxx_record_df 昨天的数据,时间从原先90+分钟降到10+分钟左右,效率提升非常明显。
示例代码
insert overwrite table ods.ods_xxx_df partition (pt = '2019-09-25')
select
id,student_id