作者:稀饭
对于存在状态更新类的数据,如果从上游ETL到下游使用层,需要考虑状态更新的问题。一般这种处理主要采取分区表清洗的方式来考虑,对于分区的设计比较重要。
对于离线数据开发来说,状态更新类数据的ETL往往要考虑的是状态更新字段的更新频率和更新的数量,按照更新频率和数据量来设置分区字段,并调度任务。举个栗子,对于那种部门表,部门变更的频率不大,部门数据整体也不大,所以从上游源表ETL到下游使用层,ETL定时任务的频率可以设置为一天一次,甚至一周一次、一个月一次。而分区字段往往采用时间dt,每个分区所包含的数据为全量数据。在这种清洗策略下,每清洗一次,就会增加一个分区(并控制分区的数量),而数据量不大的话,分区保留的数量也可以多一些:
insert overwrite table 表名 partition (dt) -- 每天跑1次
select 全量数据
from table
where dt = current_date();
复制
而对于状态更新比较频繁,但数据量不大的情况,分区字段仍然可以设置为一天一次,但刷新数据的频率要加大,也就是insert overwrite数据的时候,每天会对整个分区进行多次刷新,直到时间节点到了次日,才会新增分区:
insert overwrite table 表名 partition (dt) -- 每天跑多次
select 全量数据
from table
where dt = current_date()
复制
对于状态更新比较频繁,总数据量比较大,但每天更新的数据量不算很大的情况下,需要将分区设置为存储“当天有更新的数据”,即每个分区里存的数据,要么是当天新增的数据,要么是以前分区的数据,但是在今天有更新。在这种情况下,对于那些以前分区里有的数据,但是在刷新所在时间范围里发生更新的数据,刷新的策略会变得复杂,因为我们为了控制总数据量,需要在insert overwrite的时候,既要把存在更新的数据刷新进新的分区里,也要把以前分区里的(即没有记录到状态更新)的数据清除掉,就需要对历史分区基于update_time这类字段进行delete操作:
insert overwrite table 表名 partition (dt) -- 每天跑多次
select 部分数据
from table
where update_time = current_date() ;
delete table 表名
select 部分数据
from table
where update_time = current_date();
复制
对于状态更新比较频繁,总数据量不大,但每天更新的数据量比较大的情况下,可以将分区设置为存储“当天有更新的数据”,每个分区里的数据存全量数据,按ETL任务的定时频率将新的数据刷新到新的分区里,但不修改历史分区里的数据,这样对于某个分区内的数据来说,仍然是保留唯一性的,但需要删除分区,只保留少量的分区:
insert overwrite table 表名 partition (dt) -- 每天跑多次
select 全量数据
from table
where update_time = current_date() ;
ALTER TABLE test_table DROP PARTITION;
复制
广告区↓