Hudi实现拉链表实战

共 3230字,需浏览 7分钟

 ·

2023-08-24 14:25


1 基于Hudi表实现拉链表的方案



  • 由于Hudi表存储为了保证数据唯一性要求有主键,拉链表会对某一个对象的历史状态都存储所以主键设计为联合主键,将对象ID和生效时间作为联合主键。

  • Hudi新增了数据的更新能力,因此相对于传统的大数据平台,可以基于update的能力优化传统hive的拉链表的实现方案。

  • 增量数据一般不携带历史数据的生效时间


2 拉链表实现算法



  1. 当前最新的拉链表为Now_table(UserID:用户ID,BundleID为套餐ID;Start_date为生效时间;End_date为失效效时间)

  2. 新增数据Tmp_table,(由于大数据平台的数据基于上游采集而来,基于时间戳的增量数据相对容易获取到)

  3. 新增数据Tmp_table与Now_table关联,将以存在数据更新写入Now_table,end_date为当前时间

  4. 将新增数据全部写入Now_table,end_date为'9999-12-31'


3 实现举例



  • 创建Now_table,并初始化数据


      
Create table  Now_table(
    userid  string,
    bundleid string,
    start_date string,
    end_date  string,
    ts  timestamp
)using hudi
OPTIONS(
  type = 'mor',
`payloadClass` 'org.apache.hudi.common.model.DefaultHoodieRecordPayload',
  primaryKey = 'userid,start_date',
  preCombineField = 'ts'
 );
 
insert into Now_table(userid,bundleid,start_date,end_date) values('U0001','A01','2020-05-31','2021-05-31',now());
insert into Now_table(userid,bundleid,start_date,end_date) values('U0001','A01','2021-05-31','9999-12-31',now());
insert into Now_table(userid,bundleid,start_date,end_date) values('U0002','A01','2020-05-31','2021-05-31',now());
insert into Now_table(userid,bundleid,start_date,end_date) values('U0002','A02','2021-05-31','9999-12-31',now());


800bc8dc595b88b8eb9b86ac77dc750a.webp

  • 新增数据临时表Tmp_table,新增数据到Tmp_table


      
Create table  Tmp_table(
    userid  string,
    bundleid string,
    start_date string
)using hudi
OPTIONS(
  type = 'mor',
  primaryKey = 'userid',
  preCombineField = 'start_date'
 );
 
insert into Tmp_table(userid,bundleid,start_date) values('U0001','A03','2022-05-31');
insert into Tmp_table(userid,bundleid,start_date) values('U0002','A03','2022-05-31');
insert into Tmp_table(userid,bundleid,start_date) values('U0003','A03','2022-05-31');


Tmp_table数据内容如下:


bf181019d4e7a6c3098a3a7196d52bba.webp

  • 将Now_table数据闭链


      
insert into Now_table 
select 
 t1.userid,
 t1.bundleid,
 t1.start_date,
 t2.start_date,
 now() 
from Now_table t1,Tmp_table t2 
where t1.userid= t2.userid and t1.end_date='9999-12-31';


Now_table数据变更如下:


069f5107b9345baa72f091486bd52ca6.webp

  • 将增量数据开链写入Now_table


      
insert into Now_table 
select 
 userid,
 bundleid,
 start_date,
 '9999-12-31',
 now() 
from Tmp_table


Now_table数据更新如下:


921535791ce864f7fbb681ea303352b5.webp

  • 通过userid可以查询到历史的状态变化。


      
select userid,bundleid,start_date,end_date from Now_table where userid='U0001';


77b16652026139d0f818d393ec42af88.webp

4 算法总结



  • Hudi表具有数据更新能力,不需要对全表数据进行insert overwrite操作,算法更简单

  • Hudi表提供Upsert的能力,当相同主键的数据存在,新数据会自动更新老数据,因此不用对老数据进行update操作,直接Insert即可(Sparksql的Insert操作默认为upsert操作。)

  • 对于缓慢变化维的操作会更加简化,设置合理的主键,基于Merge语法直接操作,会更加简单。



欢迎关注微信公众号:大数据AI



浏览 139
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报