1. Hudi實現(xiàn)拉鏈表實戰(zhàn)

        共 3230字,需瀏覽 7分鐘

         ·

        2023-08-24 14:25

        1 基于Hudi表實現(xiàn)拉鏈表的方案

        • 由于Hudi表存儲為了保證數(shù)據(jù)唯一性要求有主鍵,拉鏈表會對某一個對象的歷史狀態(tài)都存儲所以主鍵設計為聯(lián)合主鍵,將對象ID和生效時間作為聯(lián)合主鍵。
        • Hudi新增了數(shù)據(jù)的更新能力,因此相對于傳統(tǒng)的大數(shù)據(jù)平臺,可以基于update的能力優(yōu)化傳統(tǒng)hive的拉鏈表的實現(xiàn)方案。
        • 增量數(shù)據(jù)一般不攜帶歷史數(shù)據(jù)的生效時間

        2 拉鏈表實現(xiàn)算法

        1. 當前最新的拉鏈表為Now_table(UserID:用戶ID,BundleID為套餐ID;Start_date為生效時間;End_date為失效效時間)
        2. 新增數(shù)據(jù)Tmp_table,(由于大數(shù)據(jù)平臺的數(shù)據(jù)基于上游采集而來,基于時間戳的增量數(shù)據(jù)相對容易獲取到)
        3. 新增數(shù)據(jù)Tmp_table與Now_table關聯(lián),將以存在數(shù)據(jù)更新寫入Now_table,end_date為當前時間
        4. 將新增數(shù)據(jù)全部寫入Now_table,end_date為'9999-12-31'

        3 實現(xiàn)舉例

        • 創(chuàng)建Now_table,并初始化數(shù)據(jù)
              
              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
        • 新增數(shù)據(jù)臨時表Tmp_table,新增數(shù)據(jù)到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數(shù)據(jù)內容如下:

        bf181019d4e7a6c3098a3a7196d52bba.webp
        • 將Now_table數(shù)據(jù)閉鏈
              
              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數(shù)據(jù)變更如下:

        069f5107b9345baa72f091486bd52ca6.webp
        • 將增量數(shù)據(jù)開鏈寫入Now_table
              
              insert into Now_table 
        select 
         userid,
         bundleid,
         start_date,
         '9999-12-31',
         now() 
        from Tmp_table

        Now_table數(shù)據(jù)更新如下:

        921535791ce864f7fbb681ea303352b5.webp
        • 通過userid可以查詢到歷史的狀態(tài)變化。
              
              select userid,bundleid,start_date,end_date from Now_table where userid='U0001';
        77b16652026139d0f818d393ec42af88.webp

        4 算法總結

        • Hudi表具有數(shù)據(jù)更新能力,不需要對全表數(shù)據(jù)進行insert overwrite操作,算法更簡單
        • Hudi表提供Upsert的能力,當相同主鍵的數(shù)據(jù)存在,新數(shù)據(jù)會自動更新老數(shù)據(jù),因此不用對老數(shù)據(jù)進行update操作,直接Insert即可(Sparksql的Insert操作默認為upsert操作。)
        • 對于緩慢變化維的操作會更加簡化,設置合理的主鍵,基于Merge語法直接操作,會更加簡單。

        歡迎關注微信公眾號:大數(shù)據(jù)AI


        瀏覽 139
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
          
          

            1. 色播激情 | 成人污视频在线观看 | 91久久人澡人妻人人澡人人爽 | 亚洲在线成人视频 | 亚洲.欧美.丝袜.中文.综合 |